'use client';

import { useCallback, useEffect, useState } from 'react';
import { formatDate } from '@/lib/format';

type Reserved = { name: string; created_at: string };

export default function AdminReservedPage() {
  const [reserved, setReserved] = useState<Reserved[]>([]);
  const [hardcoded, setHardcoded] = useState<string[]>([]);
  const [name, setName] = useState('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [notice, setNotice] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch('/api/admin/reserved');
      if (!res.ok) {
        const b = (await res.json().catch(() => ({}))) as { error?: string };
        throw new Error(b.error ?? `Request failed (${res.status})`);
      }
      const data = (await res.json()) as {
        reserved: Reserved[];
        hardcoded: string[];
      };
      setReserved(data.reserved);
      setHardcoded(data.hardcoded);
    } catch (e) {
      setError((e as Error).message);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    load();
  }, [load]);

  async function add(e: React.FormEvent) {
    e.preventDefault();
    const value = name.trim().toLowerCase();
    if (!value) return;
    setBusy(true);
    setError(null);
    setNotice(null);
    try {
      const res = await fetch('/api/admin/reserved', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: value }),
      });
      if (!res.ok) {
        const b = (await res.json().catch(() => ({}))) as { error?: string };
        throw new Error(b.error ?? `Request failed (${res.status})`);
      }
      setName('');
      setNotice(`Reserved '${value}'`);
      await load();
    } catch (e) {
      setError((e as Error).message);
    } finally {
      setBusy(false);
    }
  }

  async function remove(n: string) {
    if (!window.confirm(`Remove reserved subdomain '${n}'?`)) return;
    setBusy(true);
    setError(null);
    setNotice(null);
    try {
      const res = await fetch(
        `/api/admin/reserved?name=${encodeURIComponent(n)}`,
        { method: 'DELETE' },
      );
      if (!res.ok) {
        const b = (await res.json().catch(() => ({}))) as { error?: string };
        throw new Error(b.error ?? `Request failed (${res.status})`);
      }
      setNotice(`Removed '${n}'`);
      await load();
    } catch (e) {
      setError((e as Error).message);
    } finally {
      setBusy(false);
    }
  }

  return (
    <div>
      <h1>Reserved subdomains</h1>

      <div className="card">
        <h2>Add reserved subdomain</h2>
        <form onSubmit={add}>
          <div className="row">
            <input
              type="text"
              value={name}
              onChange={(e) => setName(e.target.value.toLowerCase())}
              placeholder="e.g. status"
              autoCapitalize="none"
              autoCorrect="off"
              spellCheck={false}
              style={{ maxWidth: 280 }}
            />
            <button type="submit" className="btn-sm" disabled={busy || !name}>
              Add
            </button>
          </div>
        </form>
        {error && <p className="error">{error}</p>}
        {notice && <p className="success">{notice}</p>}
      </div>

      <div className="card">
        <h2>Database reserved</h2>
        {loading ? (
          <p className="muted">Loading…</p>
        ) : reserved.length === 0 ? (
          <p className="muted">None reserved in the database.</p>
        ) : (
          <div className="admin-table-wrap">
            <table className="admin-table">
              <thead>
                <tr>
                  <th>Name</th>
                  <th>Added</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {reserved.map((r) => (
                  <tr key={r.name}>
                    <td>{r.name}</td>
                    <td>{formatDate(r.created_at)}</td>
                    <td>
                      <button
                        type="button"
                        className="btn-danger btn-sm"
                        disabled={busy}
                        onClick={() => remove(r.name)}
                      >
                        Remove
                      </button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      <div className="card">
        <h2>Built-in reserved</h2>
        <p className="muted">
          These are hardcoded in the app and always reserved (cannot be removed
          here).
        </p>
        <div className="row" style={{ flexWrap: 'wrap', gap: 6 }}>
          {hardcoded.map((h) => (
            <span key={h} className="badge">
              {h}
            </span>
          ))}
        </div>
      </div>
    </div>
  );
}
