import React, { useEffect, useRef, useState } from 'react';
import { ChevronRightIcon, ChevronLeftIcon } from '@heroicons/react/24/outline';

interface Props {
  value: string;        // YYYY-MM-DD Gregorian
  onChange: (v: string) => void;
  onClose: () => void;
  /** انتخاب سال→ماه→روز را فعال می‌کند (پیش‌فرض خاموش — مناسب تاریخ تولد). */
  enableYearPicker?: boolean;
}

const WEEK_DAYS = ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج'];

const pf = new Intl.DateTimeFormat('fa-IR-u-ca-persian', { calendar: 'persian' });

function toJalali(d: Date): { year: number; month: number; day: number } {
  const parts = new Intl.DateTimeFormat('en-u-ca-persian', {
    year: 'numeric', month: 'numeric', day: 'numeric',
  }).formatToParts(d);
  const get = (t: string) => parseInt(parts.find(p => p.type === t)?.value ?? '0', 10);
  return { year: get('year'), month: get('month'), day: get('day') };
}

function jalaliFirstWeekday(year: number, month: number): number {
  // Build a Gregorian date for the 1st of this Jalali month by iterating
  // Use the Intl API: find Gregorian date whose Jalali = year/month/1
  // Approximate: use known offset
  const approxGreg = jalaliToGregorian(year, month, 1);
  const d = new Date(approxGreg + 'T12:00:00');
  // JS getDay(): 0=Sun,1=Mon,...,6=Sat → convert to Sat=0
  return (d.getDay() + 1) % 7; // Sat=0, Sun=1, ..., Fri=6
}

function jalaliToGregorian(jy: number, jm: number, jd: number): string {
  const jy2 = jy - 979;
  const jm2 = jm - 1;
  let jDay = 365 * jy2 + Math.floor(jy2 / 33) * 8 + Math.floor(((jy2 % 33) + 3) / 4);
  for (let i = 0; i < jm2; i++) jDay += (i < 6 ? 31 : 30);
  jDay += jd - 1;
  let gDay = jDay + 79;
  let gy2 = 1600 + 400 * Math.floor(gDay / 146097);
  gDay %= 146097;
  let leap = true;
  if (gDay >= 36525) {
    gDay--;
    const gi = Math.floor(gDay / 36524);
    gDay %= 36524;
    gy2 += gi * 100;
    if (gDay >= 365) { gDay++; leap = false; }
  }
  gy2 += Math.floor(gDay / 1461) * 4;
  gDay %= 1461;
  if (gDay >= 366) {
    leap = false;
    gDay--;
    gy2 += Math.floor(gDay / 365);
    gDay %= 365;
  }
  const gMonthDays = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  let gm = 0;
  for (; gm < 12; gm++) {
    if (gDay < gMonthDays[gm]) break;
    gDay -= gMonthDays[gm];
  }
  return `${gy2}-${String(gm + 1).padStart(2, '0')}-${String(gDay + 1).padStart(2, '0')}`;
}

const JALALI_MONTHS = ['فروردین','اردیبهشت','خرداد','تیر','مرداد','شهریور','مهر','آبان','آذر','دی','بهمن','اسفند'];

