import { NextResponse } from 'next/server'; interface Controller { callsign: string; frequency: string; facility: number; } const facilityTypes = { 0: "OBS", 1: "FSS", 2: "DEL", 3: "GND", 4: "TWR", 5: "APP", 6: "CTR", } as const; const facilityLongNames = { OBS: "Observer", FSS: "Flight Service Station", DEL: "Clearance Delivery", GND: "Ground", TWR: "Tower", APP: "Approach/Departure", CTR: "Centre", } as const; // Define FIR coverage for airports const firCoverage: Record = { CZQM: ["CYHZ", "CYFC", "CYQM", "CYSJ", "CYZX", "CYYG", "CYYT", "CYQX", "CYYR", "LFVP", "CYQI", "CYAY", "CYDF", "CYJT"], CZUL: ["CYZV"], }; export async function GET() { try { const response = await fetch('https://data.vatsim.net/v3/vatsim-data.json', { next: { revalidate: 60 } }); if (!response.ok) { throw new Error('Failed to fetch VATSIM data'); } const data = await response.json(); // First, get all controllers including CTR const allControllers = data.controllers.map((controller: Controller) => { const shortFacility = facilityTypes[controller.facility as keyof typeof facilityTypes] || "Unknown"; return { callsign: controller.callsign, frequency: controller.frequency, facility: shortFacility, facilityLong: facilityLongNames[shortFacility as keyof typeof facilityLongNames] || "Unknown", facilityType: controller.facility, airport: controller.callsign.split('_')[0] }; }); // Separate CTR controllers const ctrControllers = allControllers.filter(c => c.facilityType === 6); // Get non-CTR controllers const localControllers = allControllers.filter(c => c.facilityType < 6 && c.facilityType > 0 && !c.callsign.includes("ATIS")); // Group local controllers by airport const controllersByAirport = localControllers.reduce((acc: any, controller) => { if (!acc[controller.airport]) { acc[controller.airport] = []; } acc[controller.airport].push(controller); return acc; }, {}); // Sort controllers at each airport by facility type (higher number = higher priority) Object.values(controllersByAirport).forEach((controllers: any) => { controllers.sort((a: any, b: any) => b.facilityType - a.facilityType); }); // Add CTR coverage for airports without local controllers ctrControllers.forEach(ctr => { const fir = ctr.callsign.split('_')[0]; const coveredAirports = firCoverage[fir] || []; coveredAirports.forEach(airport => { // Only add CTR if no local controllers are available if (!controllersByAirport[airport] || controllersByAirport[airport].length === 0) { controllersByAirport[airport] = [{ callsign: ctr.callsign, frequency: ctr.frequency, facility: ctr.facility, facilityLong: "Centre (Top-down)", airport: airport }]; } }); }); return NextResponse.json(controllersByAirport); } catch (error) { console.error(error); return NextResponse.json({ error: 'Failed to fetch controller data' }, { status: 500 }); } }