"use client";

import { useEffect, useState } from "react";
import { motion } from "framer-motion";
import { AlertTriangle, Droplets, Gauge, MapPin, Navigation, Umbrella, Wind } from "lucide-react";
import {
  calculateFeelsLike,
  formatDateTime,
  formatHumidity,
  formatPressure,
  formatRainfall,
  formatTemperature,
  formatWind,
  getWeatherDescription,
  getWeatherMoodFromData,
} from "@/lib/weather-utils";
import type { SynopStation, WeatherMood } from "@/types/imgw";
import type { ImgwCurrentWeather } from "@/types/imgw-current";
import { WeatherIcon } from "@/components/weather/weather-icon";
import { WeatherEffects } from "@/components/weather/weather-effects";
import { useI18n } from "@/lib/i18n";
import { useWeatherStore } from "@/lib/store";

type DevWeatherEffectOverride = "rain" | "thunderstorm" | "none";

function moodAccentClass(mood: WeatherMood) {
  return {
    warm: "border-accent/25 bg-accent/10 text-accent",
    cloudy: "border-border/70 bg-surface-muted text-muted",
    wind: "border-border/70 bg-surface-muted text-muted",
    cold: "border-border/70 bg-surface-muted text-muted",
    night: "border-border/70 bg-surface-muted text-muted",
    mild: "border-accent/25 bg-accent/10 text-accent",
  }[mood];
}

function readDevWeatherEffectOverride(): DevWeatherEffectOverride | null {
  if (process.env.NODE_ENV !== "development" || typeof window === "undefined") return null;
  const effect = new URLSearchParams(window.location.search).get("effect");
  if (effect === "rain" || effect === "thunderstorm" || effect === "none") return effect;
  if (effect === "storm") return "thunderstorm";
  return null;
}

