// @design-system: domain/DealDurationPicker

'use client';

import { useState, useCallback } from 'react';
import { addDays, addMonths, endOfDay, endOfMonth, format } from 'date-fns';
import { he, enUS } from 'date-fns/locale';
import { FormField } from '@/components/ui/primitives/FormField';
import { Input } from '@/components/ui/primitives/Input';
import { useT, useLocale } from '@/lib/i18n/react';

export interface BusinessHoursSnapshot {
  thursdayClosed: boolean;
  thursdayClose: string | null;
  fridayClosed: boolean;
  fridayClose: string | null;
}

export type DurationPreset =
  | '1d'
  | '1w'
  | '1m'
  | 'end-of-day'
  | 'end-of-week'
  | 'end-of-month'
  | 'custom';

export interface DealDurationPickerProps {
  startValue: string | undefined;
  endValue: string | undefined;
  onStartChange: (v: string) => void;
  onEndChange: (v: string) => void;
  businessHours: BusinessHoursSnapshot | null;
  error?: string;
  /**
   * When true, hides the start-date display row and the datetime-local start
   * override input. Used by LaunchModePicker "launch now" mode where windowStart
   * is resolved to the current time at submit — not user-editable.
   */
  hideStartInput?: boolean;
}

function toLocal(d: Date): string {
  const pad = (n: number) => String(n).padStart(2, '0');
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
}

function parseTimeStr(t: string): [number, number] {
  const [h, m] = t.split(':').map(Number);
  return [h ?? 0, m ?? 0];
}

function withCloseTime(d: Date, closeStr: string | null): Date {
  const result = new Date(d);
  if (!closeStr) {
    result.setHours(23, 59, 0, 0);
    return result;
  }
  const [h, m] = parseTimeStr(closeStr);
  result.setHours(h, m, 0, 0);
  return result;
}

function nextWeekday(from: Date, targetDay: number): Date {
  const result = new Date(from);
  result.setHours(0, 0, 0, 0);
  const diff = (targetDay - result.getDay() + 7) % 7;
  result.setDate(result.getDate() + diff);
  return result;
}

function computeEndOfWeek(start: Date, bh: BusinessHoursSnapshot): Date | null {
  if (!bh.fridayClosed) {
    const friday = nextWeekday(start, 5);
    const candidate = withCloseTime(friday, bh.fridayClose);
    if (candidate > start) return candidate;
    return null;
  }
  if (!bh.thursdayClosed) {
    const thursday = nextWeekday(start, 4);
    const candidate = withCloseTime(thursday, bh.thursdayClose);
    if (candidate > start) return candidate;
    return null;
  }
  return null;
}

const MAX_DURATION_MS = 31 * 24 * 60 * 60 * 1000;

