import { useEffect, useRef, useState } from 'react';

type Props = {
  section: string;
  initial: unknown;
};

type Status =
  | { kind: 'idle' }
  | { kind: 'saving' }
  | { kind: 'saved' }
  | { kind: 'error'; message: string }
  | { kind: 'invalid' };

export function RawJsonEditor({ section, initial }: Props) {
  const [value, setValue] = useState(() => JSON.stringify(initial, null, 2));
  const [status, setStatus] = useState<Status>({ kind: 'idle' });
  const taRef = useRef<HTMLTextAreaElement>(null);

  const format = () => {
    try {
      const parsed = JSON.parse(value);
      setValue(JSON.stringify(parsed, null, 2));
      setStatus({ kind: 'idle' });
    } catch {
      setStatus({ kind: 'invalid' });
    }
  };

  const save = async () => {
    let body: unknown;
    try {
      body = JSON.parse(value);
    } catch {
      setStatus({ kind: 'invalid' });
      return;
    }
    setStatus({ kind: 'saving' });
    try {
      const res = await fetch(`/api/content/${section}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      });
      const data = await res.json();
      if (!res.ok) {
        setStatus({ kind: 'error', message: data.message || data.error || 'erreur' });
        return;
      }
      setStatus({ kind: 'saved' });
      setTimeout(() => setStatus({ kind: 'idle' }), 2500);
    } catch (e) {
      setStatus({ kind: 'error', message: (e as Error).message });
    }
  };

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 's') {
        e.preventDefault();
        save();
      }
    };
    const ta = taRef.current;
    ta?.addEventListener('keydown', onKey as EventListener);
    return () => ta?.removeEventListener('keydown', onKey as EventListener);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [value]);

  return (
    <div className="space-y-3">
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
        <p className="font-mono text-xs text-[color:var(--color-text-dim)]">
          Mode avancé — JSON brut, validé Zod côté serveur.
        </p>
        <div className="flex flex-wrap items-center gap-2">
          <StatusPill status={status} />
          <button type="button" onClick={format} className="btn-ghost text-xs py-1.5">
            Formater
          </button>
          <button type="button" onClick={save} className="btn-primary text-xs py-1.5">
            Enregistrer
          </button>
        </div>
      </div>
      <textarea
        ref={taRef}
        value={value}
        onChange={(e) => setValue(e.target.value)}
        spellCheck={false}
        className="w-full min-h-[400px] h-[calc(100vh-300px)] max-h-[80vh] bg-[color:var(--color-surface)] border border-[color:var(--color-border)] focus:border-[color:var(--color-cyan)] focus:outline-none p-4 rounded text-sm font-mono text-[color:var(--color-text)] resize-none"
      />
    </div>
  );
}

function StatusPill({ status }: { status: Status }) {
  if (status.kind === 'idle') return null;
  if (status.kind === 'saving')
    return (
      <span className="font-mono text-xs text-[color:var(--color-text-muted)]">
        enregistrement…
      </span>
    );
  if (status.kind === 'saved')
    return (
      <span className="font-mono text-xs text-[color:var(--color-cyan)] glow-text-cyan">
        ✓ enregistré
      </span>
    );
  if (status.kind === 'invalid')
    return (
      <span className="font-mono text-xs text-[color:var(--color-magenta)]">
        JSON invalide
      </span>
    );
  return (
    <span className="font-mono text-xs text-[color:var(--color-magenta)]" title={status.message}>
      ✗ {status.message.slice(0, 60)}
    </span>
  );
}
