'use client';
import { FunctionComponent, KeyboardEvent, useMemo, useRef, useState } from 'react';
import { useLocale } from 'next-intl';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import AppIconButton from '../AppIconButton';
import { formatNumber, localeTag } from '@/utils';
import { addDaysIso, engineForLocale, todayIso, type CalendarCursor } from './calendarEngine';

export type JalaliDatePickerVariant = 'grid' | 'chips';

export interface JalaliDatePickerProps {
  /** The selected date as a wire ISO (Gregorian) `YYYY-MM-DD` string, or `null` for no selection. */
  value: string | null;
  /** Fired with the wire ISO (Gregorian) date of the day the user picked. */
  onChange: (iso: string) => void;
  /** Inclusive ISO lower bound. */
  min?: string;
  /** Inclusive ISO upper bound. */
  max?: string;
  /** `grid` (default) — a month calendar with navigation. `chips` — a horizontal day-chip strip for near
   * dates (the C4 booking-form shape), starting from `min` (or today) and running `chipDayCount` days. */
  variant?: JalaliDatePickerVariant;
  chipDayCount?: number;
  /** Already-translated accessible label for the previous/next-month buttons. */
  prevMonthLabel?: string;
  nextMonthLabel?: string;
}

const GRID_COLUMNS = 7;

/**
 * Shamsi-native date selection. Renders Jalaali on `fa`, plain Gregorian on `en` — always **emits and
 * accepts ISO Gregorian** (the wire never sees a Jalaali date; display-only, per the money-and-types
 * convention already established for Shamsi dates in `utils/date.ts`). See `calendarEngine.ts` for the
 * arithmetic decision. Keyboard-navigable (arrow keys roving across the grid, Enter/Space to pick — RTL
 * flips left/right automatically), `min`/`max` bound both variants.
 * @component JalaliDatePicker
 */
