// Open-Meteo (keyless, works from the VPS): kickoff-hour weather per venue.
// Venues are pre-geocoded at build time into public/data/venues.json —
// includes elevation (Mexico City 2,240m), which is its own story.
import { cachedFetch } from './fetcher';
import { loadStatic } from '../preview';

const SOURCE = 'open-meteo';

interface VenuesFile {
  venues: Record<string, { lat: number; lon: number; elevation: number; tz: string }>;
}

let _venues: VenuesFile | null = null;
const venues = (): VenuesFile => (_venues ??= loadStatic<VenuesFile>('venues.json'));

export interface MatchWeather {
  v: 1;
  fetchedAt: number;
  tempC: number | null;
  precipProbPct: number | null;
  windKmh: number | null;
  elevationM: number;
  tz: string;
}

interface Forecast {
  hourly?: { time?: string[]; temperature_2m?: number[]; precipitation_probability?: number[]; wind_speed_10m?: number[] };
}

/** Kickoff-hour forecast for a fixture's venue (forecast horizon ≈16 days). */
export async function fetchMatchWeather(venue: string, kickoffIso: string): Promise<MatchWeather | null> {
  const v = venues().venues[venue];
  if (!v) return null;
  const url =
    `https://api.open-meteo.com/v1/forecast?latitude=${v.lat}&longitude=${v.lon}` +
    `&hourly=temperature_2m,precipitation_probability,wind_speed_10m&forecast_days=16&timezone=UTC`;
  const f = await cachedFetch<Forecast>(SOURCE, `weather:${venue}`, url, { ttl: 3 * 60 * 60_000, minInterval: 1_000 });
  const hours = f.hourly?.time ?? [];
  const wantHour = kickoffIso.slice(0, 13); // YYYY-MM-DDTHH
  const idx = hours.findIndex((t) => t.startsWith(wantHour));
  if (idx < 0) return null;
  return {
    v: 1,
    fetchedAt: Date.now(),
    tempC: f.hourly?.temperature_2m?.[idx] ?? null,
    precipProbPct: f.hourly?.precipitation_probability?.[idx] ?? null,
    windKmh: f.hourly?.wind_speed_10m?.[idx] ?? null,
    elevationM: v.elevation,
    tz: v.tz,
  };
}
