#!/usr/bin/env node
/**
 * Menu sync — replaces the PocketBase menu with app/src/data/menu-data.mjs.
 *
 * Deletes every record in menu_categories / menu_items and inserts the
 * current food menu from code. Nothing else is touched.
 *
 * Works against any PocketBase instance (local dev or production):
 *
 *   # local dev
 *   PB_URL=http://127.0.0.1:8090 PB_SUPERUSER_EMAIL=dev@greatbear.in \
 *     PB_SUPERUSER_PASSWORD=devpass12345 node scripts/update-menu.mjs
 *
 *   # production (admin domain serves the PocketBase API)
 *   PB_URL=https://admin.greatbear.in PB_SUPERUSER_EMAIL=admin@greatbear.in \
 *     PB_SUPERUSER_PASSWORD=... node scripts/update-menu.mjs
 */
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'

const here = dirname(fileURLToPath(import.meta.url))
const { MENU_CATEGORIES, MENU_ITEMS } = await import(
  new URL(`file://${join(here, '../app/src/data/menu-data.mjs')}`)
)

const PB_URL = (process.env.PB_URL ?? 'http://127.0.0.1:8090').replace(/\/$/, '')
const EMAIL = process.env.PB_SUPERUSER_EMAIL
const PASSWORD = process.env.PB_SUPERUSER_PASSWORD

if (!EMAIL || !PASSWORD) {
  console.error(
    '[menu] PB_SUPERUSER_EMAIL and PB_SUPERUSER_PASSWORD are required\n' +
      '  e.g. PB_URL=https://admin.greatbear.in PB_SUPERUSER_EMAIL=admin@greatbear.in \\\n' +
      '       PB_SUPERUSER_PASSWORD=... node scripts/update-menu.mjs',
  )
  process.exit(1)
}

async function auth() {
  const res = await fetch(`${PB_URL}/api/collections/_superusers/auth-with-password`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ identity: EMAIL, password: PASSWORD }),
  })
  if (!res.ok) throw new Error(`superuser auth failed against ${PB_URL} (HTTP ${res.status})`)
  const json = await res.json()
  return json.token
}

async function listAll(collection, token) {
  const records = []
  let page = 1
  for (;;) {
    const res = await fetch(
      `${PB_URL}/api/collections/${collection}/records?sort=sort&perPage=200&page=${page}`,
      { headers: { Authorization: token } },
    )
    if (!res.ok) throw new Error(`list ${collection} failed (HTTP ${res.status})`)
    const json = await res.json()
    records.push(...json.items)
    if (json.items.length < json.perPage || page >= json.totalPages) break
    page += 1
  }
  return records
}

async function deleteRecord(collection, token, id) {
  const res = await fetch(`${PB_URL}/api/collections/${collection}/records/${id}`, {
    method: 'DELETE',
    headers: { Authorization: token },
  })
  if (!res.ok && res.status !== 404) {
    throw new Error(`delete ${collection}/${id} failed (HTTP ${res.status})`)
  }
}

async function createRecord(collection, token, body) {
  const res = await fetch(`${PB_URL}/api/collections/${collection}/records`, {
    method: 'POST',
    headers: { Authorization: token, 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  })
  if (!res.ok) {
    const text = await res.text()
    throw new Error(`create ${collection}/${body.uid} failed (HTTP ${res.status}): ${text}`)
  }
}

try {
  const token = await auth()
  console.log(`[menu] authenticated against ${PB_URL}`)

  for (const [collection, entries] of [
    ['menu_categories', MENU_CATEGORIES],
    ['menu_items', MENU_ITEMS],
  ]) {
    const existing = await listAll(collection, token)
    for (const record of existing) {
      await deleteRecord(collection, token, record.id)
    }
    for (const entry of entries) {
      await createRecord(collection, token, entry)
    }
    console.log(`[menu] ${collection}: -${existing.length} old, +${entries.length} new`)
  }

  console.log('[menu] done — the live menu now matches app/src/data/menu-data.mjs')
} catch (error) {
  console.error(`[menu] failed: ${error.message}`)
  process.exit(1)
}
