import { useEffect, useId, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { CloseIcon } from './icons/CloseIcon';
import { DownloadIcon } from './icons/DownloadIcon';
import { SpinnerIcon } from './icons/SpinnerIcon';

export type ExportMode = 'filters' | 'list';

interface ExportMenuProps {
  open: boolean;
  exporting: boolean;
  onClose: () => void;
  onExport: (options?: { postcodes?: string[] }) => void;
}

const EMPTY_LIST: string[] = [''];

export default function ExportMenu({ open, exporting, onClose, onExport }: ExportMenuProps) {
  const { t } = useTranslation();
  const [mode, setMode] = useState<ExportMode>('filters');
  const [postcodes, setPostcodes] = useState<string[]>(EMPTY_LIST);
  const titleId = useId();
  const inputRefs = useRef<Array<HTMLInputElement | null>>([]);
  const focusIndexRef = useRef<number | null>(null);

  useEffect(() => {
    if (!open) return;
    const handler = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [open, onClose]);

  useEffect(() => {
    if (focusIndexRef.current == null) return;
    inputRefs.current[focusIndexRef.current]?.focus();
    focusIndexRef.current = null;
  }, [postcodes.length]);

  if (!open) return null;

  const cleaned = postcodes.map((p) => p.trim()).filter(Boolean);
  const canSubmit = !exporting && (mode === 'filters' || cleaned.length > 0);

  const handleSubmit = () => {
    if (!canSubmit) return;
    if (mode === 'list') {
      onExport({ postcodes: cleaned });
    } else {
      onExport();
    }
  };

  const updateAt = (idx: number, value: string) => {
    setPostcodes((prev) => prev.map((p, i) => (i === idx ? value : p)));
  };

  const addRow = () => {
    setPostcodes((prev) => {
      focusIndexRef.current = prev.length;
      return [...prev, ''];
    });
  };

  const removeAt = (idx: number) => {
    setPostcodes((prev) => {
      if (prev.length <= 1) return [''];
      return prev.filter((_, i) => i !== idx);
    });
  };

  const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>, idx: number) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      if (idx === postcodes.length - 1 && postcodes[idx].trim()) {
        addRow();
      } else {
        inputRefs.current[idx + 1]?.focus();
      }
    } else if (e.key === 'Backspace' && postcodes[idx] === '' && postcodes.length > 1) {
      e.preventDefault();
      focusIndexRef.current = Math.max(0, idx - 1);
      removeAt(idx);
    }
  };

  const cardClass = (selected: boolean) =>
    `w-full text-left cursor-pointer rounded-lg border p-3 transition-colors ${
      selected
        ? 'border-teal-500 bg-teal-50 dark:bg-teal-900/20'
        : 'border-warm-200 dark:border-warm-700 hover:border-warm-300 dark:hover:border-warm-600 bg-white dark:bg-warm-800'
    }`;

  return (
    <>
      <div className="fixed inset-0 bg-black/50 z-[90]" onClick={onClose} aria-hidden="true" />
      <div
        role="dialog"
        aria-modal="true"
        aria-labelledby={titleId}
        className="fixed left-1/2 top-1/2 z-[91] -translate-x-1/2 -translate-y-1/2 w-[92vw] max-w-md bg-white dark:bg-warm-800 rounded-lg shadow-xl flex flex-col max-h-[90vh]"
      >
        <div className="flex items-center justify-between px-4 h-12 border-b border-warm-200 dark:border-warm-700 shrink-0">
          <span id={titleId} className="font-semibold text-navy-950 dark:text-warm-100">
            {t('export.title')}
          </span>
          <button
            type="button"
            onClick={onClose}
            aria-label={t('common.close')}
            className="flex cursor-pointer items-center justify-center w-9 h-9 -mr-2 rounded hover:bg-warm-100 dark:hover:bg-warm-700 transition-colors"
          >
            <CloseIcon className="w-5 h-5 text-warm-700 dark:text-warm-300" />
          </button>
        </div>

        <div className="p-4 space-y-3 overflow-y-auto">
          <button
            type="button"
            onClick={() => setMode('filters')}
            className={cardClass(mode === 'filters')}
          >
            <div className="font-medium text-navy-950 dark:text-warm-100">
              {t('export.modeFilters')}
            </div>
            <div className="text-xs text-warm-500 dark:text-warm-400 mt-1">
              {t('export.modeFiltersHint')}
            </div>
          </button>

          <button
            type="button"
            onClick={() => setMode('list')}
            className={cardClass(mode === 'list')}
          >
            <div className="font-medium text-navy-950 dark:text-warm-100">
              {t('export.modeList')}
            </div>
            <div className="text-xs text-warm-500 dark:text-warm-400 mt-1">
              {t('export.modeListHint')}
            </div>
          </button>

          {mode === 'list' && (
            <div className="flex flex-col gap-2 pt-1">
              <span className="text-xs font-medium text-warm-600 dark:text-warm-300">
                {t('export.listLabel')}
              </span>
              <div className="flex flex-col gap-1.5">
                {postcodes.map((value, idx) => (
                  <div key={idx} className="flex items-center gap-1.5">
                    <input
                      ref={(el) => {
                        inputRefs.current[idx] = el;
                      }}
                      type="text"
                      value={value}
                      onChange={(e) => updateAt(idx, e.target.value)}
                      onKeyDown={(e) => handleInputKeyDown(e, idx)}
                      placeholder={t('export.listPlaceholder')}
                      autoComplete="off"
                      spellCheck={false}
                      className="flex-1 rounded border border-warm-200 dark:border-warm-700 bg-white dark:bg-warm-900 px-3 py-1.5 text-sm text-navy-950 dark:text-warm-100 font-mono uppercase placeholder:normal-case placeholder:font-sans placeholder:text-warm-400 focus:outline-none focus:border-teal-500"
                    />
                    <button
                      type="button"
                      onClick={() => removeAt(idx)}
                      disabled={postcodes.length === 1 && !value}
                      aria-label={t('export.removeRow')}
                      className="flex cursor-pointer items-center justify-center w-8 h-8 rounded text-warm-500 hover:text-warm-700 hover:bg-warm-100 dark:hover:bg-warm-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
                    >
                      <CloseIcon className="w-4 h-4" />
                    </button>
                  </div>
                ))}
              </div>
              <button
                type="button"
                onClick={addRow}
                className="self-start flex cursor-pointer items-center gap-1 text-sm text-teal-700 dark:text-teal-300 hover:text-teal-800 dark:hover:text-teal-200 mt-0.5"
              >
                <span aria-hidden="true" className="text-base leading-none">
                  +
                </span>
                {t('export.addRow')}
              </button>
              <div className="text-xs text-warm-500 dark:text-warm-400">
                {t('export.listCount', { count: cleaned.length })}
              </div>
            </div>
          )}
        </div>

        <div className="px-4 py-3 border-t border-warm-200 dark:border-warm-700 shrink-0">
          <button
            type="button"
            onClick={handleSubmit}
            disabled={!canSubmit}
            className="w-full flex cursor-pointer items-center justify-center gap-2 px-4 py-2 rounded bg-teal-600 hover:bg-teal-700 text-white text-sm font-semibold disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
          >
            {exporting ? (
              <SpinnerIcon className="w-4 h-4 animate-spin" />
            ) : (
              <DownloadIcon className="w-4 h-4" />
            )}
            {exporting ? t('header.exporting') : t('header.exportLabel')}
          </button>
        </div>
      </div>
    </>
  );
}
