import { useState, useMemo } from 'react';
import {
  Box,
  Text,
  Group,
  ActionIcon,
} from '@mantine/core';
import {
  IconChevronLeft,
  IconChevronRight,
} from '@tabler/icons-react';
import { Lunar } from 'lunar-javascript';

interface FixedCalendarProps {
  value: Date | null;
  onChange: (date: Date | null) => void;
  minDate?: Date;
  maxDate?: Date;
}

// 获取某月的第一天是星期几
function getFirstDayOfMonth(date: Date): number {
  return new Date(date.getFullYear(), date.getMonth(), 1).getDay();
}

// 获取某月有多少天
function getDaysInMonth(date: Date): number {
  return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
}

// 检查两个日期是否是同一天
function isSameDay(d1: Date | null, d2: Date | null): boolean {
  if (!d1 || !d2) return false;
  return d1.getFullYear() === d2.getFullYear() &&
    d1.getMonth() === d2.getMonth() &&
    d1.getDate() === d2.getDate();
}

// 检查日期是否在范围内
function isDateInRange(date: Date, min?: Date, max?: Date): boolean {
  if (min && date < min) return false;
  if (max && date > max) return false;
  return true;
}

const WEEKDAYS = ['日', '一', '二', '三', '四', '五', '六'];
const MONTH_NAMES = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];

// 获取农历日期简写（用于日历显示）
function getLunarDayText(date: Date): string {
  try {
    const lunar = Lunar.fromYmd(date.getFullYear(), date.getMonth() + 1, date.getDate());
    const day = lunar.getDay();
    // 初一显示为"初一"，其他日期只显示日期数字
    if (day === 1) {
      return lunar.getMonthInChinese();
    }
    // 初一、十五、廿五等特殊日子
    const specialDays: Record<number, string> = {
      1: '初一',
      15: '十五',
      20: '廿',
      25: '廿五',
      30: '卅',
    };
    if (specialDays[day]) {
      return specialDays[day];
    }
    return lunar.getDayInChinese();
  } catch {
    return '';
  }
}

