'use client';

import { useState, useCallback, useEffect } from 'react';
import { cn } from '@/components/ui/utils';
import { CalendarHeader } from './CalendarHeader';
import { DayTimeView } from './DayTimeView';
import { MonthView } from './MonthView';
import { WeekView } from './WeekView';
import { WeekTimeView } from './WeekTimeView';
import type { ScheduleCalendarProps, CalendarView } from './types';
import { getNextMonth, getPrevMonth, getNextDay, getPrevDay, getNextWeek, getPrevWeek } from './utils';
import { useCalendarScheduleStore } from '@/stores/useCalendarScheduleStore';

/**
 * 스케줄 달력 공통 컴포넌트
 *
 * 주/월 뷰 전환, 일정 바 표시, 날짜별 뱃지 등을 지원하는 재사용 가능한 달력
 *
 * @example
 * ```tsx
 * <ScheduleCalendar
 *   events={[
 *     { id: '1', title: '김담당 - 현장A / ORD-001', startDate: '2025-12-01', endDate: '2025-12-05', color: 'blue' },
 *   ]}
 *   badges={[
 *     { date: '2025-12-01', count: 3, color: 'red' },
 *   ]}
 *   onDateClick={(date) => console.log('날짜 클릭:', date)}
 *   onEventClick={(event) => console.log('이벤트 클릭:', event)}
 *   filterSlot={<Select>...</Select>}
 * />
 * ```
 */
export function ScheduleCalendar({
  events = [],
  badges = [],
  currentDate: controlledDate,
  view: controlledView,
  selectedDate: controlledSelectedDate,
  onDateClick,
  onEventClick,
  onMonthChange,
  onViewChange,
  titleSlot,
  filterSlot,
  maxEventsPerDay = 5,
  weekStartsOn = 0,
  isLoading = false,
  className,
  availableViews,
  timeRange,
  hideNavigation,
}: ScheduleCalendarProps) {
  // 내부 상태 (controlled/uncontrolled 지원)
  const [internalDate, setInternalDate] = useState(() => new Date());
  const [internalView, setInternalView] = useState<CalendarView>('month');
  const [internalSelectedDate, setInternalSelectedDate] = useState<Date | null>(null);

  // 현재 사용할 값 결정
  const currentDate = controlledDate ?? internalDate;
  const view = controlledView ?? internalView;
  const selectedDate = controlledSelectedDate !== undefined ? controlledSelectedDate : internalSelectedDate;

  // Hydration 불일치 방지
  const [mounted, setMounted] = useState(false);
  useEffect(() => {
    setMounted(true);
  }, []);

  // 현재 표시 중인 연도의 공휴일/일정 데이터를 스토어에 로드
  useEffect(() => {
    const year = currentDate.getFullYear();
    useCalendarScheduleStore.getState().fetchSchedules(year);
  }, [currentDate]);

  // 이전 (뷰에 따라 일/주/월 단위)
  const handlePrevMonth = useCallback(() => {
    let newDate: Date;
    if (view === 'day-time') {
      newDate = getPrevDay(currentDate);
    } else if (view === 'week-time' || view === 'week') {
      newDate = getPrevWeek(currentDate);
    } else {
      newDate = getPrevMonth(currentDate);
    }
    if (controlledDate === undefined) {
      setInternalDate(newDate);
    }
    onMonthChange?.(newDate);
  }, [currentDate, view, controlledDate, onMonthChange]);

  // 다음 (뷰에 따라 일/주/월 단위)
  const handleNextMonth = useCallback(() => {
    let newDate: Date;
    if (view === 'day-time') {
      newDate = getNextDay(currentDate);
    } else if (view === 'week-time' || view === 'week') {
      newDate = getNextWeek(currentDate);
    } else {
      newDate = getNextMonth(currentDate);
    }
    if (controlledDate === undefined) {
      setInternalDate(newDate);
    }
    onMonthChange?.(newDate);
  }, [currentDate, view, controlledDate, onMonthChange]);

  // 뷰 변경
  const handleViewChange = useCallback((newView: CalendarView) => {
    if (controlledView === undefined) {
      setInternalView(newView);
    }
    onViewChange?.(newView);
  }, [controlledView, onViewChange]);

  // 날짜 클릭
  const handleDateClick = useCallback((date: Date) => {
    if (controlledSelectedDate === undefined) {
      setInternalSelectedDate(date);
    }
    onDateClick?.(date);
  }, [controlledSelectedDate, onDateClick]);

  // 이벤트 클릭
  const handleEventClick = useCallback((event: import('./types').ScheduleEvent) => {
    onEventClick?.(event);
  }, [onEventClick]);

  // SSR에서는 빈 컨테이너 렌더링
  if (!mounted) {
    return (
      <div className={cn('min-h-[400px] rounded-md border p-4', className)} />
    );
  }

  return (
    <div className={cn('rounded-md border p-4 bg-background', className)}>
      {/* 헤더 */}
      <CalendarHeader
        currentDate={currentDate}
        view={view}
        onPrevMonth={handlePrevMonth}
        onNextMonth={handleNextMonth}
        onViewChange={handleViewChange}
        titleSlot={titleSlot}
        filterSlot={filterSlot}
        availableViews={availableViews}
        hideNavigation={hideNavigation}
      />

      {/* 본문 */}
      <div className="mt-4">
        {isLoading ? (
          <div className="flex items-center justify-center min-h-[300px]">
            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
          </div>
        ) : view === 'day-time' ? (
          <DayTimeView
            currentDate={currentDate}
            events={events}
            selectedDate={selectedDate}
            timeRange={timeRange}
            onDateClick={handleDateClick}
            onEventClick={handleEventClick}
          />
        ) : view === 'week-time' ? (
          <WeekTimeView
            currentDate={currentDate}
            events={events}
            selectedDate={selectedDate}
            weekStartsOn={weekStartsOn}
            timeRange={timeRange}
            onDateClick={handleDateClick}
            onEventClick={handleEventClick}
          />
        ) : view === 'month' ? (
          <MonthView
            currentDate={currentDate}
            events={events}
            badges={badges}
            selectedDate={selectedDate}
            maxEventsPerDay={maxEventsPerDay}
            weekStartsOn={weekStartsOn}
            onDateClick={handleDateClick}
            onEventClick={handleEventClick}
          />
        ) : (
          <WeekView
            currentDate={currentDate}
            events={events}
            badges={badges}
            selectedDate={selectedDate}
            maxEventsPerDay={maxEventsPerDay}
            weekStartsOn={weekStartsOn}
            onDateClick={handleDateClick}
            onEventClick={handleEventClick}
          />
        )}
      </div>
    </div>
  );
}
