"use client";

import React, { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { CalendarIcon, ChevronLeft, ChevronRight } from "lucide-react";
import {
  format,
  addMonths,
  subMonths,
  startOfMonth,
  endOfMonth,
  eachDayOfInterval,
  isSameMonth,
  isSameDay,
  isToday,
} from "date-fns";
import { ko } from "date-fns/locale";
import { cn } from "@/lib/utils";

interface DateRangeValue {
  from?: Date;
  to?: Date;
}

interface ModernDatePickerProps {
  label: string;
  value: DateRangeValue;
  onChange: (value: DateRangeValue) => void;
  includeTime?: boolean;
}

export const ModernDatePicker: React.FC<ModernDatePickerProps> = ({ label, value, onChange, includeTime = false }) => {
  const [isOpen, setIsOpen] = useState(false);
  const [currentMonth, setCurrentMonth] = useState(new Date());
  const [selectingType, setSelectingType] = useState<"from" | "to">("from");
  const [viewMode, setViewMode] = useState<"calendar" | "year" | "month">("calendar");
  const [yearRangeStart, setYearRangeStart] = useState(() => Math.floor(new Date().getFullYear() / 12) * 12);
  
  // 로컬 임시 상태 (확인 버튼 누르기 전까지 임시 저장)
  const [tempValue, setTempValue] = useState<DateRangeValue>(value || {});

  // 팝오버가 열릴 때 현재 값으로 초기화
  useEffect(() => {
    if (isOpen) {
      setTempValue(value || {});
      setSelectingType("from");
      setViewMode("calendar");
    }
  }, [isOpen, value]);

  const formatDate = (date: Date | undefined) => {
    if (!date) return "";
    if (includeTime) {
      return format(date, "yyyy-MM-dd HH:mm", { locale: ko });
    }
    return format(date, "yyyy-MM-dd", { locale: ko });
  };

  const displayValue = () => {
    if (value?.from && value?.to) {
      return `${formatDate(value.from)} ~ ${formatDate(value.to)}`;
    }
    if (value?.from) {
      return `${formatDate(value.from)} ~`;
    }
    if (value?.to) {
      return `~ ${formatDate(value.to)}`;
    }
    return "";
  };

  const handleDateClick = (date: Date) => {
    // 로컬 상태만 업데이트 (onChange 호출 안 함)
    if (selectingType === "from") {
      setTempValue({ ...tempValue, from: date });
      setSelectingType("to");
    } else {
      setTempValue({ ...tempValue, to: date });
      setSelectingType("from");
    }
  };

  const handleClear = () => {
    setTempValue({});
    setSelectingType("from");
  };

  const handleConfirm = () => {
    // 날짜 순서 자동 정렬
    let finalValue = { ...tempValue };
    
    if (finalValue.from && finalValue.to) {
      // from이 to보다 나중이면 swap
      if (finalValue.from > finalValue.to) {
        const temp = finalValue.from;
        finalValue.from = finalValue.to;
        finalValue.to = temp;
      }
    }
    
    // 확인 버튼을 눌렀을 때만 onChange 호출
    onChange(finalValue);
    setIsOpen(false);
    setSelectingType("from");
  };

  const handleCancel = () => {
    // 취소 시 임시 값 버리고 팝오버 닫기
    setTempValue(value || {});
    setIsOpen(false);
    setSelectingType("from");
  };

  // 빠른 기간 선택 함수들 (즉시 적용 + 팝오버 닫기)
  const setToday = () => {
    const today = new Date();
    const newValue = { from: today, to: today };
    setTempValue(newValue);
    onChange(newValue);
    setIsOpen(false);
    setSelectingType("from");
  };

  const setThisWeek = () => {
    const today = new Date();
    const dayOfWeek = today.getDay();
    const diff = dayOfWeek === 0 ? -6 : 1 - dayOfWeek; // 월요일 기준
    const monday = new Date(today);
    monday.setDate(today.getDate() + diff);
    const sunday = new Date(monday);
    sunday.setDate(monday.getDate() + 6);
    const newValue = { from: monday, to: sunday };
    setTempValue(newValue);
    onChange(newValue);
    setIsOpen(false);
    setSelectingType("from");
  };

  const setThisMonth = () => {
    const today = new Date();
    const firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
    const lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);
    const newValue = { from: firstDay, to: lastDay };
    setTempValue(newValue);
    onChange(newValue);
    setIsOpen(false);
    setSelectingType("from");
  };

  const setLast7Days = () => {
    const today = new Date();
    const sevenDaysAgo = new Date(today);
    sevenDaysAgo.setDate(today.getDate() - 6);
    const newValue = { from: sevenDaysAgo, to: today };
    setTempValue(newValue);
    onChange(newValue);
    setIsOpen(false);
    setSelectingType("from");
  };

  const setLast30Days = () => {
    const today = new Date();
    const thirtyDaysAgo = new Date(today);
    thirtyDaysAgo.setDate(today.getDate() - 29);
    const newValue = { from: thirtyDaysAgo, to: today };
    setTempValue(newValue);
    onChange(newValue);
    setIsOpen(false);
    setSelectingType("from");
  };

  const monthStart = startOfMonth(currentMonth);
  const monthEnd = endOfMonth(currentMonth);
  const days = eachDayOfInterval({ start: monthStart, end: monthEnd });

  // 달력 시작을 월요일로 맞추기 위해 앞의 빈 칸들 계산
  const startDate = new Date(monthStart);
  const dayOfWeek = startDate.getDay();
  const paddingDays = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // 일요일(0)이면 6개, 나머지는 -1

  const allDays = [...Array(paddingDays).fill(null), ...days];

  const isInRange = (date: Date) => {
    if (!tempValue.from || !tempValue.to) return false;
    return date >= tempValue.from && date <= tempValue.to;
  };

  const isRangeStart = (date: Date) => {
    return tempValue.from && isSameDay(date, tempValue.from);
  };

  const isRangeEnd = (date: Date) => {
    return tempValue.to && isSameDay(date, tempValue.to);
  };

  return (
    <Popover open={isOpen} onOpenChange={setIsOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          className={cn(
            "w-full justify-start text-left font-normal",
            !value?.from && !value?.to && "text-muted-foreground",
          )}
        >
          <CalendarIcon className="mr-2 h-4 w-4" />
          {displayValue() || `${label} 기간 선택...`}
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-auto p-0" align="start">
        <div className="p-4">
          {/* 헤더 */}
          <div className="mb-4 flex items-center justify-between">
            <h3 className="text-sm font-medium">기간 선택</h3>
            <div className="text-muted-foreground text-xs">
              {selectingType === "from" ? "시작일을 선택하세요" : "종료일을 선택하세요"}
            </div>
          </div>

          {/* 빠른 선택 버튼 */}
          <div className="mb-4 flex flex-wrap gap-2">
            <Button variant="outline" size="sm" className="h-7 text-xs" onClick={setToday}>
              오늘
            </Button>
            <Button variant="outline" size="sm" className="h-7 text-xs" onClick={setThisWeek}>
              이번 주
            </Button>
            <Button variant="outline" size="sm" className="h-7 text-xs" onClick={setThisMonth}>
              이번 달
            </Button>
            <Button variant="outline" size="sm" className="h-7 text-xs" onClick={setLast7Days}>
              최근 7일
            </Button>
            <Button variant="outline" size="sm" className="h-7 text-xs" onClick={setLast30Days}>
              최근 30일
            </Button>
          </div>

          {viewMode === "year" ? (
            <>
              {/* 년도 선택 뷰 */}
              <div className="mb-4 flex items-center justify-between">
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0" onClick={() => setYearRangeStart(yearRangeStart - 12)}>
                  <ChevronLeft className="h-4 w-4" />
                </Button>
                <div className="text-sm font-medium">
                  {yearRangeStart} - {yearRangeStart + 11}
                </div>
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0" onClick={() => setYearRangeStart(yearRangeStart + 12)}>
                  <ChevronRight className="h-4 w-4" />
                </Button>
              </div>
              <div className="mb-4 grid grid-cols-4 gap-2">
                {Array.from({ length: 12 }, (_, i) => yearRangeStart + i).map((year) => (
                  <Button
                    key={year}
                    variant="ghost"
                    size="sm"
                    className={cn(
                      "h-9 text-xs",
                      year === currentMonth.getFullYear() && "bg-primary text-primary-foreground hover:bg-primary",
                      year === new Date().getFullYear() && year !== currentMonth.getFullYear() && "border-primary border",
                    )}
                    onClick={() => {
                      setCurrentMonth(new Date(year, currentMonth.getMonth(), 1));
                      setViewMode("month");
                    }}
                  >
                    {year}
                  </Button>
                ))}
              </div>
            </>
          ) : viewMode === "month" ? (
            <>
              {/* 월 선택 뷰 */}
              <div className="mb-4 flex items-center justify-between">
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0" onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear() - 1, currentMonth.getMonth(), 1))}>
                  <ChevronLeft className="h-4 w-4" />
                </Button>
                <button
                  type="button"
                  className="hover:bg-accent rounded-md px-2 py-1 text-sm font-medium transition-colors"
                  onClick={() => {
                    setYearRangeStart(Math.floor(currentMonth.getFullYear() / 12) * 12);
                    setViewMode("year");
                  }}
                >
                  {currentMonth.getFullYear()}년
                </button>
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0" onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear() + 1, currentMonth.getMonth(), 1))}>
                  <ChevronRight className="h-4 w-4" />
                </Button>
              </div>
              <div className="mb-4 grid grid-cols-4 gap-2">
                {Array.from({ length: 12 }, (_, i) => i).map((month) => (
                  <Button
                    key={month}
                    variant="ghost"
                    size="sm"
                    className={cn(
                      "h-9 text-xs",
                      month === currentMonth.getMonth() && "bg-primary text-primary-foreground hover:bg-primary",
                      month === new Date().getMonth() && currentMonth.getFullYear() === new Date().getFullYear() && month !== currentMonth.getMonth() && "border-primary border",
                    )}
                    onClick={() => {
                      setCurrentMonth(new Date(currentMonth.getFullYear(), month, 1));
                      setViewMode("calendar");
                    }}
                  >
                    {month + 1}월
                  </Button>
                ))}
              </div>
            </>
          ) : (
            <>
              {/* 월 네비게이션 */}
              <div className="mb-4 flex items-center justify-between">
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0" onClick={() => setCurrentMonth(subMonths(currentMonth, 1))}>
                  <ChevronLeft className="h-4 w-4" />
                </Button>
                <button
                  type="button"
                  className="hover:bg-accent rounded-md px-2 py-1 text-sm font-medium transition-colors"
                  onClick={() => {
                    setYearRangeStart(Math.floor(currentMonth.getFullYear() / 12) * 12);
                    setViewMode("year");
                  }}
                >
                  {format(currentMonth, "yyyy년 MM월", { locale: ko })}
                </button>
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0" onClick={() => setCurrentMonth(addMonths(currentMonth, 1))}>
                  <ChevronRight className="h-4 w-4" />
                </Button>
              </div>

              {/* 요일 헤더 */}
              <div className="mb-2 grid grid-cols-7 gap-1">
                {["월", "화", "수", "목", "금", "토", "일"].map((day) => (
                  <div key={day} className="text-muted-foreground p-2 text-center text-xs font-medium">
                    {day}
                  </div>
                ))}
              </div>

              {/* 날짜 그리드 */}
              <div className="mb-4 grid grid-cols-7 gap-1">
                {allDays.map((date, index) => {
                  if (!date) {
                    return <div key={index} className="p-2" />;
                  }

                  const isCurrentMonth = isSameMonth(date, currentMonth);
                  const isSelected = isRangeStart(date) || isRangeEnd(date);
                  const isInRangeDate = isInRange(date);
                  const isTodayDate = isToday(date);

                  return (
                    <Button
                      key={date.toISOString()}
                      variant="ghost"
                      size="sm"
                      className={cn(
                        "h-8 w-8 p-0 text-xs",
                        !isCurrentMonth && "text-muted-foreground opacity-50",
                        isSelected && "bg-primary text-primary-foreground hover:bg-primary",
                        isInRangeDate && !isSelected && "bg-muted",
                        isTodayDate && !isSelected && "border-primary border",
                        selectingType === "from" && "hover:bg-primary/20",
                        selectingType === "to" && "hover:bg-secondary/20",
                      )}
                      onClick={() => handleDateClick(date)}
                      disabled={!isCurrentMonth}
                    >
                      {format(date, "d")}
                    </Button>
                  );
                })}
              </div>
            </>
          )}

          {/* 선택된 범위 표시 */}
          {(tempValue.from || tempValue.to) && (
            <div className="bg-muted mb-4 rounded-md p-2">
              <div className="text-muted-foreground mb-1 text-xs">선택된 기간</div>
              <div className="text-sm">
                {tempValue.from && <span className="font-medium">시작: {formatDate(tempValue.from)}</span>}
                {tempValue.from && tempValue.to && <span className="mx-2">~</span>}
                {tempValue.to && <span className="font-medium">종료: {formatDate(tempValue.to)}</span>}
              </div>
            </div>
          )}

          {/* 액션 버튼 */}
          <div className="flex justify-between">
            <Button variant="outline" size="sm" onClick={handleClear}>
              초기화
            </Button>
            <div className="space-x-2">
              <Button variant="outline" size="sm" onClick={handleCancel}>
                취소
              </Button>
              <Button size="sm" onClick={handleConfirm}>
                확인
              </Button>
            </div>
          </div>
        </div>
      </PopoverContent>
    </Popover>
  );
};
