'use client';

import { useLocale, useTranslations } from 'next-intl';
import { formatAppInteger, usesPersianCalendar } from '@/lib/i18n/format';
import {
  formatPersianMonthLabel,
  getLocalPersianParts,
  jalaliDaysInMonth,
  persianPartsToLocalDate,
  persianYearRange,
} from '@/lib/i18n/persianCalendar';
import { startOfLocalDay } from '@/components/appointments/appointmentTime';
import { CompactSelect } from '@/components/ui/shared/CompactSelect';

const MONTH_KEYS = [
  'monthJanuary',
  'monthFebruary',
  'monthMarch',
  'monthApril',
  'monthMay',
  'monthJune',
  'monthJuly',
  'monthAugust',
  'monthSeptember',
  'monthOctober',
  'monthNovember',
  'monthDecember',
] as const;

function daysInMonth(year: number, month: number): number {
  return new Date(year, month + 1, 0).getDate();
}

function buildLocalDay(year: number, month: number, day: number): Date {
  return new Date(year, month, day, 0, 0, 0, 0);
}

function yearRange(anchor: Date): number[] {
  const anchorYear = anchor.getFullYear();
  const years: number[] = [];
  for (let y = anchorYear - 10; y <= anchorYear + 2; y += 1) {
    years.push(y);
  }
  return years;
}

export type CalendarDayPartsPanelProps = {
  panelId: string;
  value: Date;
  onChange: (day: Date) => void;
  closePanelOnDaySelect?: boolean;
  onAfterSelect?: (day: Date) => void;
};

/** Year / month / day dropdown row — shared by schedule picker and date fields. */
export function CalendarDayPartsPanel({
  panelId,
  value,
  onChange,
  closePanelOnDaySelect = false,
  onAfterSelect,
}: CalendarDayPartsPanelProps) {
  const locale = useLocale();
  const t = useTranslations('schedule');
  const normalizedValue = startOfLocalDay(value);
  const persian = usesPersianCalendar(locale);
  const jalaliParts = persian ? getLocalPersianParts(normalizedValue) : null;
  const gregorianYear = normalizedValue.getFullYear();
  const gregorianMonth = normalizedValue.getMonth();
  const gregorianDay = normalizedValue.getDate();
  const years =
    persian && jalaliParts ? persianYearRange(jalaliParts.year) : yearRange(normalizedValue);
  const selectedYear = jalaliParts?.year ?? gregorianYear;
  const selectedMonth = jalaliParts?.month ?? gregorianMonth;
  const selectedDay = jalaliParts?.day ?? gregorianDay;
  const dayCount = persian
    ? jalaliDaysInMonth(selectedYear, selectedMonth)
    : daysInMonth(selectedYear, selectedMonth);

  function applyParts(year: number, month: number, day: number, closePanel = false) {
    const maxDay = persian ? jalaliDaysInMonth(year, month) : daysInMonth(year, month);
    const clampedDay = Math.min(Math.max(1, day), maxDay);
    onChange(
      persian
        ? persianPartsToLocalDate(year, month, clampedDay)
        : buildLocalDay(year, month, clampedDay),
    );
    if (closePanel) {
      const nextDay = persian
        ? persianPartsToLocalDate(year, month, clampedDay)
        : buildLocalDay(year, month, clampedDay);
      onAfterSelect?.(nextDay);
    }
  }

  function formatPanelYear(year: number): string {
    return persian ? formatAppInteger(year, locale) : String(year);
  }

  function formatPanelDay(day: number): string {
    return persian ? formatAppInteger(day, locale) : String(day);
  }

  return (
    <div className="grid grid-cols-3 gap-2">
      <div>
        <label htmlFor={`${panelId}-year`} className="mb-1 block text-xs font-medium text-text-muted">
          {t('year')}
        </label>
        <CompactSelect
          id={`${panelId}-year`}
          value={selectedYear}
          onChange={(e) => applyParts(Number(e.target.value), selectedMonth, selectedDay)}
        >
          {years.map((year) => (
            <option key={year} value={year}>
              {formatPanelYear(year)}
            </option>
          ))}
        </CompactSelect>
      </div>

      <div>
        <label htmlFor={`${panelId}-month`} className="mb-1 block text-xs font-medium text-text-muted">
          {t('month')}
        </label>
        <CompactSelect
          id={`${panelId}-month`}
          value={selectedMonth}
          onChange={(e) => applyParts(selectedYear, Number(e.target.value), selectedDay)}
        >
          {persian
            ? Array.from({ length: 12 }, (_, i) => i + 1).map((month) => (
                <option key={month} value={month}>
                  {formatPersianMonthLabel(selectedYear, month)}
                </option>
              ))
            : MONTH_KEYS.map((key, index) => (
                <option key={key} value={index}>
                  {t(key)}
                </option>
              ))}
        </CompactSelect>
      </div>

      <div>
        <label htmlFor={`${panelId}-day`} className="mb-1 block text-xs font-medium text-text-muted">
          {t('day')}
        </label>
        <CompactSelect
          id={`${panelId}-day`}
          value={selectedDay}
          onChange={(e) =>
            applyParts(selectedYear, selectedMonth, Number(e.target.value), closePanelOnDaySelect)
          }
        >
          {Array.from({ length: dayCount }, (_, i) => i + 1).map((day) => (
            <option key={day} value={day}>
              {formatPanelDay(day)}
            </option>
          ))}
        </CompactSelect>
      </div>
    </div>
  );
}
