"use client";

import * as React from "react";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { DayPicker } from "react-day-picker";
import { format, getDay } from "date-fns";

import { ko } from "date-fns/locale";
import { cn } from "./utils";
import { buttonVariants } from "./button";
import { isHoliday, isTaxDeadline } from "@/constants/calendarEvents";

// 토요일 체크 함수 (react-day-picker modifier용)
const saturdayMatcher = (date: Date) => {
    const dateStr = format(date, "yyyy-MM-dd");
    // 토요일이면서 공휴일이 아닌 경우만
    return getDay(date) === 6 && !isHoliday(dateStr);
};

// 일요일 체크 함수 (react-day-picker modifier용)
const sundayMatcher = (date: Date) => {
    return getDay(date) === 0;
};

// 공휴일 체크 함수 (react-day-picker modifier용)
const holidayMatcher = (date: Date) => {
    const dateStr = format(date, "yyyy-MM-dd");
    return isHoliday(dateStr);
};

// 세금신고일 체크 함수 (react-day-picker modifier용)
const taxDeadlineMatcher = (date: Date) => {
    const dateStr = format(date, "yyyy-MM-dd");
    return isTaxDeadline(dateStr);
};

function Calendar({
                      className,
                      classNames,
                      showOutsideDays = true,
                      modifiers,
                      modifiersClassNames,
                      ...props
                  }: React.ComponentProps<typeof DayPicker>) {
    // Hydration 불일치 방지: 클라이언트에서만 렌더링
    const [mounted, setMounted] = React.useState(false);

    React.useEffect(() => {
        setMounted(true);
    }, []);

    if (!mounted) {
        // SSR에서는 빈 컨테이너 렌더링 (레이아웃 시프트 방지)
        return (
            <div className={cn("p-0 w-full min-h-[300px]", className)} />
        );
    }

    // 공휴일/토요일/일요일 modifiers 병합
    const mergedModifiers = {
        saturday: saturdayMatcher,
        sunday: sundayMatcher,
        holiday: holidayMatcher,
        taxDeadline: taxDeadlineMatcher,
        ...modifiers,
    };

    const mergedModifiersClassNames = {
        saturday: "text-blue-500 font-semibold",
        sunday: "text-red-500 font-semibold",
        holiday: "text-red-500 font-semibold",
        taxDeadline: "text-green-600 font-semibold",
        ...modifiersClassNames,
    };

    return (
        <DayPicker
            modifiers={mergedModifiers}
            modifiersClassNames={mergedModifiersClassNames}
            showOutsideDays={showOutsideDays}
            className={cn("p-0 w-full", className)}
            classNames={{
                months: "flex flex-col sm:flex-row gap-0 w-full h-full",
                month: "flex flex-col gap-2 w-full h-full",
                month_caption: "flex justify-center pt-0 relative items-center w-full mb-2",
                caption_label: "text-lg md:text-xl font-bold",
                nav: "flex items-center gap-2",
                button_previous: cn(
                    buttonVariants({ variant: "outline" }),
                    "size-8 md:size-9 bg-transparent p-0 opacity-60 hover:opacity-100 hover:bg-primary/10 absolute left-0",
                ),
                button_next: cn(
                    buttonVariants({ variant: "outline" }),
                    "size-8 md:size-9 bg-transparent p-0 opacity-60 hover:opacity-100 hover:bg-primary/10 absolute right-0",
                ),
                month_grid: "w-full h-full border-collapse flex flex-col mt-2",
                weekdays: "flex w-full mb-1",
                weekday:
                    "text-muted-foreground rounded-md flex-1 font-semibold text-sm md:text-base",
                week: "flex w-full mt-0 flex-1",
                day: cn(
                    "relative p-0 text-center text-sm focus-within:relative focus-within:z-20 flex-1",
                    props.mode === "range"
                        ? "[&:has(>.range-end)]:rounded-r-md [&:has(>.range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md"
                        : "",
                ),
                day_button: cn(
                    "w-full h-full p-0 font-normal aria-selected:opacity-100",
                ),
                range_start:
                    "range-start aria-selected:bg-primary aria-selected:text-primary-foreground",
                range_end:
                    "range-end aria-selected:bg-primary aria-selected:text-primary-foreground",
                selected:
                    "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
                today: "bg-accent text-accent-foreground",
                outside:
                    "outside text-muted-foreground/40 aria-selected:text-muted-foreground",
                disabled: "text-muted-foreground opacity-30",
                range_middle:
                    "aria-selected:bg-accent aria-selected:text-accent-foreground",
                hidden: "invisible",
                ...classNames,
            }}
            components={{
                Chevron: ({ orientation, ...props }) => {
                    const Icon = orientation === "left" ? ChevronLeft : ChevronRight;
                    return <Icon className="size-5" {...props} />;
                },
            }}
            locale={ko}
            {...props}
        />
    );
}

export { Calendar };
