import { NextResponse } from "next/server" import { getGoogleSheetsClient } from "@/lib/google-sheets" import { BOOKING_CRITERIA } from "@/lib/event.config" const BOOKING_SHEET_ID = process.env.BOOKING_SHEET_ID const BOOKING_SHEET_NAME = process.env.BOOKING_SHEET_NAME || "Sheet1" // In-memory cache (2-min TTL) let cache: { data: Record | null; timestamp: number } = { data: null, timestamp: 0 } const CACHE_TTL_MS = 2 * 60 * 1000 interface BedRow { venue: string bedType: string occupied: boolean } function parseBedsFromSheet(data: string[][]): BedRow[] { const beds: BedRow[] = [] let currentVenue = "" let bedTypeCol = -1 let dateColumnIndices: number[] = [] let inDataSection = false const venueNames = [...new Set(Object.values(BOOKING_CRITERIA).map((c) => c.venue.toLowerCase()))] for (const row of data) { if (!row || row.length === 0) { inDataSection = false continue } const firstCell = (row[0] || "").trim().toLowerCase() const matchedVenue = venueNames.find((v) => firstCell.includes(v)) if (matchedVenue) { const criteria = Object.values(BOOKING_CRITERIA).find((c) => c.venue.toLowerCase() === matchedVenue) currentVenue = criteria?.venue || row[0].trim() inDataSection = false continue } if (!currentVenue) continue const lowerRow = row.map((c) => (c || "").trim().toLowerCase()) const roomIdx = lowerRow.findIndex((c) => c === "room" || c === "room #" || c === "room number") const bedIdx = lowerRow.findIndex((c) => c === "bed type" || c === "bed" || c === "type" || c === "bed/type") if (roomIdx !== -1 && bedIdx !== -1) { bedTypeCol = bedIdx dateColumnIndices = [] for (let j = bedIdx + 1; j < row.length; j++) { if ((row[j] || "").trim()) dateColumnIndices.push(j) } inDataSection = true continue } if (inDataSection && bedTypeCol !== -1) { let bedType = (row[bedTypeCol] || "").trim().toLowerCase() if (!bedType) continue if (bedType.includes("(") && !bedType.includes(")")) bedType += ")" const occupied = dateColumnIndices.some((colIdx) => (row[colIdx] || "").trim().length > 0) beds.push({ venue: currentVenue, bedType, occupied }) } } return beds } async function checkAvailability(): Promise | null> { if (!BOOKING_SHEET_ID) return null const now = Date.now() if (cache.data && now - cache.timestamp < CACHE_TTL_MS) { return cache.data } try { const sheets = getGoogleSheetsClient() const response = await sheets.spreadsheets.values.get({ spreadsheetId: BOOKING_SHEET_ID, range: BOOKING_SHEET_NAME, }) const sheetData = response.data.values || [] if (sheetData.length === 0) return null const beds = parseBedsFromSheet(sheetData) const availability: Record = {} for (const [type, criteria] of Object.entries(BOOKING_CRITERIA)) { availability[type] = beds.some( (bed) => bed.venue === criteria.venue && criteria.bedTypes.includes(bed.bedType) && !bed.occupied && (!criteria.roomFilter || true) // roomFilter not applicable to availability-only check ) } cache.data = availability cache.timestamp = now return availability } catch (error) { console.error("[Availability] Error checking availability:", error) return null } } export async function GET() { const availability = await checkAvailability() if (!availability) { return NextResponse.json({ error: "Booking sheet not configured" }, { status: 503 }) } return NextResponse.json(availability) }