import React, { useEffect, useMemo, useState } from 'react';
import { createPortal } from 'react-dom';

import { DEFAULT_NPC_GROUP_COLOR } from '../../shared/npcs/npcGroups';
import type { ProjectNpcGroup } from '../../shared/types';
import editorStyles from '../editor/EditorApp.module.css';
import { useEditorI18n } from '../editor/i18n/EditorI18nContext';
import { Button, Input } from '../shared/ui/controls';

import styles from './NpcGroupModal.module.css';

type NpcGroupModalProps = {
  open: boolean;
  initial: ProjectNpcGroup | null;
  siblingNames: string[];
  onClose: () => void;
  onSave: (input: { name: string; color: string }) => Promise<void>;
};

function normalizeName(input: string): string {
  return input.trim().toLowerCase();
}

export function NpcGroupModal({ open, initial, siblingNames, onClose, onSave }: NpcGroupModalProps) {
  const { t } = useEditorI18n();
  const [name, setName] = useState('');
  const [color, setColor] = useState(DEFAULT_NPC_GROUP_COLOR);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!open) return;
    setName(initial?.name ?? '');
    setColor(initial?.color ?? DEFAULT_NPC_GROUP_COLOR);
    setSaving(false);
    setError(null);
  }, [initial, open]);

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

  const trimmed = name.trim();
  const nameOk = trimmed.length >= 1;
  const nameDup = useMemo(() => {
    if (!nameOk) return false;
    const key = normalizeName(trimmed);
    const except = normalizeName(initial?.name ?? '');
    return siblingNames.some((n) => {
      const nk = normalizeName(n);
      return nk === key && nk !== except;
    });
  }, [initial?.name, nameOk, siblingNames, trimmed]);

  const canSave = nameOk && !nameDup && !saving;

  if (!open) return null;

  return createPortal(
    <>
      <button
        type="button"
        aria-label={t('common.close')}
        onClick={onClose}
        className={editorStyles.modalBackdrop}
      />
      <div role="dialog" aria-modal="true" className={editorStyles.modalDialog}>
        <div className={editorStyles.modalHeader}>
          <div className={editorStyles.modalTitle}>{initial ? t('npcs.editGroup') : t('npcs.addGroup')}</div>
          <button
            type="button"
            aria-label={t('common.close')}
            onClick={onClose}
            className={editorStyles.modalClose}
          >
            ×
          </button>
        </div>

        <div className={editorStyles.fieldGrid}>
          <div className={editorStyles.fieldLabel}>{t('npcs.groupName')}</div>
          <div className={styles.nameColorRow}>
            <input
              type="color"
              className={styles.colorInput}
              value={color}
              onChange={(e) => setColor(e.target.value)}
              aria-label={t('npcs.groupColor')}
            />
            <Input value={name} onChange={setName} placeholder={t('npcs.groupName')} />
          </div>
          {!nameOk ? <div className={editorStyles.fieldError}>{t('npcs.groupNameRequired')}</div> : null}
          {nameDup ? <div className={editorStyles.fieldError}>{t('npcs.groupNameDup')}</div> : null}
        </div>

        {error ? <div className={editorStyles.fieldError}>{error}</div> : null}

        <div className={editorStyles.modalFooter}>
          <Button onClick={onClose} disabled={saving}>
            {t('common.cancel')}
          </Button>
          <Button
            variant="primary"
            disabled={!canSave}
            onClick={() => {
              if (!canSave) return;
              void (async () => {
                setSaving(true);
                setError(null);
                try {
                  await onSave({ name: trimmed, color });
                  onClose();
                } catch (e) {
                  setError(e instanceof Error ? e.message : String(e));
                } finally {
                  setSaving(false);
                }
              })();
            }}
          >
            {t('common.save')}
          </Button>
        </div>
      </div>
    </>,
    document.body,
  );
}
