import { useEffect, useMemo, useRef, useState } from 'react';
import {
  isoToJalaliParts,
  jalaliMonthLength,
  jalaliMonthNames,
  jalaliToday,
  jalaliToDate,
  jalaliToIso,
  jalaliWeekdayIndex,
  persianDigits,
} from '@/lib/persianDate';

type Props = {
  label?: string;
  /** مقدار میلادی «YYYY-MM-DD» — همان چیزی که به سرور می‌رود. */
  value: string;
  onChange: (iso: string) => void;
  error?: string;
  placeholder?: string;
  clearable?: boolean;
};

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

export function JalaliDatePicker({ label, value, onChange, error, placeholder = 'انتخاب تاریخ', clearable = true }: Props) {
  const today = useMemo(() => jalaliToday(), []);
  const selected = isoToJalaliParts(value || null);

  const [open, setOpen] = useState(false);
  const [mode, setMode] = useState<'days' | 'months' | 'years'>('days');
  const [viewYear, setViewYear] = useState(selected?.jy ?? today.jy);
  const [viewMonth, setViewMonth] = useState(selected?.jm ?? today.jm);
  const rootRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!open) return;
    const onDocClick = (event: MouseEvent) => {
      if (rootRef.current && !rootRef.current.contains(event.target as Node)) setOpen(false);
    };
    const onKey = (event: KeyboardEvent) => {
      if (event.key === 'Escape') setOpen(false);
    };
    document.addEventListener('mousedown', onDocClick);
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('mousedown', onDocClick);
      document.removeEventListener('keydown', onKey);
    };
  }, [open]);

  const openPicker = () => {
    setViewYear(selected?.jy ?? today.jy);
    setViewMonth(selected?.jm ?? today.jm);
    setMode('days');
    setOpen((prev) => !prev);
  };

  const shiftMonth = (delta: number) => {
    let m = viewMonth + delta;
    let y = viewYear;
    if (m < 1) { m = 12; y -= 1; }
    if (m > 12) { m = 1; y += 1; }
    setViewMonth(m);
    setViewYear(y);
  };

  const pickDay = (day: number) => {
    onChange(jalaliToIso(viewYear, viewMonth, day));
    setOpen(false);
  };

  const monthLen = jalaliMonthLength(viewYear, viewMonth);
  const firstWeekday = jalaliWeekdayIndex(jalaliToDate(viewYear, viewMonth, 1));

  const display = selected
    ? persianDigits(`${selected.jy}/${String(selected.jm).padStart(2, '0')}/${String(selected.jd).padStart(2, '0')}`)
    : '';

  const yearOptions = useMemo(() => {
    const base = selected?.jy ?? today.jy;
    const years: number[] = [];
    for (let y = base + 10; y >= base - 60; y -= 1) years.push(y);
    return years;
  }, [selected?.jy, today.jy]);

  return (
    <div className="form-field jdp-field" ref={rootRef}>
      {label && <span>{label}</span>}
      <div className="jdp-anchor">
        <button type="button" className={`jdp-input${display ? '' : ' jdp-input--empty'}`} onClick={openPicker}>
          <i className="bi bi-calendar3" aria-hidden="true" />
          <span>{display || placeholder}</span>
          {clearable && display && (
            <span
              className="jdp-clear"
              role="button"
              tabIndex={0}
              aria-label="پاک کردن تاریخ"
              onClick={(event) => { event.stopPropagation(); onChange(''); }}
              onKeyDown={(event) => { if (event.key === 'Enter') { event.stopPropagation(); onChange(''); } }}
            >
              <i className="bi bi-x-lg" />
            </span>
          )}
        </button>

        {open && (
          <div className="jdp-pop" role="dialog" aria-label="تقویم جلالی">
            <div className="jdp-head">
              <button type="button" className="jdp-nav" aria-label="ماه بعد" onClick={() => shiftMonth(1)}>
                <i className="bi bi-chevron-right" />
              </button>
              <div className="jdp-title">
                <button type="button" onClick={() => setMode(mode === 'months' ? 'days' : 'months')}>
                  {jalaliMonthNames[viewMonth - 1]}
                </button>
                <button type="button" onClick={() => setMode(mode === 'years' ? 'days' : 'years')}>
                  {persianDigits(viewYear)}
                </button>
              </div>
              <button type="button" className="jdp-nav" aria-label="ماه قبل" onClick={() => shiftMonth(-1)}>
                <i className="bi bi-chevron-left" />
              </button>
            </div>

            {mode === 'days' && (
              <>
                <div className="jdp-week">
                  {WEEKDAY_SHORT.map((w, i) => (
                    <span key={w} className={i === 6 ? 'jdp-fri' : undefined}>{w}</span>
                  ))}
                </div>
                <div className="jdp-grid">
                  {Array.from({ length: firstWeekday }).map((_, i) => <span key={`b${i}`} />)}
                  {Array.from({ length: monthLen }).map((_, i) => {
                    const day = i + 1;
                    const isToday = viewYear === today.jy && viewMonth === today.jm && day === today.jd;
                    const isSelected = !!selected && selected.jy === viewYear && selected.jm === viewMonth && selected.jd === day;
                    const isFriday = (firstWeekday + i) % 7 === 6;
                    return (
                      <button
                        key={day}
                        type="button"
                        className={[
                          'jdp-day',
                          isToday ? 'is-today' : '',
                          isSelected ? 'is-selected' : '',
                          isFriday ? 'jdp-fri' : '',
                        ].filter(Boolean).join(' ')}
                        onClick={() => pickDay(day)}
                      >
                        {persianDigits(day)}
                      </button>
                    );
                  })}
                </div>
              </>
            )}

            {mode === 'months' && (
              <div className="jdp-months">
                {jalaliMonthNames.map((name, i) => (
                  <button
                    key={name}
                    type="button"
                    className={i + 1 === viewMonth ? 'is-selected' : undefined}
                    onClick={() => { setViewMonth(i + 1); setMode('days'); }}
                  >
                    {name}
                  </button>
                ))}
              </div>
            )}

            {mode === 'years' && (
              <div className="jdp-years">
                {yearOptions.map((year) => (
                  <button
                    key={year}
                    type="button"
                    className={year === viewYear ? 'is-selected' : undefined}
                    onClick={() => { setViewYear(year); setMode('days'); }}
                  >
                    {persianDigits(year)}
                  </button>
                ))}
              </div>
            )}

            <div className="jdp-foot">
              <button
                type="button"
                className="jdp-today"
                onClick={() => { onChange(jalaliToIso(today.jy, today.jm, today.jd)); setOpen(false); }}
              >
                <i className="bi bi-calendar-check" /> امروز
              </button>
              {clearable && (
                <button type="button" className="jdp-reset" onClick={() => { onChange(''); setOpen(false); }}>
                  پاک کردن
                </button>
              )}
            </div>
          </div>
        )}
      </div>
      {error && <span className="field-error">{error}</span>}
    </div>
  );
}
