// Geocode the 16 World Cup 2026 venues once (Open-Meteo geocoding, keyless)
// → public/data/venues.json with lat/lon/elevation/timezone per fixture-venue
// string. Elevation matters here: Mexico City sits at ~2,240m.
import { writeFileSync, mkdirSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';

const OUT_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'public', 'data');

/** fixture venue string → geocoding query + expected country (disambiguator) */
const VENUES: Record<string, { q: string; cc: string }> = {
  'Atlanta': { q: 'Atlanta', cc: 'US' },
  'Boston (Foxborough)': { q: 'Foxborough', cc: 'US' },
  'Dallas (Arlington)': { q: 'Arlington', cc: 'US' },
  'Guadalajara (Zapopan)': { q: 'Zapopan', cc: 'MX' },
  'Houston': { q: 'Houston', cc: 'US' },
  'Kansas City': { q: 'Kansas City', cc: 'US' },
  'Los Angeles (Inglewood)': { q: 'Inglewood', cc: 'US' },
  'Mexico City': { q: 'Mexico City', cc: 'MX' },
  'Miami (Miami Gardens)': { q: 'Miami Gardens', cc: 'US' },
  'Monterrey (Guadalupe)': { q: 'Guadalupe', cc: 'MX' },
  'New York/New Jersey (East Rutherford)': { q: 'East Rutherford', cc: 'US' },
  'Philadelphia': { q: 'Philadelphia', cc: 'US' },
  'San Francisco Bay Area (Santa Clara)': { q: 'Santa Clara', cc: 'US' },
  'Seattle': { q: 'Seattle', cc: 'US' },
  'Toronto': { q: 'Toronto', cc: 'CA' },
  'Vancouver': { q: 'Vancouver', cc: 'CA' },
};

/** Geocoder misses (e.g. "Vancouver" resolving to a Vancouver-Island point):
 *  pin the known city coordinates explicitly. */
const OVERRIDES: Record<string, { lat: number; lon: number; elevation: number; tz: string }> = {
  Vancouver: { lat: 49.2827, lon: -123.1207, elevation: 70, tz: 'America/Vancouver' },
};

interface GeoResult {
  results?: { latitude: number; longitude: number; elevation?: number; timezone?: string; name: string; country_code?: string }[];
}

async function main(): Promise<void> {
  const out: Record<string, { lat: number; lon: number; elevation: number; tz: string }> = {};
  for (const [venue, { q, cc }] of Object.entries(VENUES)) {
    const override = OVERRIDES[venue];
    if (override) {
      out[venue] = override;
      console.log(venue, '→ (override)', override);
      continue;
    }
    const url = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(q)}&count=10&language=en&format=json`;
    const res = await fetch(url);
    const d = (await res.json()) as GeoResult & { results?: { population?: number }[] };
    const candidates = (d.results ?? []).filter((x) => x.country_code === cc);
    const r = candidates.sort((a, b) => ((b as { population?: number }).population ?? 0) - ((a as { population?: number }).population ?? 0))[0];
    if (!r) throw new Error(`no geocoding result for ${venue} (${q}, ${cc})`);
    out[venue] = {
      lat: +r.latitude.toFixed(4),
      lon: +r.longitude.toFixed(4),
      elevation: Math.round(r.elevation ?? 0),
      tz: r.timezone ?? 'UTC',
    };
    console.log(venue, '→', out[venue]);
    await new Promise((resolve) => setTimeout(resolve, 250));
  }
  mkdirSync(OUT_DIR, { recursive: true });
  writeFileSync(join(OUT_DIR, 'venues.json'), JSON.stringify({ generatedAt: new Date().toISOString(), venues: out }, null, 1));
  console.log(`venues → public/data/venues.json (${Object.keys(out).length})`);
}

void main();