export default function PersianCalendar({ value, onChange, onClose, enableYearPicker = false }: Props) {
  const ref = useRef<HTMLDivElement>(null);

  const todayGreg = new Date().toISOString().slice(0, 10);
  const todayJ = toJalali(new Date(todayGreg + 'T12:00:00'));
  const valueJ = value ? toJalali(new Date(value + 'T12:00:00')) : todayJ;

  const [viewYear, setViewYear] = useState(valueJ.year);
  const [viewMonth, setViewMonth] = useState(valueJ.month);
  const [mode, setMode] = useState<'day' | 'month' | 'year'>('day');
  // ابتدای بازه‌ی ۱۲تایی سال در نمای انتخاب سال
  const [yearRangeStart, setYearRangeStart] = useState(valueJ.year - (valueJ.year % 12));

  const faYear = (y: number) => y.toLocaleString('fa-IR', { useGrouping: false });

  useEffect(() => {
    function handler(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) onClose();
    }
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [onClose]);

  const daysCount = viewMonth <= 6 ? 31 : viewMonth <= 11 ? 30 : 29;
  const firstWd = jalaliFirstWeekday(viewYear, viewMonth);

  function prevMonth() {
    if (viewMonth === 1) { setViewYear(y => y - 1); setViewMonth(12); }
    else setViewMonth(m => m - 1);
  }
  function nextMonth() {
    if (viewMonth === 12) { setViewYear(y => y + 1); setViewMonth(1); }
    else setViewMonth(m => m + 1);
  }

  function selectDay(day: number) {
    const greg = jalaliToGregorian(viewYear, viewMonth, day);
    onChange(greg);
    onClose();
  }

  const isToday = (day: number) =>
    todayJ.year === viewYear && todayJ.month === viewMonth && todayJ.day === day;

  const isSelected = (day: number) =>
    value !== '' && valueJ.year === viewYear && valueJ.month === viewMonth && valueJ.day === day;

  const cells: (number | null)[] = [...Array(firstWd).fill(null), ...Array.from({ length: daysCount }, (_, i) => i + 1)];
  while (cells.length % 7 !== 0) cells.push(null);

  return (
    <div ref={ref} style={{
      position: 'absolute', top: '100%', right: 0, zIndex: 999, marginTop: 4,
      background: 'var(--surface)', border: '1px solid var(--border)',
      borderRadius: 'var(--r)', boxShadow: 'var(--shadow-lg)',
      padding: '12px', width: 268, direction: 'rtl',
    }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
        <button
          type="button"
          onClick={mode === 'year' ? () => setYearRangeStart(s => s - 12) : nextMonth}
          style={{ ...navBtnStyle, visibility: mode === 'month' ? 'hidden' : 'visible' }}
        >
          <ChevronRightIcon style={{ width: 16, height: 16 }} />
        </button>

        {mode === 'day' && (
          <span style={{ fontWeight: 700, fontSize: 14, display: 'flex', gap: 6 }}>
            <span
              onClick={enableYearPicker ? () => setMode('month') : undefined}
              style={{ cursor: enableYearPicker ? 'pointer' : 'default', color: enableYearPicker ? 'var(--primary)' : 'inherit' }}
            >
              {JALALI_MONTHS[viewMonth - 1]}
            </span>
            <span
              onClick={enableYearPicker ? () => { setYearRangeStart(viewYear - (viewYear % 12)); setMode('year'); } : undefined}
              style={{ cursor: enableYearPicker ? 'pointer' : 'default', color: enableYearPicker ? 'var(--primary)' : 'inherit' }}
            >
              {faYear(viewYear)}
            </span>
          </span>
        )}
        {mode === 'month' && <span style={{ fontWeight: 700, fontSize: 14 }}>انتخاب ماه {faYear(viewYear)}</span>}
        {mode === 'year' && (
          <span style={{ fontWeight: 700, fontSize: 14 }}>
            {faYear(yearRangeStart)} - {faYear(yearRangeStart + 11)}
          </span>
        )}

        <button
          type="button"
          onClick={mode === 'year' ? () => setYearRangeStart(s => s + 12) : prevMonth}
          style={{ ...navBtnStyle, visibility: mode === 'month' ? 'hidden' : 'visible' }}
        >
          <ChevronLeftIcon style={{ width: 16, height: 16 }} />
        </button>
      </div>

      {/* Day view */}
      {mode === 'day' && (
        <>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2, marginBottom: 4 }}>
            {WEEK_DAYS.map(d => (
              <div key={d} style={{ textAlign: 'center', fontSize: 11, color: 'var(--text-3)', fontWeight: 600, padding: '2px 0' }}>
                {d}
              </div>
            ))}
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)', gap: 2 }}>
            {cells.map((day, i) => {
              if (!day) return <div key={i} />;
              const sel = isSelected(day);
              const tod = isToday(day) && !sel;
              return (
                <button
                  key={i}
                  type="button"
                  onClick={() => selectDay(day)}
                  style={{
                    width: 32, height: 32, borderRadius: '50%', fontSize: 12,
                    border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontWeight: sel || tod ? 700 : 400,
                    background: sel ? 'var(--primary)' : tod ? 'var(--surface-2)' : 'transparent',
                    color: sel ? '#fff' : tod ? 'var(--text)' : 'var(--text)',
                    transition: 'background 0.1s',
                  }}
                  onMouseEnter={e => { if (!sel && !tod) (e.currentTarget as HTMLButtonElement).style.background = 'var(--surface-2)'; }}
                  onMouseLeave={e => { if (!sel && !tod) (e.currentTarget as HTMLButtonElement).style.background = 'transparent'; }}
                >
                  {day.toLocaleString('fa-IR')}
                </button>
              );
            })}
          </div>
        </>
      )}

      {/* Month view */}
      {mode === 'month' && (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 6 }}>
          {JALALI_MONTHS.map((mName, idx) => {
            const m = idx + 1;
            const active = m === viewMonth;
            return (
              <button
                key={m}
                type="button"
                onClick={() => { setViewMonth(m); setMode('day'); }}
                style={{ ...gridItemStyle, background: active ? 'var(--primary)' : 'transparent', color: active ? '#fff' : 'var(--text)' }}
                onMouseEnter={e => { if (!active) (e.currentTarget as HTMLButtonElement).style.background = 'var(--surface-2)'; }}
                onMouseLeave={e => { if (!active) (e.currentTarget as HTMLButtonElement).style.background = 'transparent'; }}
              >
                {mName}
              </button>
            );
          })}
        </div>
      )}

      {/* Year view */}
      {mode === 'year' && (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 6 }}>
          {Array.from({ length: 12 }, (_, i) => yearRangeStart + i).map(y => {
            const active = y === viewYear;
            return (
              <button
                key={y}
                type="button"
                onClick={() => { setViewYear(y); setMode('month'); }}
                style={{ ...gridItemStyle, background: active ? 'var(--primary)' : 'transparent', color: active ? '#fff' : 'var(--text)' }}
                onMouseEnter={e => { if (!active) (e.currentTarget as HTMLButtonElement).style.background = 'var(--surface-2)'; }}
                onMouseLeave={e => { if (!active) (e.currentTarget as HTMLButtonElement).style.background = 'transparent'; }}
              >
                {faYear(y)}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

const navBtnStyle: React.CSSProperties = {
  background: 'transparent', border: 'none', cursor: 'pointer',
  color: 'var(--text-2)', padding: 4, borderRadius: 'var(--r-sm)',
  display: 'flex', alignItems: 'center',
};

const gridItemStyle: React.CSSProperties = {
  height: 40, borderRadius: 'var(--r-sm)', fontSize: 13, fontWeight: 500,
  border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
  transition: 'background 0.1s',
};
