import { NextResponse } from 'next/server'; // Library branch locations with approximate coordinates const LIBRARY_LOCATIONS: Record = { 'Beckwourth': { lat: 32.7157, lng: -117.1611 }, 'Benjamin': { lat: 32.8328, lng: -117.2713 }, 'Balboa': { lat: 32.7330, lng: -117.1430 }, 'Carmel Mountain': { lat: 32.9286, lng: -117.1311 }, 'Carmel Valley': { lat: 32.9340, lng: -117.2340 }, 'Central Library': { lat: 32.7216, lng: -117.1574 }, 'City Heights': { lat: 32.7411, lng: -117.1045 }, 'Clairemont': { lat: 32.8328, lng: -117.2050 }, 'College-Rolando': { lat: 32.7482, lng: -117.0704 }, 'Kensington': { lat: 32.7644, lng: -117.1164 }, 'La Jolla': { lat: 32.8344, lng: -117.2544 }, 'Linda Vista': { lat: 32.7714, lng: -117.1789 }, 'Logan Heights': { lat: 32.7030, lng: -117.1289 }, 'Malcolm X': { lat: 32.7089, lng: -117.1242 }, 'Mission Hills': { lat: 32.7469, lng: -117.1978 }, 'Oak Park': { lat: 32.7328, lng: -117.1461 }, 'Paradise Hills': { lat: 32.6747, lng: -117.0742 }, 'Rancho Bernardo': { lat: 33.0200, lng: -117.1156 }, 'Rancho Penasquitos': { lat: 32.958034, lng: -117.121975 }, 'San Ysidro': { lat: 32.5592, lng: -117.0431 }, 'Skyline Hills': { lat: 32.6781, lng: -117.0200 }, }; interface BibItem { branchName: string; availability: { statusType: string; }; } interface BiblioResponse { entities: { bibItems: Record; }; } interface LocationData { name: string; lat: number; lng: number; available: boolean; passType: string; } async function fetchAvailabilityData(itemNumber: string): Promise { try { const response = await fetch( `https://gateway.bibliocommons.com/v2/libraries/sandiego/bibs/${itemNumber}/availability?locale=en-US`, { headers: { 'User-Agent': 'Mozilla/5.0 (compatible; LibraryChecker/1.0)', }, } ); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data: BiblioResponse = await response.json(); return Object.values(data.entities.bibItems || {}); } catch (error) { console.error(`Error fetching data for ${itemNumber}:`, error); return []; } } export async function GET() { try { // Fetch both types of passes const [passItems, backpackItems] = await Promise.all([ fetchAvailabilityData('S161C1690437'), // Pure parking pass fetchAvailabilityData('S161C1805116'), // Backpack with pass ]); const locationMap = new Map(); // Process parking passes passItems.forEach(item => { const location = LIBRARY_LOCATIONS[item.branchName]; if (location && item.branchName) { const isAvailable = item.availability?.statusType === 'AVAILABLE'; const existing = locationMap.get(item.branchName); if (existing) { // Update existing entry - if either item type is available, mark as available existing.available = existing.available || isAvailable; existing.passType = 'Both'; } else { locationMap.set(item.branchName, { name: item.branchName, lat: location.lat, lng: location.lng, available: isAvailable, passType: 'Pass Only', }); } } }); // Process backpack items backpackItems.forEach(item => { const location = LIBRARY_LOCATIONS[item.branchName]; if (location && item.branchName) { const isAvailable = item.availability?.statusType === 'AVAILABLE'; const existing = locationMap.get(item.branchName); if (existing) { // Update existing entry - if either item type is available, mark as available existing.available = existing.available || isAvailable; existing.passType = 'Both'; } else { locationMap.set(item.branchName, { name: item.branchName, lat: location.lat, lng: location.lng, available: isAvailable, passType: 'Backpack Only', }); } } }); const locations = Array.from(locationMap.values()); return NextResponse.json({ locations, lastUpdated: new Date().toISOString(), }); } catch (error) { console.error('Error in API route:', error); return NextResponse.json( { error: 'Failed to fetch availability data' }, { status: 500 } ); } }