// Wetter-Check für Outdoor-Shootings (siehe weatherCheck.ts) — nutzt
// Open-Meteo (open-meteo.com), da kostenlos und ohne API-Key nutzbar, im
// Gegensatz zu den meisten anderen Wetterdiensten. Kein Vertrag/Schlüssel
// nötig, den man in den Einstellungen pflegen müsste.

export type GeocodedLocation = { latitude: number; longitude: number };

export async function geocodeCity(city: string, countryCode?: string): Promise<GeocodedLocation | null> {
  if (!city.trim()) return null;
  try {
    const url = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(city.trim())}&count=5&language=de&format=json`;
    const res = await fetch(url);
    if (!res.ok) return null;
    const data = (await res.json()) as { results?: { latitude: number; longitude: number; country_code?: string }[] };
    if (!data.results || data.results.length === 0) return null;
    // Bevorzugt ein Ergebnis mit passendem Ländercode (mehrdeutige Städtenamen
    // wie "Bielefeld" sind selten, aber z. B. "Berlin" gibt es auch in den USA).
    const match =
      (countryCode && data.results.find((r) => r.country_code?.toUpperCase() === countryCode.toUpperCase())) ||
      data.results[0];
    return { latitude: match.latitude, longitude: match.longitude };
  } catch {
    return null;
  }
}

export type WeatherForecast = {
  date: string;
  weatherCode: number;
  precipitationProbabilityMax: number;
  temperatureMax: number;
  temperatureMin: number;
};

// Liefert die Tages-Vorhersage für genau das Datum des Shootings — Open-Meteo
// erlaubt Vorhersagen bis 16 Tage im Voraus, für unseren ~48h-Vorlauf reicht
// das komfortabel.
// Deutsches Kalenderdatum (nicht date.toISOString(), das das UTC-Datum
// liefert) — für ein Shooting kurz nach Mitternacht deutscher Zeit (z. B.
// 00:30 Uhr CEST = 22:30 Uhr UTC am Vortag) würde toISOString() sonst den
// falschen, einen Tag zu frühen Vorhersagetag abfragen.
const BERLIN_DATE_FORMATTER = new Intl.DateTimeFormat("en-CA", { timeZone: "Europe/Berlin" });
function berlinDateStr(date: Date): string {
  return BERLIN_DATE_FORMATTER.format(date); // en-CA formattiert als YYYY-MM-DD
}

export async function getDailyForecast(location: GeocodedLocation, date: Date): Promise<WeatherForecast | null> {
  try {
    const dateStr = berlinDateStr(date);
    const url =
      `https://api.open-meteo.com/v1/forecast?latitude=${location.latitude}&longitude=${location.longitude}` +
      `&daily=weather_code,precipitation_probability_max,temperature_2m_max,temperature_2m_min` +
      `&timezone=auto&start_date=${dateStr}&end_date=${dateStr}`;
    const res = await fetch(url);
    if (!res.ok) return null;
    const data = (await res.json()) as {
      daily?: {
        time: string[];
        weather_code: number[];
        precipitation_probability_max: number[];
        temperature_2m_max: number[];
        temperature_2m_min: number[];
      };
    };
    if (!data.daily || data.daily.time.length === 0) return null;
    return {
      date: data.daily.time[0],
      weatherCode: data.daily.weather_code[0],
      precipitationProbabilityMax: data.daily.precipitation_probability_max[0],
      temperatureMax: data.daily.temperature_2m_max[0],
      temperatureMin: data.daily.temperature_2m_min[0],
    };
  } catch {
    return null;
  }
}

// WMO-Wettercodes (von Open-Meteo verwendet): ab 51 beginnt Niederschlag
// (Nieselregen), 95+ ist Gewitter. Zusätzlich hohe Regenwahrscheinlichkeit
// auch ohne "offiziellen" Niederschlagscode als eigenes Kriterium.
export function isBadWeatherLikely(forecast: WeatherForecast): boolean {
  return forecast.weatherCode >= 51 || forecast.precipitationProbabilityMax >= 60;
}

export function describeWeatherCode(code: number, isEn: boolean): string {
  if (code >= 95) return isEn ? "thunderstorms" : "Gewitter";
  if (code >= 85) return isEn ? "snow showers" : "Schneeschauer";
  if (code >= 80) return isEn ? "rain showers" : "Regenschauer";
  if (code >= 71) return isEn ? "snow" : "Schnee";
  if (code >= 61) return isEn ? "rain" : "Regen";
  if (code >= 51) return isEn ? "drizzle" : "Nieselregen";
  if (code >= 45) return isEn ? "fog" : "Nebel";
  if (code >= 1) return isEn ? "clouds" : "Bewölkung";
  return isEn ? "clear skies" : "klarer Himmel";
}