export function DealDurationPicker({
  startValue,
  endValue,
  onStartChange,
  onEndChange,
  businessHours,
  error,
  hideStartInput = false,
}: DealDurationPickerProps) {
  const t = useT('vendor_add_deal');
  const { locale: appLocale } = useLocale();
  const dateFnsLocale = appLocale === 'he' ? he : enUS;
  const [preset, setPreset] = useState<DurationPreset>('1w');
  const [showStartOverride, setShowStartOverride] = useState(false);

  const startDate = startValue ? new Date(startValue) : new Date();

  const applyPreset = useCallback(
    (p: DurationPreset, base: Date) => {
      setPreset(p);
      if (p === 'custom') return;
      let end: Date | null = null;
      if (p === '1d') end = addDays(base, 1);
      else if (p === '1w') end = addDays(base, 7);
      else if (p === '1m') end = addMonths(base, 1);
      else if (p === 'end-of-day') {
        const e = endOfDay(base);
        end = e > base ? e : null;
      } else if (p === 'end-of-week')
        end = businessHours ? computeEndOfWeek(base, businessHours) : null;
      else if (p === 'end-of-month') {
        const e = endOfMonth(base);
        end = e > base ? e : null;
      }
      if (end) onEndChange(toLocal(end));
    },
    [businessHours, onEndChange],
  );

  const handleStartChange = (v: string) => {
    onStartChange(v);
    const newBase = v ? new Date(v) : new Date();
    applyPreset(preset, newBase);
  };

  const isMaxExceeded =
    startValue && endValue
      ? new Date(endValue).getTime() - new Date(startValue).getTime() > MAX_DURATION_MS
      : false;

  const showEndOfWeek = businessHours
    ? !businessHours.fridayClosed || !businessHours.thursdayClosed
    : false;

  const presets: { key: DurationPreset; label: string }[] = [
    { key: '1d', label: t('duration_preset_1d') },
    { key: '1w', label: t('duration_preset_1w') },
    { key: '1m', label: t('duration_preset_1m') },
    { key: 'end-of-day', label: t('duration_preset_end_of_day') },
    ...(showEndOfWeek
      ? [{ key: 'end-of-week' as DurationPreset, label: t('duration_preset_end_of_week') }]
      : []),
    { key: 'end-of-month', label: t('duration_preset_end_of_month') },
    { key: 'custom', label: t('duration_preset_custom') },
  ];

  const endDateDisplay =
    endValue && preset !== 'custom'
      ? format(new Date(endValue), 'EEEE d MMMM, HH:mm', { locale: dateFnsLocale })
      : null;

  return (
    <div className="flex flex-col gap-2">
      <span className="text-text-primary text-sm font-medium">{t('duration_label')}</span>

      {!hideStartInput && (
        <div className="flex items-center gap-2">
          {!showStartOverride && (
            <>
              <span className="text-text-secondary text-sm">
                {startValue
                  ? format(new Date(startValue), 'd MMM HH:mm', { locale: dateFnsLocale })
                  : t('duration_immediate')}
              </span>
              <button
                type="button"
                onClick={() => setShowStartOverride(true)}
                className="text-mode-vendor-600 text-xs underline"
              >
                {t('duration_change_start')}
              </button>
            </>
          )}
        </div>
      )}

      {!hideStartInput && showStartOverride && (
        <FormField htmlFor="deal-start" label={t('start_time')}>
          <Input
            id="deal-start"
            type="datetime-local"
            dir="ltr"
            value={startValue ?? ''}
            onChange={(e) => handleStartChange(e.target.value)}
          />
        </FormField>
      )}

      <div className="flex flex-wrap gap-1.5" role="group" aria-label={t('duration_label')}>
        {presets.map(({ key, label }) => (
          <button
            key={key}
            type="button"
            onClick={() => applyPreset(key, startDate)}
            aria-pressed={preset === key}
            className={[
              'rounded-full border px-3 py-1 text-xs font-medium transition-colors',
              preset === key
                ? 'bg-mode-vendor-600 border-mode-vendor-600 text-white'
                : 'border-border-default text-text-secondary hover:border-mode-vendor-400',
            ].join(' ')}
          >
            {label}
          </button>
        ))}
      </div>

      {preset === 'custom' && (
        <FormField htmlFor="deal-end" label={t('end_time')}>
          <Input
            id="deal-end"
            type="datetime-local"
            dir="ltr"
            className="w-auto"
            value={endValue ?? ''}
            onChange={(e) => onEndChange(e.target.value)}
          />
        </FormField>
      )}

      {endDateDisplay && (
        <p className="text-text-secondary text-xs">
          {t('duration_ends_on')} <span className="font-medium">{endDateDisplay}</span>
        </p>
      )}

      {isMaxExceeded && (
        <p role="alert" className="text-danger-600 text-xs">
          {t('duration_max_error')}
        </p>
      )}

      {error && (
        <p role="alert" className="text-danger-600 text-xs">
          {error}
        </p>
      )}
    </div>
  );
}
