"use client";

import { useEffect, useId, useMemo, useRef, useState } from "react";
import { CalendarDays, ChevronLeft, ChevronRight } from "lucide-react";
import { cn } from "@/lib/utils";
import {
  MONTHS,
  WEEKDAYS,
  formatJalali,
  formatJalaliDateTime,
  isoToJalaliParts,
  jalaliMonthLength,
  jalaliPartsToIso,
  jalaliWeekdaySat0,
  shiftJalaliMonth,
  todayIso,
} from "@/lib/jalali";

type DatePickerProps = {
  value?: string;
  onChange?: (iso: string) => void;
  onBlur?: () => void;
  name?: string;
  id?: string;
  disabled?: boolean;
  placeholder?: string;
  className?: string;
  /** Gregorian ISO min/max (optional) */
  min?: string;
  max?: string;
};

/**
 * Shamsi (Jalali) date picker — Design System.
 * `value` / `onChange` use Gregorian ISO `YYYY-MM-DD` for backend APIs.
 * Calendar UI never opens the native Gregorian picker.
 */
export function DatePicker({
  value,
  onChange,
  onBlur,
  name,
  id,
  disabled,
  placeholder = "انتخاب تاریخ",
  className,
  min,
  max,
}: DatePickerProps) {
  const autoId = useId();
  const inputId = id || autoId;
  const rootRef = useRef<HTMLDivElement>(null);
  const [open, setOpen] = useState(false);

  const selected = value ? isoToJalaliParts(value) : null;
  const initial = selected || isoToJalaliParts(todayIso());
  const [view, setView] = useState({ year: initial.year, month: initial.month });

  useEffect(() => {
    if (!open) return;
    const parts = value ? isoToJalaliParts(value) : isoToJalaliParts(todayIso());
    setView({ year: parts.year, month: parts.month });
  }, [open, value]);

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

  const cells = useMemo(() => {
    const len = jalaliMonthLength(view.year, view.month);
    const start = jalaliWeekdaySat0(view.year, view.month, 1);
    const items: ({ day: number; iso: string } | null)[] = [];
    for (let i = 0; i < start; i++) items.push(null);
    for (let day = 1; day <= len; day++) {
      const iso = jalaliPartsToIso({ year: view.year, month: view.month, day });
      items.push({ day, iso });
    }
    return items;
  }, [view.year, view.month]);

  const minIso = min || undefined;
  const maxIso = max || undefined;
  const today = todayIso();

  const pick = (iso: string) => {
    if (minIso && iso < minIso) return;
    if (maxIso && iso > maxIso) return;
    onChange?.(iso);
    setOpen(false);
    onBlur?.();
  };

  const display = value ? formatJalali(value) : "";

  return (
    <div ref={rootRef} className={cn("relative", className)}>
      <input type="hidden" name={name} value={value || ""} readOnly />
      <button
        type="button"
        id={inputId}
        disabled={disabled}
        aria-haspopup="dialog"
        aria-expanded={open}
        aria-label="انتخاب تاریخ شمسی"
        onClick={() => !disabled && setOpen((o) => !o)}
        className={cn(
          "flex h-10 w-full items-center justify-between gap-2 rounded-xl border border-[var(--border)] bg-[var(--surface)] px-3 text-sm text-secondary",
          "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30",
          "disabled:cursor-not-allowed disabled:opacity-50",
          !display && "text-[var(--muted)]"
        )}
      >
        <span className="font-medium tabular-nums" dir="ltr">
          {display || placeholder}
        </span>
        <CalendarDays className="h-4 w-4 shrink-0 text-[var(--muted)]" />
      </button>

      {open ? (
        <div
          role="dialog"
          aria-label="تقویم شمسی"
          className="absolute z-50 mt-2 w-[288px] rounded-2xl border border-[var(--border)] bg-[var(--surface)] p-3 shadow-[var(--shadow-md)]"
        >
          <div className="mb-3 flex items-center justify-between gap-2">
            <button
              type="button"
              className="rounded-lg p-1.5 hover:bg-[var(--surface-muted)]"
              aria-label="ماه بعد"
              onClick={() => setView((v) => shiftJalaliMonth(v.year, v.month, 1))}
            >
              <ChevronRight className="h-4 w-4" />
            </button>
            <div className="text-sm font-semibold text-secondary">
              {MONTHS[view.month - 1]} {view.year}
            </div>
            <button
              type="button"
              className="rounded-lg p-1.5 hover:bg-[var(--surface-muted)]"
              aria-label="ماه قبل"
              onClick={() => setView((v) => shiftJalaliMonth(v.year, v.month, -1))}
            >
              <ChevronLeft className="h-4 w-4" />
            </button>
          </div>

          <div className="mb-1 grid grid-cols-7 gap-1 text-center text-[11px] text-[var(--muted)]">
            {WEEKDAYS.map((w) => (
              <div key={w} className="py-1 font-medium">
                {w}
              </div>
            ))}
          </div>

          <div className="grid grid-cols-7 gap-1">
            {cells.map((cell, idx) => {
              if (!cell) return <div key={`e-${idx}`} />;
              const isSelected = value === cell.iso;
              const isToday = cell.iso === today;
              const disabledDay =
                (minIso ? cell.iso < minIso : false) || (maxIso ? cell.iso > maxIso : false);
              return (
                <button
                  key={cell.iso}
                  type="button"
                  disabled={disabledDay}
                  onClick={() => pick(cell.iso)}
                  className={cn(
                    "flex h-9 items-center justify-center rounded-lg text-sm tabular-nums transition-colors",
                    isSelected && "bg-primary text-white shadow-sm",
                    !isSelected && isToday && "ring-1 ring-primary/40 text-primary",
                    !isSelected && !isToday && "hover:bg-[var(--surface-muted)] text-secondary",
                    disabledDay && "opacity-30 cursor-not-allowed hover:bg-transparent"
                  )}
                >
                  {cell.day}
                </button>
              );
            })}
          </div>

          <div className="mt-3 flex items-center justify-between border-t border-[var(--border)] pt-2">
            <button
              type="button"
              className="text-xs font-medium text-primary hover:underline"
              onClick={() => pick(today)}
            >
              امروز
            </button>
            <button
              type="button"
              className="text-xs text-[var(--muted)] hover:text-secondary"
              onClick={() => {
                setOpen(false);
                onBlur?.();
              }}
            >
              بستن
            </button>
          </div>
        </div>
      ) : null}
    </div>
  );
}

/** Display-only Jalali date from Gregorian ISO. */
export function JalaliDateText({
  value,
  className,
  withTime,
}: {
  value?: string | Date | null;
  className?: string;
  withTime?: boolean;
}) {
  return (
    <span className={cn("tabular-nums", className)} dir="ltr">
      {withTime ? formatJalaliDateTime(value) : formatJalali(value)}
    </span>
  );
}
