'use client';
import { useEffect, useRef, useState } from 'react';

const MONTHS = [
  'January', 'February', 'March', 'April', 'May', 'June',
  'July', 'August', 'September', 'October', 'November', 'December',
];
const WD = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];

function pad(n: number) {
  return String(n).padStart(2, '0');
}
function toISO(y: number, m: number, d: number) {
  return `${y}-${pad(m + 1)}-${pad(d)}`;
}
function parseISO(v: string): { y: number; m: number; d: number } | null {
  const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v);
  if (!m) return null;
  const y = Number(m[1]); const mo = Number(m[2]) - 1; const d = Number(m[3]);
  if (mo < 0 || mo > 11 || d < 1 || d > 31) return null;
  return { y, m: mo, d };
}
function formatHuman(v: string): string {
  const p = parseISO(v);
  if (!p) return '';
  return `${p.d} ${MONTHS[p.m].slice(0, 3)} ${p.y}`;
}

/**
 * Floating-label date picker with month/year dropdowns (easy far-future
 * picking, unlike the native control). Same 3.5rem footprint as FloatInput.
 * Value is always YYYY-MM-DD (or '').
 */
export function DatePicker({ label, id, value, onChange, error, hint, min, max, required }: {
  label: string; id: string; value: string; onChange: (v: string) => void;
  error?: string; hint?: string; min?: string; max?: string; required?: boolean;
}) {
  const [open, setOpen] = useState(false);
  const wrapRef = useRef<HTMLDivElement>(null);
  const now = new Date();
  const parsed = parseISO(value);
  const [vy, setVy] = useState(parsed?.y ?? now.getFullYear());
  const [vm, setVm] = useState(parsed?.m ?? now.getMonth());

  // When opened, jump the calendar to the current value (or today).
  useEffect(() => {
    if (open) {
      const p = parseISO(value);
      setVy(p?.y ?? new Date().getFullYear());
      setVm(p?.m ?? new Date().getMonth());
    }
  }, [open, value]);

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

  const minY = min ? Number(min.slice(0, 4)) : now.getFullYear() - 10;
  const maxY = max ? Number(max.slice(0, 4)) : now.getFullYear() + 20;
  const years: number[] = [];
  for (let y = minY; y <= maxY; y++) years.push(y);

  const firstDow = (new Date(vy, vm, 1).getDay() + 6) % 7; // Monday-first
  const daysInMonth = new Date(vy, vm + 1, 0).getDate();
  const cells: (number | null)[] = [...Array(firstDow).fill(null)];
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);

  const pick = (d: number) => {
    onChange(toISO(vy, vm, d));
    setOpen(false);
  };
  const todayStr = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;

  return (
    <div ref={wrapRef} className={`ff floated relative`}>
      <input
        id={id} readOnly
        value={formatHuman(value)}
        placeholder=" "
        aria-label={label}
        aria-invalid={!!error}
        aria-expanded={open}
        autoComplete="off"
        onFocus={() => setOpen(true)}
        onClick={() => setOpen(true)}
        className="input cursor-pointer pr-9"
      />
      <label htmlFor={id}>{label}{required && <span aria-hidden="true"> *</span>}</label>
      <span aria-hidden="true" className="absolute right-3 pointer-events-none text-slate-400" style={{ top: '1.05rem' }}>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
          <rect x="3" y="4" width="18" height="18" rx="2" /><path d="M16 2v4M8 2v4M3 10h18" />
        </svg>
      </span>
      {open && (
        <div role="dialog" aria-label={`${label} calendar`} className="absolute z-40 mt-1 rounded-xl border shadow-xl p-2 w-64"
          style={{ background: 'var(--surface)', borderColor: 'var(--line)' }}>
          <div className="flex gap-1 mb-1">
            <select aria-label="Month" className="input text-sm !min-h-0 !h-9" value={vm} onChange={(e) => setVm(Number(e.target.value))}>
              {MONTHS.map((m, i) => <option key={m} value={i}>{m}</option>)}
            </select>
            <select aria-label="Year" className="input text-sm !min-h-0 !h-9" value={vy} onChange={(e) => setVy(Number(e.target.value))}>
              {years.map((y) => <option key={y} value={y}>{y}</option>)}
            </select>
          </div>
          <div className="grid grid-cols-7 gap-0.5 text-center">
            {WD.map((w) => <span key={w} className="text-[10px] font-bold py-0.5" style={{ color: 'var(--muted)' }}>{w}</span>)}
            {cells.map((d, i) => d == null ? <span key={`b${i}`} /> : (() => {
              const iso = toISO(vy, vm, d);
              const dis = !!((min && iso < min) || (max && iso > max));
              const sel = iso === value;
              const isToday = iso === todayStr;
              return (
                <button key={d} type="button" disabled={dis} onClick={() => pick(d)}
                  aria-label={iso} aria-pressed={sel}
                  className={`text-xs rounded-md py-1 transition ${sel ? 'font-bold text-white' : dis ? 'opacity-30' : 'hover:bg-slate-500/15'}`}
                  style={sel ? { background: 'var(--ink)', color: 'var(--bg)' } : isToday ? { outline: '1px solid var(--accent)' } : undefined}>
                  {d}
                </button>
              );
            })())}
          </div>
          <div className="flex gap-1 mt-1">
            <button type="button" className="btn-ghost btn-sm flex-1" onClick={() => { onChange(todayStr); setOpen(false); }}>Today</button>
            <button type="button" className="btn-ghost btn-sm flex-1" onClick={() => { onChange(''); setOpen(false); }}>Clear</button>
          </div>
        </div>
      )}
      {hint && !error && <p className="hint mt-1">{hint}</p>}
      {error && <p role="alert" className="field-error">{error}</p>}
    </div>
  );
}
