'use client';

import { useMemo } from 'react';
import { cn } from '@/components/ui/utils';
import { ScheduleBar } from './ScheduleBar';
import { MorePopover } from './MorePopover';
import type { WeekViewProps } from './types';
import {
  getWeekDays,
  checkIsToday,
  isSameDate,
  getEventSegmentsForWeek,
  assignEventRows,
  getEventsForDate,
  getBadgeForDate,
} from './utils';
import { format, getDay } from 'date-fns';
import { ko } from 'date-fns/locale';
import { isHoliday, getHolidayName } from '@/constants/calendarEvents';

/**
 * 주간 뷰 컴포넌트
 * - 주간 그리드 레이아웃 (7 컬럼)
 * - 요일 헤더 (날짜 + 요일)
 * - 날짜 셀 렌더링
 * - 일정 바 렌더링
 */
export function WeekView({
  currentDate,
  events,
  badges,
  selectedDate,
  maxEventsPerDay,
  weekStartsOn,
  onDateClick,
  onEventClick,
}: WeekViewProps) {
  // 주간 날짜 배열
  const weekDays = useMemo(
    () => getWeekDays(currentDate, weekStartsOn),
    [currentDate, weekStartsOn]
  );

  // 이 주에 해당하는 이벤트 세그먼트 계산
  const eventSegments = useMemo(
    () => getEventSegmentsForWeek(events, weekDays, weekStartsOn),
    [events, weekDays, weekStartsOn]
  );

  // 이벤트 행 배치
  const rowAssignments = useMemo(
    () => assignEventRows(eventSegments),
    [eventSegments]
  );

  // 표시할 이벤트 수 계산
  const visibleRows = maxEventsPerDay;

  // 각 날짜별 숨겨진 이벤트 수 계산
  const hiddenEventCounts = useMemo(() => {
    const counts: Map<number, number> = new Map();

    weekDays.forEach((date, colIndex) => {
      const dayEvents = getEventsForDate(events, date);
      const hidden = Math.max(0, dayEvents.length - visibleRows);
      if (hidden > 0) {
        counts.set(colIndex, hidden);
      }
    });

    return counts;
  }, [weekDays, events, visibleRows]);

  // 셀 최소 높이 계산
  const maxRowIndex = Math.max(0, ...Array.from(rowAssignments.values()));
  const rowHeight = Math.max(120, 48 + Math.min(maxRowIndex + 1, visibleRows) * 24 + 24);

  return (
    <div className="flex flex-col">
      {/* 요일 헤더 (날짜 + 요일) */}
      <div className="grid grid-cols-7 mb-1">
        {weekDays.map((date) => {
          const dayOfWeek = getDay(date);
          const isSaturday = dayOfWeek === 6;
          const isSunday = dayOfWeek === 0;
          const dateStr = format(date, 'yyyy-MM-dd');
          const isHolidayDate = isHoliday(dateStr);
          const holidayName = getHolidayName(dateStr);
          const isRedDay = isSunday || isHolidayDate; // 일요일 또는 공휴일 → 빨간색
          const isBlueDay = isSaturday && !isHolidayDate; // 토요일(공휴일 아닌 경우) → 파란색
          const isToday = checkIsToday(date);

          return (
            <div
              key={date.toISOString()}
              className={cn(
                'text-center py-2',
                'flex flex-col items-center'
              )}
              title={holidayName || undefined}
            >
              <span
                className={cn(
                  'text-xs font-semibold text-muted-foreground',
                  isRedDay && 'text-red-400',
                  isBlueDay && 'text-blue-400'
                )}
              >
                {format(date, 'E', { locale: ko })}
              </span>
              <span
                className={cn(
                  'text-lg font-bold mt-0.5',
                  isRedDay && 'text-red-500',
                  isBlueDay && 'text-blue-500',
                  isToday && 'bg-primary text-primary-foreground rounded-full w-8 h-8 flex items-center justify-center'
                )}
              >
                {format(date, 'd')}
              </span>
            </div>
          );
        })}
      </div>

      {/* 주간 본문 */}
      <div
        className="relative grid grid-cols-7 border rounded-md overflow-hidden"
        style={{ minHeight: `${rowHeight}px` }}
      >
        {/* 날짜 셀들 */}
        {weekDays.map((date, colIndex) => {
          const dayOfWeek = getDay(date);
          const _isWeekend = dayOfWeek === 0 || dayOfWeek === 6;
          const badge = getBadgeForDate(badges, date);
          const hiddenCount = hiddenEventCounts.get(colIndex) || 0;
          const dayEvents = getEventsForDate(events, date);

          return (
            <div
              key={date.toISOString()}
              className={cn(
                'relative p-2 border-r last:border-r-0',
                'flex flex-col cursor-pointer transition-colors',
                // 선택된 날짜 - 배경색 + 호버 시 더 진하게
                isSameDate(selectedDate, date)
                  ? 'bg-primary/15 hover:bg-primary/25'
                  : 'hover:bg-muted/30'
              )}
              onClick={() => onDateClick(date)}
            >
              {/* 뱃지 */}
              {badge && badge.count > 0 && (
                <div className="absolute top-1 right-1">
                  <span
                    className={cn(
                      'min-w-[18px] h-[18px] px-1',
                      'flex items-center justify-center',
                      'text-[10px] font-bold rounded-full',
                      'bg-red-500 text-white'
                    )}
                  >
                    {badge.count > 99 ? '99+' : badge.count}
                  </span>
                </div>
              )}

              {/* 더보기 버튼 (하단에 배치) */}
              {hiddenCount > 0 && (
                <div className="absolute bottom-1 left-2">
                  <MorePopover
                    date={date}
                    events={dayEvents}
                    hiddenCount={hiddenCount}
                    onEventClick={onEventClick}
                    onDateClick={onDateClick}
                  />
                </div>
              )}
            </div>
          );
        })}

        {/* 이벤트 바들 (절대 위치) */}
        {eventSegments
          .filter((segment) => {
            const rowIndex = rowAssignments.get(segment.event.id) || 0;
            return rowIndex < visibleRows;
          })
          .map((segment) => {
            const rowIndex = rowAssignments.get(segment.event.id) || 0;

            return (
              <ScheduleBar
                key={`${segment.event.id}-week`}
                event={segment.event}
                isStart={segment.isStart}
                isEnd={segment.isEnd}
                colSpan={segment.colSpan}
                startCol={segment.startCol}
                rowIndex={rowIndex}
                onClick={onEventClick}
              />
            );
          })}
      </div>
    </div>
  );
}
