import { useEffect, useState, type ReactNode } from 'react';
import {
  FormProvider,
  useForm,
  type DefaultValues,
  type FieldValues,
  type Resolver,
} from 'react-hook-form';

type Props<T extends FieldValues> = {
  section: string;
  defaultValues: DefaultValues<T>;
  resolver: Resolver<T>;
  children: ReactNode;
};

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

export function FormShell<T extends FieldValues>({
  section,
  defaultValues,
  resolver,
  children,
}: Props<T>) {
  const methods = useForm<T>({ defaultValues, resolver, mode: 'onBlur' });
  const [status, setStatus] = useState<Status>({ kind: 'idle' });

  const onSubmit = methods.handleSubmit(async (values) => {
    setStatus({ kind: 'saving' });
    try {
      const res = await fetch(`/api/content/${section}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(values),
      });
      const data = await res.json();
      if (!res.ok) {
        setStatus({ kind: 'error', message: data.message || data.error || 'erreur' });
        return;
      }
      setStatus({ kind: 'saved' });
      methods.reset(values as DefaultValues<T>);
      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();
        onSubmit();
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onSubmit]);

  const dirty = methods.formState.isDirty;

  return (
    <FormProvider {...methods}>
      <form onSubmit={onSubmit} className="space-y-6">
        <div className="sticky top-16 z-30 -mx-4 px-4 py-3 bg-[rgba(10,10,15,0.85)] backdrop-blur-xl border-b border-[color:var(--color-border)] flex flex-wrap items-center justify-between gap-2">
          <div className="flex items-center gap-3 min-w-0">
            <Pill status={status} dirty={dirty} />
          </div>
          <div className="flex flex-wrap items-center gap-2">
            {dirty && (
              <button
                type="button"
                onClick={() => methods.reset()}
                className="font-mono text-xs uppercase tracking-widest text-[color:var(--color-text-muted)] hover:text-[color:var(--color-magenta)] px-3 py-1.5 transition-colors"
              >
                annuler
              </button>
            )}
            <button
              type="submit"
              disabled={status.kind === 'saving'}
              className="btn-primary text-xs py-1.5 disabled:opacity-50"
            >
              {status.kind === 'saving' ? 'enregistrement…' : 'enregistrer'}
            </button>
          </div>
        </div>

        <div className="space-y-8">{children}</div>

        <div className="pt-6 border-t border-[color:var(--color-border)] flex justify-end">
          <button
            type="submit"
            disabled={status.kind === 'saving'}
            className="btn-primary disabled:opacity-50"
          >
            {status.kind === 'saving' ? 'enregistrement…' : 'enregistrer'}
          </button>
        </div>
      </form>
    </FormProvider>
  );
}

function Pill({ status, dirty }: { status: Status; dirty: boolean }) {
  if (status.kind === 'saving')
    return (
      <span className="flex items-center gap-2 font-mono text-xs uppercase tracking-widest text-[color:var(--color-acid)]">
        <span className="led led-acid animate-led-red" />
        enregistrement…
      </span>
    );
  if (status.kind === 'saved')
    return (
      <span className="sticker text-[color:var(--color-cyan)] glow-text-cyan animate-pulse-neon">
        ✓ saved
      </span>
    );
  if (status.kind === 'error')
    return (
      <span
        className="flex items-center gap-2 font-mono text-xs uppercase tracking-widest text-[color:var(--color-magenta)]"
        title={status.message}
      >
        <span className="led led-red animate-led-red" />
        ✗ {status.message.slice(0, 80)}
      </span>
    );
  if (dirty)
    return (
      <span className="flex items-center gap-2 font-mono text-xs uppercase tracking-widest text-[color:var(--color-text-muted)]">
        <span className="led" style={{ background: 'var(--color-text-muted)', boxShadow: 'none' }} />
        modifications non sauvées
      </span>
    );
  return (
    <span className="flex items-center gap-2 font-mono text-xs uppercase tracking-widest text-[color:var(--color-text-dim)]">
      <span className="led led-cyan" />
      synced
    </span>
  );
}