const JalaliDatePicker: FunctionComponent<JalaliDatePickerProps> = ({
  value,
  onChange,
  min,
  max,
  variant = 'grid',
  chipDayCount = 14,
  prevMonthLabel,
  nextMonthLabel,
}) => {
  const locale = useLocale();
  const engine = useMemo(() => engineForLocale(locale), [locale]);
  const dir = locale === 'fa' ? 'rtl' : 'ltr';

  const initialCursor = useMemo<CalendarCursor>(() => {
    const base = value ?? min ?? todayIso();
    const { year, month } = engine.fromIso(base);
    return { year, month };
  }, [value, min, engine]);
  const [cursor, setCursor] = useState<CalendarCursor>(initialCursor);
  const cellRefs = useRef<Array<HTMLButtonElement | null>>([]);

  if (variant === 'chips') {
    const startIso = min && min > todayIso() ? min : todayIso();
    const days = Array.from({ length: chipDayCount }, (_, i) => addDaysIso(startIso, i));
    return (
      <Stack
        direction="row"
        dir={dir}
        data-jalali-picker="chips"
        sx={{ gap: 1, overflowX: 'auto', pb: 0.5, WebkitOverflowScrolling: 'touch' }}
      >
        {days.map((dayIso) => {
          const disabled = Boolean(max && dayIso > max);
          const selected = value === dayIso;
          const cell = engine.fromIso(dayIso);
          const weekday = new Intl.DateTimeFormat(localeTag(locale), { weekday: 'short' }).format(
            new Date(`${dayIso}T00:00:00`),
          );
          return (
            <Box
              key={dayIso}
              component="button"
              type="button"
              disabled={disabled}
              onClick={() => onChange(dayIso)}
              data-day={dayIso}
              data-selected={selected ? 'true' : undefined}
              sx={{
                flexShrink: 0,
                minWidth: 56,
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                gap: 0.25,
                px: 1.5,
                py: 1,
                borderRadius: 'var(--bal-radius-sm)',
                border: '1px solid',
                borderColor: selected ? 'var(--bal-primary)' : 'var(--bal-divider)',
                bgcolor: selected ? 'var(--bal-primary-soft)' : 'transparent',
                color: disabled ? 'var(--bal-text-secondary)' : 'var(--bal-text-primary)',
                cursor: disabled ? 'not-allowed' : 'pointer',
                opacity: disabled ? 0.5 : 1,
              }}
            >
              <Typography variant="caption" sx={{ color: 'text.secondary' }}>
                {weekday}
              </Typography>
              <Typography variant="body2" sx={{ fontWeight: selected ? 700 : 500 }}>
                {formatNumber(cell.day, locale)}
              </Typography>
            </Box>
          );
        })}
      </Stack>
    );
  }

  const daysInMonth = engine.daysInMonth(cursor.year, cursor.month);
  const offset = engine.firstWeekdayOffset(cursor.year, cursor.month);
  const cells: Array<{ iso: string; day: number } | null> = [
    ...Array.from({ length: offset }, () => null),
    ...Array.from({ length: daysInMonth }, (_, i) => {
      const day = i + 1;
      return { iso: engine.toIso(cursor.year, cursor.month, day), day };
    }),
  ];
  const todayIsoValue = todayIso();

  const goToMonth = (delta: number) => setCursor((c) => engine.addMonths(c, delta));

  const focusCell = (index: number) => {
    const el = cellRefs.current[index];
    if (el && !el.disabled) el.focus();
  };

  const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>, index: number) => {
    const deltas: Record<string, number> = {
      ArrowRight: dir === 'rtl' ? -1 : 1,
      ArrowLeft: dir === 'rtl' ? 1 : -1,
      ArrowDown: GRID_COLUMNS,
      ArrowUp: -GRID_COLUMNS,
    };
    const delta = deltas[event.key];
    if (delta === undefined) return;
    event.preventDefault();
    focusCell(index + delta);
  };

  return (
    <Stack dir={dir} data-jalali-picker="grid" sx={{ gap: 1.5, width: '100%' }}>
      <Stack direction="row" sx={{ alignItems: 'center', justifyContent: 'space-between' }}>
        <AppIconButton icon="back" title={prevMonthLabel} onClick={() => goToMonth(-1)} iconProps={{ size: 18 }} />
        <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
          {engine.monthYearLabel(cursor, locale === 'fa' ? 'fa-IR-u-ca-persian' : 'en-US')}
        </Typography>
        <AppIconButton icon="forward" title={nextMonthLabel} onClick={() => goToMonth(1)} iconProps={{ size: 18 }} />
      </Stack>
      <Box sx={{ display: 'grid', gridTemplateColumns: `repeat(${GRID_COLUMNS}, 1fr)`, gap: 0.5 }}>
        {engine.weekdayLabels(localeTag(locale)).map((label, i) => (
          <Typography key={i} variant="caption" align="center" sx={{ color: 'text.secondary', fontWeight: 500 }}>
            {label}
          </Typography>
        ))}
        {cells.map((cell, index) => {
          if (!cell) return <Box key={`pad-${index}`} />;
          const disabled = Boolean((min && cell.iso < min) || (max && cell.iso > max));
          const selected = value === cell.iso;
          const isToday = cell.iso === todayIsoValue;
          return (
            <Box
              key={cell.iso}
              component="button"
              type="button"
              ref={(el: HTMLElement | null) => {
                cellRefs.current[index] = el as HTMLButtonElement | null;
              }}
              disabled={disabled}
              tabIndex={selected || (!value && isToday) ? 0 : -1}
              onClick={() => onChange(cell.iso)}
              onKeyDown={(e) => handleKeyDown(e, index)}
              data-day={cell.iso}
              data-selected={selected ? 'true' : undefined}
              data-today={isToday ? 'true' : undefined}
              sx={{
                aspectRatio: '1 / 1',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                borderRadius: '50%',
                border: isToday && !selected ? '1px solid var(--bal-primary)' : '1px solid transparent',
                bgcolor: selected ? 'var(--bal-primary)' : 'transparent',
                color: selected ? 'var(--bal-primary-contrast)' : disabled ? 'var(--bal-text-secondary)' : 'var(--bal-text-primary)',
                fontWeight: selected ? 700 : 500,
                cursor: disabled ? 'not-allowed' : 'pointer',
                opacity: disabled ? 0.4 : 1,
                fontSize: '0.875rem',
                '&:hover': disabled ? undefined : { bgcolor: selected ? 'var(--bal-primary)' : 'var(--bal-primary-soft)' },
              }}
            >
              {formatNumber(cell.day, locale)}
            </Box>
          );
        })}
      </Box>
    </Stack>
  );
};

export default JalaliDatePicker;
