import React, { useMemo, useState } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import {
  addMonths,
  buildMonthCells,
  formatISODate,
  formatMonthTitle,
  isDateInRange,
  isRangeEnd,
  isRangeStart,
  normalizeDateRange,
  parseISODate,
  sameCalendarDay,
  startOfMonth,
  WEEKDAY_LABELS,
} from '../utils/dateRangeCalendar';
import type { DateRangeValue } from '../utils/dateRangeCalendar';

interface DateRangeCalendarPanelProps {
  startDate: string;
  endDate: string;
  onChange: (range: DateRangeValue) => void;
  onComplete?: () => void;
}

function MonthPanel({
  monthDate,
  start,
  end,
  hover,
  onDayClick,
  onDayHover,
}: {
  monthDate: Date;
  start: Date | null;
  end: Date | null;
  hover: Date | null;
  onDayClick: (date: Date) => void;
  onDayHover: (date: Date | null) => void;
}) {
  const cells = useMemo(() => buildMonthCells(monthDate), [monthDate]);
  const today = useMemo(() => new Date(), []);

  return (
    <div className="vm-date-range-month">
      <div className="vm-date-range-month-title">{formatMonthTitle(monthDate)}</div>
      <div className="vm-date-range-weekdays" aria-hidden>
        {WEEKDAY_LABELS.map((label) => (
          <span key={label} className="vm-date-range-weekday">{label}</span>
        ))}
      </div>
      <div className="vm-date-range-days" role="grid">
        {cells.map((cell) => {
          const key = formatISODate(cell.date);
          const selectedStart = isRangeStart(cell.date, start, end, hover);
          const selectedEnd = isRangeEnd(cell.date, start, end, hover);
          const inRange = isDateInRange(cell.date, start, end, hover);
          const isToday = sameCalendarDay(cell.date, today);
          const classNames = [
            'vm-date-range-day',
            !cell.inMonth ? 'is-outside' : '',
            inRange ? 'is-in-range' : '',
            selectedStart ? 'is-range-start' : '',
            selectedEnd ? 'is-range-end' : '',
            isToday ? 'is-today' : '',
          ].filter(Boolean).join(' ');

          return (
            <button
              key={key}
              type="button"
              role="gridcell"
              className={classNames}
              aria-label={key}
              aria-pressed={selectedStart || selectedEnd}
              onMouseEnter={() => onDayHover(cell.date)}
              onMouseLeave={() => onDayHover(null)}
              onClick={() => onDayClick(cell.date)}
            >
              <span>{cell.date.getDate()}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

export function DateRangeCalendarPanel({
  startDate,
  endDate,
  onChange,
  onComplete,
}: DateRangeCalendarPanelProps) {
  const start = parseISODate(startDate);
  const end = parseISODate(endDate);
  const [viewMonth, setViewMonth] = useState(() => startOfMonth(start || end || new Date()));
  const [hoverDate, setHoverDate] = useState<Date | null>(null);

  const leftMonth = viewMonth;
  const rightMonth = addMonths(viewMonth, 1);

  const handleDayClick = (date: Date) => {
    const iso = formatISODate(date);
    if (!startDate || (startDate && endDate)) {
      onChange({ startDate: iso, endDate: '' });
      return;
    }

    const next = normalizeDateRange(startDate, iso);
    onChange(next);
    onComplete?.();
  };

  return (
    <div className="vm-date-range-calendars">
      <div className="vm-date-range-calendars-nav">
        <button
          type="button"
          className="vm-date-range-nav-btn"
          aria-label="上一月"
          onClick={() => setViewMonth((prev) => addMonths(prev, -1))}
        >
          <ChevronLeft size={16} aria-hidden />
        </button>
        <button
          type="button"
          className="vm-date-range-nav-btn"
          aria-label="下一月"
          onClick={() => setViewMonth((prev) => addMonths(prev, 1))}
        >
          <ChevronRight size={16} aria-hidden />
        </button>
      </div>
      <div className="vm-date-range-calendars-body">
        <MonthPanel
          monthDate={leftMonth}
          start={start}
          end={end}
          hover={hoverDate}
          onDayClick={handleDayClick}
          onDayHover={setHoverDate}
        />
        <MonthPanel
          monthDate={rightMonth}
          start={start}
          end={end}
          hover={hoverDate}
          onDayClick={handleDayClick}
          onDayHover={setHoverDate}
        />
      </div>
    </div>
  );
}
