'use client';

import { ReactNode, useCallback, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';

type Status = 'unknown' | 'authed' | 'denied';

/**
 * Client-side admin gate.
 *
 * 1. If `x-admin-key` is stored in sessionStorage → validate via
 *    /api/admin/verify.
 * 2. Otherwise show a key entry form (basic-auth fallback for users who
 *    prefer the `ADMIN_USER:ADMIN_KEY` header).
 *
 * The key is never written to localStorage and is cleared on a hard tab
 * close. For hardening, front the admin area with real HTTP Basic auth
 * at the reverse-proxy layer too.
 */
export default function AdminGate({ children }: { children: ReactNode }) {
  const [status, setStatus] = useState<Status>('unknown');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const router = useRouter();
  const [keyInput, setKeyInput] = useState('');

  const validate = useCallback(
    async (key: string) => {
      setBusy(true);
      setError(null);
      try {
        const res = await fetch('/api/admin/verify', {
          headers: { 'x-admin-key': key },
        });
        if (res.ok) {
          sessionStorage.setItem('mb_admin_key', key);
          setStatus('authed');
        } else {
          setStatus('denied');
          setError('Invalid admin key.');
        }
      } catch {
        setError('Network error');
      } finally {
        setBusy(false);
      }
    },
    [],
  );

  useEffect(() => {
    const stored = sessionStorage.getItem('mb_admin_key');
    if (stored) validate(stored);
    else setStatus('denied');
  }, [validate]);

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    if (keyInput.trim()) await validate(keyInput.trim());
  }

  function logout() {
    sessionStorage.removeItem('mb_admin_key');
    setStatus('denied');
    setKeyInput('');
    router.refresh();
  }

  if (status === 'authed') {
    return (
      <div className="mx-auto max-w-4xl px-4 py-8 sm:px-6">
        <div className="mb-6 flex items-center justify-between">
          <h1 className="font-display text-2xl font-bold text-ink-900">
            Admin · Settings
          </h1>
          <button
            onClick={logout}
            className="rounded-md border border-ink-300 px-3 py-1.5 text-sm text-ink-600 hover:bg-ink-100"
          >
            Sign out
          </button>
        </div>
        {children}
      </div>
    );
  }

  return (
    <div className="mx-auto max-w-md px-4 py-24">
      <div className="rounded-2xl border border-ink-200 bg-white p-8 shadow-sm">
        <h1 className="font-display text-2xl font-bold text-ink-900">Admin</h1>
        <p className="mt-1 text-sm text-ink-500">
          Enter the admin key from <code>ADMIN_API_KEY</code> (or your{' '}
          <code>USER:ADMIN_API_KEY</code> basic-auth string) to continue.
        </p>
        <form onSubmit={submit} className="mt-6 space-y-4">
          <input
            type="password"
            value={keyInput}
            onChange={(e) => setKeyInput(e.target.value)}
            placeholder="Admin key"
            autoFocus
            className="w-full rounded-lg border border-ink-300 px-3 py-2.5 text-sm focus:border-maple-600 focus:outline-none"
          />
          {error && <p className="text-sm text-red-700">{error}</p>}
          <button
            type="submit"
            disabled={busy}
            className="w-full rounded-lg bg-maple-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-maple-700 disabled:opacity-50"
          >
            {busy ? 'Verifying…' : 'Unlock'}
          </button>
        </form>
        <p className="mt-4 text-xs text-ink-400">
          Tip: keep the key in a password manager; it is only held in your
          browser session while you have this tab open.
        </p>
      </div>
    </div>
  );
}