export function WeatherHero({ station, currentWeather, currentWeatherLoading = false, currentForecastWeatherCode, locationName, distanceKm }: { station: SynopStation; currentWeather?: ImgwCurrentWeather | null; currentWeatherLoading?: boolean; currentForecastWeatherCode?: number | null; locationName?: string; distanceKm?: number }) {
  const { language, t } = useI18n();
  const temperatureUnit = useWeatherStore((state) => state.temperatureUnit);
  const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
  const [devEffectOverride, setDevEffectOverride] = useState<DevWeatherEffectOverride | null>(null);
  const displayedLocationName = locationName ?? station.name;
  const hasFullHybridAnalysis = currentWeather?.coverage === "full" || currentWeather?.coverage === "hourly";
  const hasPartialHybridAnalysis = currentWeather?.coverage === "precipitation-only";
  const hasDistantFallback = !hasFullHybridAnalysis && !currentWeatherLoading && distanceKm !== undefined && distanceKm >= 30;
  const displayedStation = currentWeather ? {
    ...station,
    measuredAt: hasFullHybridAnalysis ? currentWeather.measuredAt : station.measuredAt,
    temperature: currentWeather.temperature ?? station.temperature,
    windSpeed: currentWeather.windSpeed ?? station.windSpeed,
    windDirection: currentWeather.windDirection ?? station.windDirection,
    humidity: currentWeather.humidity ?? station.humidity,
    pressure: currentWeather.pressure ?? station.pressure,
    rainfall: currentWeather.precipitation10m ?? station.rainfall,
  } : station;
  const mood = getWeatherMoodFromData(displayedStation);
  const moodAccent = moodAccentClass(mood);
  const feelsLike = currentWeather?.feelsLike ?? calculateFeelsLike(displayedStation.temperature, displayedStation.humidity, displayedStation.windSpeed);
  const metrics = [
    { icon: Droplets, label: t("weather.humidity"), value: formatHumidity(displayedStation.humidity, language) },
    { icon: Wind, label: t("weather.wind"), value: formatWind(displayedStation.windSpeed, null, language, windSpeedUnit) },
    { icon: Umbrella, label: currentWeather?.precipitation10m !== null && currentWeather?.precipitation10m !== undefined ? t("weather.rainfall10m") : t("weather.rainfallTotal"), value: formatRainfall(displayedStation.rainfall, language) },
    { icon: Gauge, label: t("weather.pressure"), value: formatPressure(displayedStation.pressure, language) },
  ];
  const effectPrecipitation10m = devEffectOverride === "rain" || devEffectOverride === "thunderstorm"
    ? 0.1
    : devEffectOverride === "none"
      ? 0
      : currentWeather?.precipitation10m;
  const effectThunderstorm = devEffectOverride === "thunderstorm"
    ? true
    : devEffectOverride === "rain" || devEffectOverride === "none"
      ? false
      : currentWeather?.condition === "thunderstorm";
  const weatherDescription = getWeatherDescription(displayedStation, language, currentWeather?.condition, currentForecastWeatherCode);

  useEffect(() => {
    if (process.env.NODE_ENV !== "development") return;
    const updateOverride = () => setDevEffectOverride(readDevWeatherEffectOverride());
    updateOverride();
    window.addEventListener("popstate", updateOverride);
    return () => window.removeEventListener("popstate", updateOverride);
  }, []);

  return (
    <motion.section
      initial={{ opacity: 0, y: 18 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.55, ease: "easeOut" }}
      className="relative isolate overflow-hidden rounded-panel border border-border/70 bg-surface-raised px-5 py-6 shadow-card sm:px-8 sm:py-8 lg:px-10"
    >
      <WeatherEffects precipitation10m={effectPrecipitation10m} thunderstorm={effectThunderstorm} />
      <div className="relative z-10">
        <div>
          <div className="flex flex-wrap items-center gap-2">
            <span className="flex items-center gap-1.5 text-sm font-medium text-muted"><MapPin className="size-4" />{displayedLocationName}</span>
            <span className={`rounded-control border px-2.5 py-1 text-[0.68rem] font-semibold uppercase tracking-[0.14em] ${moodAccent}`}>
              {weatherDescription}
            </span>
          </div>
          <div className="mt-2 space-y-1 text-xs text-muted">
            <p>{currentWeatherLoading
              ? t("location.heroHybridLoading", { station: station.name })
              : hasFullHybridAnalysis
              ? t("location.heroHybridSource", { location: displayedLocationName })
              : hasPartialHybridAnalysis
                ? t("location.heroHybridPartial", { station: station.name, distance: distanceKm ?? 0 })
              : locationName
                ? t("location.heroStationFallbackWithDistance", { station: station.name, distance: distanceKm ?? 0 })
                : t("location.heroStationFallback", { station: station.name })}</p>
            {hasFullHybridAnalysis && locationName && <p>{t("location.heroNearestStation", { station: station.name, distance: distanceKm ?? 0 })}</p>}
            {hasDistantFallback && <p className="flex items-start gap-1.5 text-warning"><AlertTriangle className="mt-0.5 size-3.5 shrink-0" />{t("location.heroDistantFallback")}</p>}
          </div>
        </div>
        <div className="mt-8 flex items-end justify-between gap-3 sm:mt-10">
          <div>
            <div className="text-[5.8rem] font-semibold leading-[0.85] tracking-[-0.1em] sm:text-[8rem]">
              {formatTemperature(displayedStation.temperature, language, temperatureUnit)}
            </div>
            <p className="mt-5 text-xl font-medium tracking-tight sm:text-2xl">{weatherDescription}</p>
            <p className="mt-1 text-sm text-muted">{t("weather.feelsLike")} {formatTemperature(feelsLike, language, temperatureUnit)} · {t("weather.measurement")} {formatDateTime(displayedStation.measuredAt, language)}</p>
          </div>
          <WeatherIcon mood={mood} condition={currentWeather?.condition} className="mb-4 size-20 text-accent sm:size-28" />
        </div>
        <div className="mt-8 grid grid-cols-2 gap-2.5 sm:mt-10 lg:grid-cols-4">
          {metrics.map(({ icon: Icon, label, value }) => (
            <div key={label} className="rounded-card border border-border/60 bg-surface-muted p-3.5">
              <div className="flex items-center gap-2 text-xs text-muted"><Icon className="size-3.5 text-accent" />{label}</div>
              <p className="mt-2 text-base font-semibold">{value}</p>
            </div>
          ))}
        </div>
        {displayedStation.windDirection !== null && (
          <p className="mt-4 flex items-center gap-1.5 text-xs text-muted">
            <Navigation className="size-3.5" style={{ transform: `rotate(${displayedStation.windDirection}deg)` }} />
            {t("weather.windDirection")}: {displayedStation.windDirection}°
          </p>
        )}
      </div>
    </motion.section>
  );
}
