'use client';

/**
 * 날씨 위젯 컴포넌트
 * - 실시간 날씨 정보를 표시
 * - 컴팩트 모드: 높이가 작을 때 핵심 정보만 표시
 */

import React, { useEffect, useState, useRef } from 'react';
import { getWeather, WeatherData } from '@/lib/api/openApi';
import {
  Cloud,
  CloudRain,
  Sun,
  CloudSnow,
  Wind,
  Droplets,
  Gauge,
  RefreshCw,
  Check,
  ChevronsUpDown,
  Settings,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';
import { cn } from '@/lib/utils';
import { DashboardElement } from '@/components/admin/dashboard/types';

// 컴팩트 모드 임계값 (픽셀)
const COMPACT_HEIGHT_THRESHOLD = 180;

interface WeatherWidgetProps {
  element?: DashboardElement;
  city?: string;
  refreshInterval?: number; // 새로고침 간격 (ms), 기본값: 600000 (10분)
}

export default function WeatherWidget({
  element,
  city = '서울',
  refreshInterval = 600000,
}: WeatherWidgetProps) {
  const [open, setOpen] = useState(false);
  const [settingsOpen, setSettingsOpen] = useState(false);
  const [selectedCity, setSelectedCity] = useState(city);
  const [weather, setWeather] = useState<WeatherData | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
  
  // 컨테이너 높이 측정을 위한 ref
  const containerRef = useRef<HTMLDivElement>(null);
  const [containerHeight, setContainerHeight] = useState<number>(300);
  
  // 컴팩트 모드 여부 (element.size.height 또는 실제 컨테이너 높이 기반)
  const isCompact = element?.size?.height 
    ? element.size.height < COMPACT_HEIGHT_THRESHOLD 
    : containerHeight < COMPACT_HEIGHT_THRESHOLD;
  
  // 컨테이너 높이 측정
  useEffect(() => {
    if (!containerRef.current) return;
    
    const observer = new ResizeObserver((entries) => {
      for (const entry of entries) {
        setContainerHeight(entry.contentRect.height);
      }
    });
    
    observer.observe(containerRef.current);
    return () => observer.disconnect();
  }, []);
  
  // 표시할 날씨 정보 선택
  const [selectedItems, setSelectedItems] = useState<string[]>([
    'temperature',
    'feelsLike',
    'humidity',
    'windSpeed',
    'pressure',
  ]);

  // 날씨 항목 정의
  const weatherItems = [
    { id: 'temperature', label: '기온', icon: Sun },
    { id: 'feelsLike', label: '체감온도', icon: Sun },
    { id: 'humidity', label: '습도', icon: Droplets },
    { id: 'windSpeed', label: '풍속', icon: Wind },
    { id: 'pressure', label: '기압', icon: Gauge },
  ];

  // 항목 토글
  const toggleItem = (itemId: string) => {
    setSelectedItems((prev) =>
      prev.includes(itemId) ? prev.filter((id) => id !== itemId) : [...prev, itemId]
    );
  };

  // 도시 목록 (전국 시/군/구 단위)
  const cities = [
    // 서울특별시 (25개 구)
    { value: '서울', label: '서울' },
    { value: '종로구', label: '서울 종로구' },
    { value: '중구', label: '서울 중구' },
    { value: '용산구', label: '서울 용산구' },
    { value: '성동구', label: '서울 성동구' },
    { value: '광진구', label: '서울 광진구' },
    { value: '동대문구', label: '서울 동대문구' },
    { value: '중랑구', label: '서울 중랑구' },
    { value: '성북구', label: '서울 성북구' },
    { value: '강북구', label: '서울 강북구' },
    { value: '도봉구', label: '서울 도봉구' },
    { value: '노원구', label: '서울 노원구' },
    { value: '은평구', label: '서울 은평구' },
    { value: '서대문구', label: '서울 서대문구' },
    { value: '마포구', label: '서울 마포구' },
    { value: '양천구', label: '서울 양천구' },
    { value: '강서구', label: '서울 강서구' },
    { value: '구로구', label: '서울 구로구' },
    { value: '금천구', label: '서울 금천구' },
    { value: '영등포구', label: '서울 영등포구' },
    { value: '동작구', label: '서울 동작구' },
    { value: '관악구', label: '서울 관악구' },
    { value: '서초구', label: '서울 서초구' },
    { value: '강남구', label: '서울 강남구' },
    { value: '송파구', label: '서울 송파구' },
    { value: '강동구', label: '서울 강동구' },
    
    // 부산광역시
    { value: '부산', label: '부산' },
    { value: '해운대구', label: '부산 해운대구' },
    { value: '부산진구', label: '부산 부산진구' },
    { value: '동래구', label: '부산 동래구' },
    { value: '사하구', label: '부산 사하구' },
    { value: '금정구', label: '부산 금정구' },
    { value: '사상구', label: '부산 사상구' },
    
    // 인천광역시
    { value: '인천', label: '인천' },
    { value: '부평구', label: '인천 부평구' },
    { value: '계양구', label: '인천 계양구' },
    { value: '남동구', label: '인천 남동구' },
    
    // 대구광역시
    { value: '대구', label: '대구' },
    { value: '수성구', label: '대구 수성구' },
    { value: '달서구', label: '대구 달서구' },
    
    // 광주광역시
    { value: '광주', label: '광주' },
    { value: '광산구', label: '광주 광산구' },
    
    // 대전광역시
    { value: '대전', label: '대전' },
    { value: '유성구', label: '대전 유성구' },
    
    // 울산광역시
    { value: '울산', label: '울산' },
    
    // 세종특별자치시
    { value: '세종', label: '세종' },
    
    // 경기도 (주요 도시)
    { value: '수원', label: '수원' },
    { value: '성남', label: '성남' },
    { value: '고양', label: '고양' },
    { value: '용인', label: '용인' },
    { value: '부천', label: '부천' },
    { value: '안산', label: '안산' },
    { value: '안양', label: '안양' },
    { value: '남양주', label: '남양주' },
    { value: '화성', label: '화성' },
    { value: '평택', label: '평택' },
    { value: '의정부', label: '의정부' },
    { value: '시흥', label: '시흥' },
    { value: '파주', label: '파주' },
    { value: '김포', label: '김포' },
    { value: '광명', label: '광명' },
    
    // 강원도
    { value: '춘천', label: '춘천' },
    { value: '원주', label: '원주' },
    { value: '강릉', label: '강릉' },
    { value: '속초', label: '속초' },
    { value: '동해', label: '동해' },
    { value: '태백', label: '태백' },
    { value: '삼척', label: '삼척' },
    
    // 충청북도
    { value: '청주', label: '청주' },
    { value: '충주', label: '충주' },
    { value: '제천', label: '제천' },
    
    // 충청남도
    { value: '천안', label: '천안' },
    { value: '공주', label: '공주' },
    { value: '보령', label: '보령' },
    { value: '아산', label: '아산' },
    { value: '서산', label: '서산' },
    { value: '논산', label: '논산' },
    { value: '당진', label: '당진' },
    
    // 전라북도
    { value: '전주', label: '전주' },
    { value: '군산', label: '군산' },
    { value: '익산', label: '익산' },
    { value: '정읍', label: '정읍' },
    { value: '남원', label: '남원' },
    { value: '김제', label: '김제' },
    
    // 전라남도
    { value: '목포', label: '목포' },
    { value: '여수', label: '여수' },
    { value: '순천', label: '순천' },
    { value: '나주', label: '나주' },
    { value: '광양', label: '광양' },
    
    // 경상북도
    { value: '포항', label: '포항' },
    { value: '경주', label: '경주' },
    { value: '김천', label: '김천' },
    { value: '안동', label: '안동' },
    { value: '구미', label: '구미' },
    { value: '영주', label: '영주' },
    { value: '영천', label: '영천' },
    { value: '상주', label: '상주' },
    { value: '문경', label: '문경' },
    { value: '경산', label: '경산' },
    { value: '울릉도', label: '울릉도' },
    
    // 경상남도
    { value: '창원', label: '창원' },
    { value: '진주', label: '진주' },
    { value: '통영', label: '통영' },
    { value: '사천', label: '사천' },
    { value: '김해', label: '김해' },
    { value: '밀양', label: '밀양' },
    { value: '거제', label: '거제' },
    { value: '양산', label: '양산' },
    
    // 제주특별자치도
    { value: '제주', label: '제주' },
    { value: '서귀포', label: '서귀포' },
  ];

  // 날씨 정보 가져오기
  const fetchWeather = async () => {
    try {
      setLoading(true);
      setError(null);
      const data = await getWeather(selectedCity, 'metric', 'kr');
      setWeather(data);
      setLastUpdated(new Date());
    } catch (err: any) {
      console.error('날씨 조회 실패:', err);
      
      // 에러 메시지 추출
      let errorMessage = '날씨 정보를 가져오는 중 오류가 발생했습니다.';
      
      if (err.response?.status === 503) {
        errorMessage = 'API 키가 설정되지 않았습니다. 관리자에게 문의하세요.';
      } else if (err.response?.status === 401) {
        errorMessage = 'API 키가 유효하지 않습니다.';
      } else if (err.response?.status === 404) {
        errorMessage = `도시를 찾을 수 없습니다: ${city}`;
      } else if (err.response?.data?.message) {
        errorMessage = err.response.data.message;
      }
      
      setError(errorMessage);
    } finally {
      setLoading(false);
    }
  };

  // 초기 로딩 및 자동 새로고침
  useEffect(() => {
    fetchWeather();
    const interval = setInterval(fetchWeather, refreshInterval);
    return () => clearInterval(interval);
  }, [selectedCity, refreshInterval]);

  // 도시 변경 핸들러
  const handleCityChange = (newCity: string) => {
    setSelectedCity(newCity);
  };

  // 날씨 아이콘 선택
  const getWeatherIcon = (weatherMain: string) => {
    switch (weatherMain.toLowerCase()) {
      case 'clear':
        return <Sun className="h-12 w-12 text-warning" />;
      case 'clouds':
        return <Cloud className="h-12 w-12 text-muted-foreground" />;
      case 'rain':
      case 'drizzle':
        return <CloudRain className="h-12 w-12 text-primary" />;
      case 'snow':
        return <CloudSnow className="h-12 w-12 text-primary/70" />;
      default:
        return <Cloud className="h-12 w-12 text-muted-foreground" />;
    }
  };

  // 로딩 상태
  if (loading && !weather) {
    return (
      <div className="flex h-full items-center justify-center bg-background rounded-lg border p-6">
        <div className="flex flex-col items-center gap-3">
          <RefreshCw className="h-8 w-8 animate-spin text-primary" />
          <div className="text-center">
            <p className="text-sm font-semibold text-foreground mb-1">실제 기상청 API 연결 중...</p>
            <p className="text-xs text-muted-foreground">실시간 관측 데이터를 가져오고 있습니다</p>
          </div>
        </div>
      </div>
    );
  }

  // 에러 상태
  if (error || !weather) {
    const isTestMode = error?.includes('API 키가 설정되지 않았습니다');
    return (
      <div className="flex h-full flex-col items-center justify-center rounded-lg border p-6 bg-background">
        <Cloud className="h-12 w-12 text-muted-foreground mb-2" />
        <div className="text-center mb-3">
          <p className="text-sm font-semibold text-foreground mb-1">
            {isTestMode ? '⚠️ 테스트 모드' : '❌ 연결 실패'}
          </p>
          <p className="text-xs text-foreground">
            {error || '날씨 정보를 불러올 수 없습니다.'}
          </p>
          {isTestMode && (
            <p className="text-xs text-warning mt-2">
              임시 데이터가 표시됩니다
            </p>
          )}
        </div>
        <Button
          variant="outline"
          size="sm"
          onClick={fetchWeather}
          className="gap-1"
        >
          <RefreshCw className="h-3 w-3" />
          다시 시도
        </Button>
      </div>
    );
  }

  // 날씨 아이콘 렌더링 헬퍼
  const renderWeatherIcon = (weatherMain: string, size: "sm" | "md" = "sm") => {
    const iconClass = size === "sm" ? "h-5 w-5" : "h-8 w-8";
    switch (weatherMain.toLowerCase()) {
      case 'clear':
        return <Sun className={`${iconClass} text-warning`} />;
      case 'clouds':
        return <Cloud className={`${iconClass} text-muted-foreground`} />;
      case 'rain':
      case 'drizzle':
        return <CloudRain className={`${iconClass} text-primary`} />;
      case 'snow':
        return <CloudSnow className={`${iconClass} text-primary/70`} />;
      default:
        return <Cloud className={`${iconClass} text-muted-foreground`} />;
    }
  };

  // 컴팩트 모드 렌더링
  if (isCompact) {
    return (
      <div ref={containerRef} className="h-full bg-background rounded-lg border p-3 flex flex-col">
        {/* 컴팩트 헤더 - 도시명, 온도, 날씨 아이콘 한 줄에 표시 */}
        <div className="flex items-center justify-between gap-2 flex-1">
          <div className="flex items-center gap-2 min-w-0 flex-1">
            {renderWeatherIcon(weather.weatherMain, "md")}
            <div className="min-w-0 flex-1">
              <div className="flex items-center gap-2">
                <span className="text-xl font-bold text-foreground">
                  {weather.temperature}°C
                </span>
                <span className="text-xs text-muted-foreground capitalize truncate">
                  {weather.weatherDescription}
                </span>
              </div>
              <Popover open={open} onOpenChange={setOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="ghost"
                    role="combobox"
                    aria-expanded={open}
                    className="justify-between text-xs text-muted-foreground hover:bg-muted/80 h-auto py-0 px-1"
                  >
                    {cities.find((city) => city.value === selectedCity)?.label || '도시 선택'}
                    <ChevronsUpDown className="ml-1 h-3 w-3 shrink-0 opacity-50" />
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-[200px] p-0" align="start">
                  <Command>
                    <CommandInput placeholder="도시 검색..." />
                    <CommandList>
                      <CommandEmpty>도시를 찾을 수 없습니다.</CommandEmpty>
                      <CommandGroup>
                        {cities.map((city) => (
                          <CommandItem
                            key={city.value}
                            value={city.value}
                            onSelect={(currentValue) => {
                              handleCityChange(currentValue === selectedCity ? selectedCity : currentValue);
                              setOpen(false);
                            }}
                          >
                            <Check
                              className={cn(
                                'mr-2 h-4 w-4',
                                selectedCity === city.value ? 'opacity-100' : 'opacity-0'
                              )}
                            />
                            {city.label}
                          </CommandItem>
                        ))}
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
            </div>
          </div>
          <Button
            variant="ghost"
            size="sm"
            onClick={fetchWeather}
            disabled={loading}
            className="h-7 w-7 p-0 flex-shrink-0"
          >
            <RefreshCw className={`h-3.5 w-3.5 ${loading ? 'animate-spin' : ''}`} />
          </Button>
        </div>
      </div>
    );
  }

  // 일반 모드 렌더링
  return (
    <div ref={containerRef} className="h-full bg-background rounded-lg border p-4">
      {/* 헤더 */}
      <div className="flex items-center justify-between mb-3">
        <div className="flex-1">
          <h3 className="text-lg font-semibold text-foreground mb-1">{element?.customTitle || "날씨"}</h3>
          <div className="flex items-center gap-2 mb-1">
            <Popover open={open} onOpenChange={setOpen}>
              <PopoverTrigger asChild>
                <Button
                  variant="ghost"
                  role="combobox"
                  aria-expanded={open}
                  className="justify-between text-sm text-foreground hover:bg-muted/80 h-auto py-0.5 px-2"
                >
                  {cities.find((city) => city.value === selectedCity)?.label || '도시 선택'}
                  <ChevronsUpDown className="ml-2 h-3.5 w-3.5 shrink-0 opacity-50" />
                </Button>
              </PopoverTrigger>
              <PopoverContent className="w-[200px] p-0" align="start">
                <Command>
                  <CommandInput placeholder="도시 검색..." />
                  <CommandList>
                    <CommandEmpty>도시를 찾을 수 없습니다.</CommandEmpty>
                    <CommandGroup>
                      {cities.map((city) => (
                        <CommandItem
                          key={city.value}
                          value={city.value}
                          onSelect={(currentValue) => {
                            handleCityChange(currentValue === selectedCity ? selectedCity : currentValue);
                            setOpen(false);
                          }}
                        >
                          <Check
                            className={cn(
                              'mr-2 h-4 w-4',
                              selectedCity === city.value ? 'opacity-100' : 'opacity-0'
                            )}
                          />
                          {city.label}
                        </CommandItem>
                      ))}
                    </CommandGroup>
                  </CommandList>
                </Command>
              </PopoverContent>
            </Popover>
          </div>
          <p className="text-xs text-muted-foreground pl-2">
            {lastUpdated
              ? `업데이트: ${lastUpdated.toLocaleTimeString('ko-KR', {
                  hour: '2-digit',
                  minute: '2-digit',
                })}`
              : ''}
          </p>
        </div>
        <Popover open={settingsOpen} onOpenChange={setSettingsOpen}>
          <PopoverTrigger asChild>
            <Button
              variant="ghost"
              size="sm"
              className="h-8 w-8 p-0"
            >
              <Settings className="h-4 w-4" />
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-[200px] p-3" align="end">
            <div className="space-y-2">
              <h4 className="text-sm font-semibold text-foreground mb-3">표시 항목</h4>
              {weatherItems.map((item) => {
                const Icon = item.icon;
                return (
                  <button
                    key={item.id}
                    onClick={() => toggleItem(item.id)}
                    className={cn(
                      'w-full flex items-center gap-2 px-2 py-1.5 rounded text-xs transition-colors',
                      selectedItems.includes(item.id)
                        ? 'bg-primary/10 text-primary'
                        : 'text-foreground hover:bg-muted'
                    )}
                  >
                    <Check
                      className={cn(
                        'h-3.5 w-3.5',
                        selectedItems.includes(item.id) ? 'opacity-100' : 'opacity-0'
                      )}
                    />
                    <Icon className="h-3.5 w-3.5" />
                    <span>{item.label}</span>
                  </button>
                );
              })}
            </div>
          </PopoverContent>
        </Popover>
        <Button
          variant="ghost"
          size="sm"
          onClick={fetchWeather}
          disabled={loading}
          className="h-8 w-8 p-0"
        >
          <RefreshCw className={`h-4 w-4 ${loading ? 'animate-spin' : ''}`} />
        </Button>
      </div>

      {/* 반응형 그리드 레이아웃 - 자동 조정 */}
      <div className="grid gap-2" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))' }}>
        {/* 날씨 아이콘 및 온도 */}
        <div className="bg-muted/80 rounded-lg p-3">
          <div className="flex items-center gap-1.5">
            <div className="flex-shrink-0">
              {renderWeatherIcon(weather.weatherMain)}
            </div>
            <div className="min-w-0 flex-1">
              <div className="text-sm font-bold text-foreground leading-tight truncate">
                {weather.temperature}°C
              </div>
              <p className="text-xs text-muted-foreground capitalize leading-tight truncate">
                {weather.weatherDescription}
              </p>
            </div>
          </div>
        </div>

        {/* 기온 - 선택 가능 */}
        {selectedItems.includes('temperature') && (
          <div className="flex items-center gap-1.5 bg-muted/80 rounded-lg p-3">
            <Sun className="h-3.5 w-3.5 text-warning flex-shrink-0" />
            <div className="min-w-0 flex-1">
              <p className="text-xs text-muted-foreground leading-tight truncate">기온</p>
              <p className="text-sm font-semibold text-foreground leading-tight truncate">
                {weather.temperature}°C
              </p>
            </div>
          </div>
        )}

        {/* 체감 온도 */}
        {selectedItems.includes('feelsLike') && (
          <div className="flex items-center gap-1.5 bg-muted/80 rounded-lg p-3">
            <Wind className="h-3.5 w-3.5 text-primary flex-shrink-0" />
            <div className="min-w-0 flex-1">
              <p className="text-xs text-muted-foreground leading-tight truncate">체감온도</p>
              <p className="text-sm font-semibold text-foreground leading-tight truncate">
                {weather.feelsLike}°C
              </p>
            </div>
          </div>
        )}

        {/* 습도 */}
        {selectedItems.includes('humidity') && (
          <div className="flex items-center gap-1.5 bg-muted/80 rounded-lg p-3">
            <Droplets className="h-3.5 w-3.5 text-primary flex-shrink-0" />
            <div className="min-w-0 flex-1">
              <p className="text-xs text-muted-foreground leading-tight truncate">습도</p>
              <p className="text-sm font-semibold text-foreground leading-tight truncate">
                {weather.humidity}%
              </p>
            </div>
          </div>
        )}

        {/* 풍속 */}
        {selectedItems.includes('windSpeed') && (
          <div className="flex items-center gap-1.5 bg-muted/80 rounded-lg p-3">
            <Wind className="h-3.5 w-3.5 text-success flex-shrink-0" />
            <div className="min-w-0 flex-1">
              <p className="text-xs text-muted-foreground leading-tight truncate">풍속</p>
              <p className="text-sm font-semibold text-foreground leading-tight truncate">
                {weather.windSpeed} m/s
              </p>
            </div>
          </div>
        )}

        {/* 기압 */}
        {selectedItems.includes('pressure') && (
          <div className="flex items-center gap-1.5 bg-muted/80 rounded-lg p-3">
            <Gauge className="h-3.5 w-3.5 text-primary flex-shrink-0" />
            <div className="min-w-0 flex-1">
              <p className="text-xs text-muted-foreground leading-tight truncate">기압</p>
              <p className="text-sm font-semibold text-foreground leading-tight truncate">
                {weather.pressure} hPa
              </p>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