export function FixedCalendar({ value, onChange, minDate, maxDate }: FixedCalendarProps) {
  const [currentMonth, setCurrentMonth] = useState(value || new Date());

  // 生成日历数据（固定6行7列 = 42天）
  const calendarDays = useMemo(() => {
    const year = currentMonth.getFullYear();
    const month = currentMonth.getMonth();

    const firstDay = getFirstDayOfMonth(new Date(year, month, 1));
    const daysInMonth = getDaysInMonth(new Date(year, month, 1));

    const days: Array<{
      date: Date;
      isCurrentMonth: boolean;
      isToday: boolean;
      isSelected: boolean;
      isDisabled: boolean;
      lunarText?: string; // 农历日期简写
    }> = [];

    // 上月剩余的天数
    const prevMonthDays = getDaysInMonth(new Date(year, month - 1, 1));
    for (let i = firstDay - 1; i >= 0; i--) {
      const date = new Date(year, month - 1, prevMonthDays - i);
      const lunarText = getLunarDayText(date);
      days.push({
        date,
        isCurrentMonth: false,
        isToday: isSameDay(date, new Date()),
        isSelected: isSameDay(date, value),
        isDisabled: !isDateInRange(date, minDate, maxDate),
        lunarText,
      });
    }

    // 当月的天数
    for (let i = 1; i <= daysInMonth; i++) {
      const date = new Date(year, month, i);
      const lunarText = getLunarDayText(date);
      days.push({
        date,
        isCurrentMonth: true,
        isToday: isSameDay(date, new Date()),
        isSelected: isSameDay(date, value),
        isDisabled: !isDateInRange(date, minDate, maxDate),
        lunarText,
      });
    }

    // 下月需要填充的天数
    const remainingDays = 42 - days.length;
    for (let i = 1; i <= remainingDays; i++) {
      const date = new Date(year, month + 1, i);
      const lunarText = getLunarDayText(date);
      days.push({
        date,
        isCurrentMonth: false,
        isToday: isSameDay(date, new Date()),
        isSelected: isSameDay(date, value),
        isDisabled: !isDateInRange(date, minDate, maxDate),
        lunarText,
      });
    }

    return days;
  }, [currentMonth, value, minDate, maxDate]);

  const handlePrevMonth = () => {
    setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1));
  };

  const handleNextMonth = () => {
    setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1));
  };

  const handleDateClick = (date: Date, isDisabled: boolean) => {
    if (!isDisabled) {
      onChange(date);
    }
  };

  return (
    <Box
      style={{
        background: '#fff',
        borderRadius: 12,
        padding: 16,
        width: 280,
        boxShadow: '0 4px 20px rgba(0, 0, 0, 0.08)',
      }}
    >
      {/* 头部：月份选择 */}
      <Group justify="space-between" mb={12}>
        <ActionIcon
          variant="subtle"
          size="sm"
          radius="md"
          onClick={handlePrevMonth}
          style={{ color: '#666' }}
        >
          <IconChevronLeft size={18} />
        </ActionIcon>
        <Text
          size="sm"
          fw={600}
          style={{
            minWidth: 100,
            textAlign: 'center',
            color: '#1a1a1a',
            letterSpacing: '0.02em',
          }}
        >
          {MONTH_NAMES[currentMonth.getMonth()]} {currentMonth.getFullYear()}
        </Text>
        <ActionIcon
          variant="subtle"
          size="sm"
          radius="md"
          onClick={handleNextMonth}
          style={{ color: '#666' }}
        >
          <IconChevronRight size={18} />
        </ActionIcon>
      </Group>

      {/* 星期行 */}
      <Group gap={0} mb={8}>
        {WEEKDAYS.map((day) => (
          <Box
            key={day}
            style={{
              flex: 1,
              textAlign: 'center',
              fontSize: 11,
              color: '#999',
              fontWeight: 500,
              padding: '6px 0',
              letterSpacing: '0.05em',
            }}
          >
            {day}
          </Box>
        ))}
      </Group>

      {/* 日期网格 - 固定6行7列 */}
      <Box style={{ display: 'flex', flexDirection: 'column' }}>
        {Array.from({ length: 6 }).map((_, weekIndex) => (
          <Group key={weekIndex} gap={0} style={{ flex: 1 }}>
            {Array.from({ length: 7 }).map((_, dayIndex) => {
              const dayIndex_ = weekIndex * 7 + dayIndex;
              const day = calendarDays[dayIndex_];
              if (!day) return null;

              return (
                <Box
                  key={dayIndex_}
                  onClick={() => handleDateClick(day.date, day.isDisabled)}
                  style={{
                    flex: 1,
                    aspectRatio: '1',
                    display: 'flex',
                    flexDirection: 'column',
                    alignItems: 'center',
                    justifyContent: 'center',
                    fontSize: 13,
                    cursor: day.isDisabled ? 'not-allowed' : 'pointer',
                    borderRadius: 8,
                    background: day.isSelected
                      ? '#007AFF'
                      : day.isToday
                      ? 'rgba(0, 122, 255, 0.12)'
                      : 'transparent',
                    color: day.isCurrentMonth
                      ? day.isDisabled
                        ? '#d1d5db'
                        : day.isSelected
                        ? '#fff'
                        : '#374151'
                      : day.isDisabled
                      ? '#e5e7eb'
                      : '#9ca3af',
                    fontWeight: day.isSelected ? 600 : 500,
                    transition: 'all 0.15s ease',
                  }}
                  onMouseEnter={(e) => {
                    if (!day.isDisabled && !day.isSelected) {
                      e.currentTarget.style.background = 'rgba(0, 122, 255, 0.06)';
                    }
                  }}
                  onMouseLeave={(e) => {
                    if (!day.isDisabled && !day.isSelected) {
                      e.currentTarget.style.background = 'transparent';
                    }
                  }}
                >
                  <span>{day.date.getDate()}</span>
                  {day.lunarText && day.isCurrentMonth && !day.isDisabled && (
                    <span
                      style={{
                        fontSize: 9,
                        color: day.isSelected ? 'rgba(255,255,255,0.8)' : '#FF9500',
                        fontWeight: 400,
                        lineHeight: 1.2,
                      }}
                    >
                      {day.lunarText}
                    </span>
                  )}
                </Box>
              );
            })}
          </Group>
        ))}
      </Box>
    </Box>
  );
}
