import React, { useState, useEffect } from 'react';
import { useQuery } from "@tanstack/react-query";
import { Card, CardContent } from '@/components/ui/card';
import { Calendar as CalendarComponent } from '@/components/ui/calendaredit';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Alert, AlertDescription } from '@/components/ui/alert';
import {
  Sun,
  Cloud,
  CloudRain,
  CloudDrizzle,
  CloudSnow,
  CloudLightning,
  CloudFog,
  CloudSun,
  CircleAlert,
  Tornado,
  Haze,
  Moon,
  Wind,
  Droplets,
  ThermometerSun,
  ThermometerSnowflake,
  Sunrise,
  Sunset,
  AlertTriangle,
  Umbrella,
  ChevronLeft,
  ChevronRight
} from 'lucide-react';
import { cn } from "@/lib/utils";

const OFFICE_TZ = 'America/New_York'; // office wall-clock (see docs/TIME.md)
const officeHour = (date) =>
  Number(date.toLocaleString('en-US', { hour: 'numeric', hour12: false, timeZone: OFFICE_TZ })) % 24;

const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
  const [datetime, setDatetime] = useState(new Date());
  const [prevTime, setPrevTime] = useState(getTimeComponents(new Date()));
  const [isTimeChanging, setIsTimeChanging] = useState(false);
  const [mounted, setMounted] = useState(false);
  const { data: weatherData } = useQuery({
    queryKey: ["weather-current-forecast"],
    queryFn: async () => {
      const API_KEY = import.meta.env.VITE_OPENWEATHER_API_KEY;
      const [weatherResponse, forecastResponse] = await Promise.all([
        fetch(
          `https://api.openweathermap.org/data/2.5/weather?lat=43.63507&lon=-84.18995&appid=${API_KEY}&units=imperial`
        ),
        fetch(
          `https://api.openweathermap.org/data/2.5/forecast?lat=43.63507&lon=-84.18995&appid=${API_KEY}&units=imperial`
        )
      ]);

      const weather = await weatherResponse.json();
      const forecastData = await forecastResponse.json();

      const dailyForecasts = forecastData.list.reduce((acc, item) => {
        const date = new Date(item.dt * 1000).toLocaleDateString();
        if (!acc[date]) {
          acc[date] = {
            ...item,
            precipitation: item.rain?.['3h'] || item.snow?.['3h'] || 0,
            pop: item.pop * 100,
          };
        }
        return acc;
      }, {});

      return {
        weather,
        forecast: Object.values(dailyForecasts).slice(0, 5),
      };
    },
    refetchInterval: 300000,
  });

  const weather = weatherData?.weather ?? null;
  const forecast = weatherData?.forecast ?? null;

  useEffect(() => {
    setTimeout(() => setMounted(true), 150);

    const timer = setInterval(() => {
      const newDate = new Date();
      const newTime = getTimeComponents(newDate);

      if (newTime.minutes !== prevTime.minutes) {
        setIsTimeChanging(true);
        setTimeout(() => setIsTimeChanging(false), 200);
      }

      setPrevTime(newTime);
      setDatetime(newDate);
    }, 1000);
    return () => clearInterval(timer);
  }, [prevTime]);

  function getTimeComponents(date) {
    const hour24 = officeHour(date);
    const minutes = Number(date.toLocaleString('en-US', { minute: 'numeric', timeZone: OFFICE_TZ }));
    const ampm = hour24 >= 12 ? 'PM' : 'AM';
    const hours = hour24 % 12 || 12;
    return {
      hours: hours.toString(),
      minutes: minutes.toString().padStart(2, '0'),
      ampm
    };
  }

  const formatDate = (date) => {
    return {
      weekday: date.toLocaleDateString('en-US', { weekday: 'long', timeZone: OFFICE_TZ }),
      month: date.toLocaleDateString('en-US', { month: 'long', timeZone: OFFICE_TZ }),
      day: Number(date.toLocaleDateString('en-US', { day: 'numeric', timeZone: OFFICE_TZ }))
    };
  };

  const getWeatherIcon = (weatherCode, currentTime, small = false) => {
    if (!weatherCode) return <CircleAlert className="w-12 h-12 text-red-500" />;
    const code = parseInt(weatherCode, 10);
    const iconProps = small ? "w-8 h-8" : "w-12 h-12";
    const isNight = officeHour(currentTime) >= 18 || officeHour(currentTime) < 6;
    
    switch (true) {
      case code >= 200 && code < 300:
        return <CloudLightning className={cn(iconProps, "text-yellow-300")} />;
      case code >= 300 && code < 500:
        return <CloudDrizzle className={cn(iconProps, "text-blue-300")} />;
      case code >= 500 && code < 600:
        return <CloudRain className={cn(iconProps, "text-blue-300")} />;
      case code >= 600 && code < 700:
        return <CloudSnow className={cn(iconProps, "text-blue-200")} />;
      case code >= 700 && code < 721:
        return <CloudFog className={cn(iconProps, "text-gray-300")} />;
      case code === 721:
        return <Haze className={cn(iconProps, "text-gray-300")} />;
      case code >= 722 && code < 781:
        return <CloudFog className={cn(iconProps, "text-gray-300")} />;
      case code === 781:
        return <Tornado className={cn(iconProps, "text-gray-300")} />;
      case code === 800:
        return officeHour(currentTime) >= 6 && officeHour(currentTime) < 18 ? (
          <Sun className={cn(iconProps, "text-yellow-300")} />
        ) : (
          <Moon className={cn(iconProps, "text-gray-300")} />
        );
      case code >= 800 && code < 803:
        return <CloudSun className={cn(iconProps, isNight ? "text-gray-300" : "text-gray-200")} />;
      case code >= 803:
        return <Cloud className={cn(iconProps, "text-gray-300")} />;
      default:
        return <CircleAlert className={cn(iconProps, "text-red-500")} />;
    }
  };

  const getWeatherBackground = (weatherCode, isNight) => {
    const code = parseInt(weatherCode, 10);
    
    // Thunderstorm (200-299)
    if (code >= 200 && code < 300) {
      return "bg-gradient-to-br from-slate-900 to-purple-800";
    }
    
    // Drizzle (300-399)
    if (code >= 300 && code < 400) {
      return "bg-gradient-to-br from-slate-800 to-blue-800";
    }
    
    // Rain (500-599)
    if (code >= 500 && code < 600) {
      return "bg-gradient-to-br from-slate-800 to-blue-800";
    }
    
    // Snow (600-699)
    if (code >= 600 && code < 700) {
      return "bg-gradient-to-br from-slate-700 to-blue-800";
    }
    
    // Atmosphere (700-799: mist, smoke, haze, fog, etc.)
    if (code >= 700 && code < 800) {
      return "bg-gradient-to-br from-slate-700 to-slate-500";
    }
    
    // Clear (800)
    if (code === 800) {
      if (isNight) {
        return "bg-gradient-to-br from-slate-900 to-blue-900";
      }
      return "bg-gradient-to-br from-blue-600 to-sky-400";
    }
    
    // Clouds (801-804)
    if (code > 800) {
      if (isNight) {
        return "bg-gradient-to-br from-slate-800 to-slate-600";
      }
      return "bg-gradient-to-br from-slate-600 to-slate-400";
    }
    
    // Default fallback
    return "bg-gradient-to-br from-slate-700 to-slate-500";
  };
  
  const getTemperatureColor = (weatherCode, isNight) => {
    const code = parseInt(weatherCode, 10);
    
    // Snow - dark background, light text
    if (code >= 600 && code < 700) {
      return "text-white";
    }
    
    // Clear day - light background, dark text
    if (code === 800 && !isNight) {
      return "text-white";
    }
    
    // Cloudy day - medium background, ensure contrast
    if (code > 800 && !isNight) {
      return "text-white";
    }
    
    // All other cases (darker backgrounds)
    return "text-white";
  };

  const { hours, minutes, ampm } = getTimeComponents(datetime);
  const dateInfo = formatDate(datetime);

  const formatTime = (timestamp) => {
    if (!timestamp) return '--:--';
    const date = new Date(timestamp * 1000);
    return date.toLocaleTimeString('en-US', {
      hour: 'numeric',
      minute: '2-digit',
      hour12: true,
      timeZone: OFFICE_TZ
    });
  };

  const WeatherDetails = () => (
    <div className="space-y-4 p-3">
      <div className="grid grid-cols-3 gap-2">
        <Card className="bg-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] p-2">
          <div className="flex items-center gap-1">
            <ThermometerSun className="w-5 h-5 text-yellow-300" />
            <div className="flex flex-col">
              <span className="text-xs text-slate-300">High</span>
              <span className="text-sm font-bold text-white">{Math.round(weather.main.temp_max)}°F</span>
            </div>
          </div>
        </Card>
        
        <Card className="bg-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] p-2">
          <div className="flex items-center gap-1">
            <ThermometerSnowflake className="w-5 h-5 text-blue-300" />
            <div className="flex flex-col">
              <span className="text-xs text-slate-300">Low</span>
              <span className="text-sm font-bold text-white">{Math.round(weather.main.temp_min)}°F</span>
            </div>
          </div>
        </Card>

        <Card className="bg-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] p-2">
          <div className="flex items-center gap-1">
            <Droplets className="w-5 h-5 text-blue-300" />
            <div className="flex flex-col">
              <span className="text-xs text-slate-300">Humidity</span>
              <span className="text-sm font-bold text-white">{weather.main.humidity}%</span>
            </div>
          </div>
        </Card>

        <Card className="bg-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] p-2">
          <div className="flex items-center gap-1">
            <Wind className="w-5 h-5 text-slate-300" />
            <div className="flex flex-col">
              <span className="text-xs text-slate-300">Wind</span>
              <span className="text-sm font-bold text-white">{Math.round(weather.wind.speed)} mph</span>
            </div>
          </div>
        </Card>

        <Card className="bg-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] p-2">
          <div className="flex items-center gap-1">
            <Sunrise className="w-5 h-5 text-yellow-300" />
            <div className="flex flex-col">
              <span className="text-xs text-slate-300">Sunrise</span>
              <span className="text-sm font-bold text-white">{formatTime(weather.sys?.sunrise)}</span>
            </div>
          </div>
        </Card>

        <Card className="bg-slate-700/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] p-2">
          <div className="flex items-center gap-1">
            <Sunset className="w-5 h-5 text-orange-300" />
            <div className="flex flex-col">
              <span className="text-xs text-slate-300">Sunset</span>
              <span className="text-sm font-bold text-white">{formatTime(weather.sys?.sunset)}</span>
            </div>
          </div>
        </Card>
      </div>

      {forecast && (
        <div>
          <div className="grid grid-cols-5 gap-2">
            {forecast.map((day, index) => {
              const forecastTime = new Date(day.dt * 1000);
              const isNight = officeHour(forecastTime) >= 18 || officeHour(forecastTime) < 6;
              return (
                <Card 
                  key={index} 
                  className={cn(
                    getWeatherBackground(day.weather[0].id, isNight),
                    "p-2 border-white/[0.08] ring-1 ring-white/[0.05]"
                  )}
                >
                  <div className="flex flex-col items-center gap-1">
                    <span className="text-sm font-medium text-white">
                      {forecastTime.toLocaleDateString('en-US', { weekday: 'short' })}
                    </span>
                    {getWeatherIcon(day.weather[0].id, forecastTime, true)}
                    <div className="flex justify-center gap-1 items-baseline w-full">
                      <span className="text-sm font-medium text-white">
                        {Math.round(day.main.temp_max)}°
                      </span>
                      <span className="text-xs text-slate-300">
                        {Math.round(day.main.temp_min)}°
                      </span>
                    </div>
                    <div className="flex flex-col items-center gap-1 w-full pt-1">
                      {day.rain?.['3h'] > 0 && (
                        <div className="flex items-center gap-1">
                          <CloudRain className="w-3 h-3 text-blue-300" />
                          <span className="text-xs text-white">{day.rain['3h'].toFixed(2)}"</span>
                        </div>
                      )}
                      {day.snow?.['3h'] > 0 && (
                        <div className="flex items-center gap-1">
                          <CloudSnow className="w-3 h-3 text-blue-300" />
                          <span className="text-xs text-white">{day.snow['3h'].toFixed(2)}"</span>
                        </div>
                      )}
                      {!day.rain?.['3h'] && !day.snow?.['3h'] && (
                        <div className="flex items-center gap-1">
                          <Umbrella className="w-3 h-3 text-slate-300" />
                          <span className="text-xs text-white">0"</span>
                        </div>
                      )}
                    </div>
                  </div>
                </Card>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );

  return (
    <div className="flex flex-col items-center w-full transition-opacity duration-300 ${mounted ? 'opacity-100' : 'opacity-0'}">
      {/* Time Display */}
      <Card className="bg-gradient-to-br mb-[7px] from-indigo-900/70 to-blue-800/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20 px-1 py-2 w-full hover:scale-[1.02] transition-transform duration-300">
        <CardContent className="p-3 h-[106px] flex items-center">
          <div className="flex justify-center items-baseline w-full tracking-tighter">
            <div className={`transition-opacity duration-200 ${isTimeChanging ? 'opacity-60' : 'opacity-100'}`}>
              <span className="text-7xl font-light text-white">{hours}</span>
              <span className="text-7xl font-light text-white">:</span>
              <span className="text-7xl font-light text-white">{minutes}</span>
              <span className="text-lg font-light text-white/90 ml-1">{ampm}</span>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Date and Weather Display */}
      <div className="h-[121px] mb-[7px] grid grid-cols-2 gap-2 w-full">
        <Card className="h-full bg-gradient-to-br from-violet-900/70 to-purple-800/50 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20 flex items-center justify-center">
          <CardContent className="h-full p-0">
            <div className="flex flex-col items-center justify-center h-full">
              <span className="text-6xl font-light text-white tracking-tighter">
                {dateInfo.day}
              </span>
              <span className="text-sm font-bold text-white mt-2">
                {dateInfo.weekday}
              </span>
            </div>
          </CardContent>
        </Card>

        {weather?.main && (
          <Popover>
            <PopoverTrigger asChild>
              <Card className={cn(
                getWeatherBackground(
                  weather.weather[0]?.id,
                  officeHour(datetime) >= 18 || officeHour(datetime) < 6
                ),
                "flex items-center justify-center cursor-pointer hover:brightness-110 hover:ring-white/[0.12] transition-all relative backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20"
              )}>
                <CardContent className="h-full p-3">
                  <div className="flex flex-col items-center">
                    {getWeatherIcon(weather.weather[0]?.id, datetime)}
                    <span className="text-3xl font-normal ml-1 mt-2 text-white">
                      {Math.round(weather.main.temp)}°
                    </span>
                  </div>
                </CardContent>
                {weather.alerts && (
                  <div className="absolute top-1 right-1">
                    <AlertTriangle className="w-5 h-5 text-red-500" />
                  </div>
                )}
              </Card>
            </PopoverTrigger>
            <PopoverContent 
              className="w-[450px] bg-gradient-to-br from-slate-800/90 to-slate-700/80 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20"
              align="start"
              side="right"
              sideOffset={10}
              style={{ 
                transform: `scale(${scaleFactor})`,
                transformOrigin: 'left top'
              }}
            >
              {weather.alerts && (
                <Alert variant="warning" className="mb-3 bg-amber-900/50 border-amber-700">
                  <AlertTriangle className="h-3 w-3 text-amber-500" />
                  <AlertDescription className="text-xs text-amber-200">
                    {weather.alerts[0].event}
                  </AlertDescription>
                </Alert>
              )}
              <WeatherDetails />
            </PopoverContent>
          </Popover>
        )}
      </div>

      {/* Calendar Display */}
      <Card className="w-full h-[208px] bg-gradient-to-br from-slate-900 to-slate-800/70 backdrop-blur-xl border-white/[0.08] ring-1 ring-white/[0.05] shadow-lg shadow-black/20">
        <CardContent className="p-0">
          <CalendarComponent
            selected={datetime}
            className="w-full"
            classNames={{
              caption: "flex justify-center relative items-center mt-1 mb-2",
              caption_label: "text-sm font-medium text-white",
              nav_button: cn(
                "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
                "hover:bg-white/10 h-5 w-5 bg-transparent p-0 text-slate-300 hover:text-white"
              ),
              table: "w-full border-collapse",
              head_cell: "text-slate-400 rounded-md font-normal text-[0.65rem] w-full mb-0.5",
              row: "flex w-full",
              cell: cn(
                "w-full relative p-0 text-center text-xs focus-within:relative focus-within:z-20",
                "[&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50",
                "[&:has([aria-selected])]:rounded-md"
              ),
              day: cn(
                "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
                "hover:bg-white/10 h-6 w-full p-0 font-normal text-xs text-slate-200 aria-selected:opacity-100"
              ),
              day_selected: "bg-indigo-500/60 text-white hover:bg-indigo-500/70 focus:bg-indigo-500/70",
              day_today: "bg-white/10 text-white font-semibold",
              day_outside: "day-outside text-slate-500 aria-selected:bg-accent/50 aria-selected:text-slate-400",
              day_disabled: "text-slate-600 opacity-50",
            }}
          />
        </CardContent>
      </Card>
    </div>
  );
};

export default DateTimeWeatherDisplay;