/**
 * Server-side PocketBase access.
 *
 * All content lives in PocketBase; this module fetches it over the local
 * HTTP API. If PocketBase is unreachable (e.g. during an image build check
 * or a maintenance restart) every fetch falls back to the bundled seed
 * content so the site still renders.
 */
import seed from '~/data/content.json'
// The food menu lives in its own module (shared with scripts/update-menu.mjs)
// instead of content.json, since it is synced by its own script.
import { MENU_CATEGORIES, MENU_ITEMS } from '~/data/menu-data.mjs'
import type {
  Brew,
  Experience,
  MenuCategory,
  MenuItem,
  Pairing,
  Settings,
  Stat,
  Testimonial,
} from './types'

const PB_URL = process.env.PB_URL ?? 'http://127.0.0.1:8090'

const TIMEOUT_MS = 3000

interface PbRecords<T> {
  items: T[]
}

async function pbList<T>(collection: string): Promise<T[] | null> {
  try {
    const res = await fetch(
      `${PB_URL}/api/collections/${collection}/records?sort=sort&perPage=200`,
      { signal: AbortSignal.timeout(TIMEOUT_MS) },
    )
    if (!res.ok) return null
    const json = (await res.json()) as PbRecords<T>
    return json.items
  } catch {
    return null
  }
}

function orFallback<T>(items: T[] | null, fallback: T[]): T[] {
  return items && items.length > 0 ? items : fallback
}

export async function fetchSettings(): Promise<Settings> {
  const items = await pbList<Settings>('settings')
  return items?.[0] ?? seed.settings
}

export async function fetchStats(): Promise<Stat[]> {
  return orFallback(await pbList<Stat>('stats'), seed.stats)
}

export async function fetchBrews(): Promise<Brew[]> {
  return orFallback(await pbList<Brew>('brews'), seed.brews)
}

export async function fetchExperiences(): Promise<Experience[]> {
  return orFallback(await pbList<Experience>('experiences'), seed.experiences)
}

export async function fetchTestimonials(): Promise<Testimonial[]> {
  return orFallback(await pbList<Testimonial>('testimonials'), seed.testimonials)
}

export async function fetchMenuCategories(): Promise<MenuCategory[]> {
  return orFallback(
    await pbList<MenuCategory>('menu_categories'),
    MENU_CATEGORIES as MenuCategory[],
  )
}

export async function fetchMenuItems(): Promise<MenuItem[]> {
  return orFallback(await pbList<MenuItem>('menu_items'), MENU_ITEMS as MenuItem[])
}

export async function fetchPairings(): Promise<Pairing[]> {
  return orFallback(await pbList<Pairing>('pairings'), seed.pairings)
}

export interface CreateReservationPayload {
  name: string
  phone: string
  source: string
  date?: string
  time?: string
  guests?: string
  requests?: string
}

export async function createReservationRecord(payload: CreateReservationPayload): Promise<void> {
  const res = await fetch(`${PB_URL}/api/collections/reservations/records`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
    signal: AbortSignal.timeout(TIMEOUT_MS),
  })
  if (!res.ok) {
    throw new Error(`PocketBase rejected the reservation (HTTP ${res.status})`)
  }
}
