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

import { ipcChannels } from '../../../shared/ipc/contracts';
import { EULA_CURRENT_VERSION } from '../../../shared/license/eulaVersion';
import type { LicenseSnapshot } from '../../../shared/license/licenseSnapshot';
import { EULA_RU_MARKDOWN } from '../../legal/eulaRu';
import { getDndApi } from '../../shared/dndApi';
import { Button } from '../../shared/ui/controls';
import styles from '../EditorApp.module.css';

type LicenseTokenModalProps = {
  open: boolean;
  onClose: () => void;
  onSaved: () => void;
};

export function LicenseTokenModal({ open, onClose, onSaved }: LicenseTokenModalProps) {
  const [token, setToken] = useState('');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!open) return;
    setToken('');
    setSaving(false);
    setError(null);
  }, [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]);

  if (!open) return null;

  return createPortal(
    <>
      <button type="button" aria-label="Закрыть" onClick={onClose} className={styles.modalBackdrop} />
      <div role="dialog" aria-modal="true" className={styles.modalDialog}>
        <div className={styles.modalHeader}>
          <div className={styles.modalTitle}>Указать ключ</div>
          <button type="button" aria-label="Закрыть" onClick={onClose} className={styles.modalClose}>
            ×
          </button>
        </div>
        <div className={styles.fieldGrid}>
          <div className={styles.fieldLabel}>КЛЮЧ</div>
          <textarea
            className={styles.licenseTextarea}
            value={token}
            onChange={(e) => setToken(e.target.value)}
            placeholder="Продуктовый ключ DND-..."
            spellCheck={false}
          />
        </div>
        {error ? <div className={styles.fieldError}>{error}</div> : null}
        <div className={styles.modalFooter}>
          <Button onClick={onClose} disabled={saving}>
            Отмена
          </Button>
          <Button
            variant="primary"
            disabled={saving || !token.trim()}
            onClick={() => {
              void (async () => {
                setSaving(true);
                setError(null);
                try {
                  await getDndApi().invoke(ipcChannels.license.setToken, { token: token.trim() });
                  onSaved();
                  onClose();
                } catch (e) {
                  setError(e instanceof Error ? e.message : String(e));
                } finally {
                  setSaving(false);
                }
              })();
            }}
          >
            Сохранить
          </Button>
        </div>
      </div>
    </>,
    document.body,
  );
}

type EulaModalProps = {
  open: boolean;
  onClose: () => void;
  onAccepted: () => void;
};

export function EulaModal({ open, onClose, onAccepted }: EulaModalProps) {
  const [saving, setSaving] = useState(false);

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

  if (!open) return null;

  return createPortal(
    <>
      <button type="button" aria-label="Закрыть" onClick={onClose} className={styles.modalBackdrop} />
      <div role="dialog" aria-modal="true" className={styles.modalDialog}>
        <div className={styles.modalHeader}>
          <div className={styles.modalTitle}>Лицензионное соглашение</div>
          <button type="button" aria-label="Закрыть" onClick={onClose} className={styles.modalClose}>
            ×
          </button>
        </div>
        <div className={styles.eulaScroll}>{EULA_RU_MARKDOWN}</div>
        <div className={styles.modalFooter}>
          <Button onClick={onClose} disabled={saving}>
            Не принимаю
          </Button>
          <Button
            variant="primary"
            disabled={saving}
            onClick={() => {
              void (async () => {
                setSaving(true);
                try {
                  await getDndApi().invoke(ipcChannels.license.acceptEula, {
                    version: EULA_CURRENT_VERSION,
                  });
                  onAccepted();
                  onClose();
                } finally {
                  setSaving(false);
                }
              })();
            }}
          >
            Принимаю условия
          </Button>
        </div>
      </div>
    </>,
    document.body,
  );
}

type LicenseAboutModalProps = {
  open: boolean;
  onClose: () => void;
  snapshot: LicenseSnapshot | null;
};

function reasonLabel(reason: LicenseSnapshot['reason']): string {
  switch (reason) {
    case 'ok':
      return 'Активна';
    case 'none':
      return 'Ключ не указан';
    case 'expired':
      return 'Срок действия истёк';
    case 'bad_signature':
      return 'Недействительная подпись';
    case 'bad_payload':
      return 'Неверный формат токена';
    case 'malformed':
      return 'Повреждённый токен';
    case 'not_yet_valid':
      return 'Ещё не действует';
    case 'wrong_device':
      return 'Другой привязанный компьютер';
    case 'revoked_remote':
      return 'Отозвана на сервере';
    default:
      return reason;
  }
}

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

  if (!open) return null;

  const expText =
    snapshot?.summary?.exp != null
      ? new Date(snapshot.summary.exp * 1000).toLocaleString('ru-RU', {
          dateStyle: 'long',
          timeStyle: 'short',
        })
      : '—';

  return createPortal(
    <>
      <button type="button" aria-label="Закрыть" onClick={onClose} className={styles.modalBackdrop} />
      <div role="dialog" aria-modal="true" className={styles.modalDialog}>
        <div className={styles.modalHeader}>
          <div className={styles.modalTitle}>О лицензии</div>
          <button type="button" aria-label="Закрыть" onClick={onClose} className={styles.modalClose}>
            ×
          </button>
        </div>
        {snapshot?.devSkip ? (
          <div className={styles.fieldError}>
            Режим разработки: проверка лицензии отключена (DND_SKIP_LICENSE).
          </div>
        ) : null}
        <div className={styles.fieldGrid}>
          <div className={styles.fieldLabel}>СТАТУС</div>
          <div>{snapshot ? reasonLabel(snapshot.reason) : '—'}</div>
        </div>
        {snapshot?.summary ? (
          <>
            <div className={styles.fieldGrid}>
              <div className={styles.fieldLabel}>ПРОДУКТ</div>
              <div>{snapshot.summary.pid}</div>
            </div>
            <div className={styles.fieldGrid}>
              <div className={styles.fieldLabel}>ID ЛИЦЕНЗИИ</div>
              <div style={{ wordBreak: 'break-all' }}>{snapshot.summary.sub}</div>
            </div>
            <div className={styles.fieldGrid}>
              <div className={styles.fieldLabel}>ОКОНЧАНИЕ</div>
              <div>{expText}</div>
            </div>
            <div className={styles.fieldGrid}>
              <div className={styles.fieldLabel}>УСТРОЙСТВО</div>
              <div style={{ wordBreak: 'break-all' }}>{snapshot.deviceId}</div>
            </div>
          </>
        ) : (
          <div className={styles.muted}>Нет данных лицензии.</div>
        )}
        <div className={styles.modalFooter}>
          <Button variant="primary" onClick={onClose}>
            Закрыть
          </Button>
        </div>
      </div>
    </>,
    document.body,
  );
}
