"use client";

import { useCallback, useEffect, useState } from "react";
import { withBase } from "@/lib/basePath";
import type { AppEntry, AppStatus } from "@/lib/registry";

type PublicUser = { email: string; name: string; allowedApps: string[]; admin: boolean; hasPassword: boolean };

const BLANK_APP: AppEntry = { slug: "", title: "", description: "", path: "", status: "active", roles: [] };
const BLANK_USER = { email: "", name: "", allowedApps: [] as string[], admin: false, password: "" };

// Same-origin fetch (session cookie travels automatically); throws on non-2xx.
async function send<T>(url: string, init?: RequestInit): Promise<T> {
  const r = await fetch(withBase(url), { cache: "no-store", ...init });
  const d = await r.json().catch(() => ({}));
  if (!r.ok) throw new Error(d.error || `Request failed (${r.status})`);
  return d as T;
}

export default function AdminPage() {
  const [apps, setApps] = useState<AppEntry[]>([]);
  const [users, setUsers] = useState<PublicUser[]>([]);
  const [msg, setMsg] = useState<{ kind: "ok" | "err"; text: string } | null>(null);
  const [busy, setBusy] = useState(false);

  const [appForm, setAppForm] = useState<AppEntry>(BLANK_APP);
  const [appEditing, setAppEditing] = useState(false);
  const [userForm, setUserForm] = useState(BLANK_USER);
  const [userEditing, setUserEditing] = useState(false);

  const load = useCallback(async () => {
    try {
      const [a, u] = await Promise.all([
        send<{ apps: AppEntry[] }>("/api/apps"),
        send<{ users: PublicUser[] }>("/api/users"),
      ]);
      setApps(a.apps || []);
      setUsers(u.users || []);
    } catch (e) {
      setMsg({ kind: "err", text: (e as Error).message });
    }
  }, []);
  useEffect(() => { load(); }, [load]);

  function ok(text: string) { setMsg({ kind: "ok", text }); }
  function err(e: unknown) { setMsg({ kind: "err", text: (e as Error).message }); }

  // ── Apps ──────────────────────────────────────────────────────────────────
  async function saveApp() {
    setBusy(true); setMsg(null);
    try {
      const { apps } = await send<{ apps: AppEntry[] }>("/api/apps", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(appForm) });
      setApps(apps); setAppForm(BLANK_APP); setAppEditing(false); ok(`Saved app “${appForm.title}”.`);
    } catch (e) { err(e); } finally { setBusy(false); }
  }
  async function removeApp(slug: string) {
    if (!confirm(`Remove app “${slug}”?`)) return;
    setBusy(true); setMsg(null);
    try { const { apps } = await send<{ apps: AppEntry[] }>(`/api/apps?slug=${encodeURIComponent(slug)}`, { method: "DELETE" }); setApps(apps); ok(`Removed “${slug}”.`); }
    catch (e) { err(e); } finally { setBusy(false); }
  }

  // ── Users ─────────────────────────────────────────────────────────────────
  async function saveUser() {
    setBusy(true); setMsg(null);
    try {
      const body: Record<string, unknown> = { email: userForm.email, name: userForm.name, allowedApps: userForm.allowedApps, admin: userForm.admin };
      if (userForm.password) body.password = userForm.password;
      const { users } = await send<{ users: PublicUser[] }>("/api/users", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body) });
      setUsers(users); setUserForm(BLANK_USER); setUserEditing(false); ok(`Saved user “${userForm.email}”.`);
    } catch (e) { err(e); } finally { setBusy(false); }
  }
  async function removeUser(email: string) {
    if (!confirm(`Remove user “${email}”?`)) return;
    setBusy(true); setMsg(null);
    try { const { users } = await send<{ users: PublicUser[] }>(`/api/users?email=${encodeURIComponent(email)}`, { method: "DELETE" }); setUsers(users); ok(`Removed “${email}”.`); }
    catch (e) { err(e); } finally { setBusy(false); }
  }
  function toggleApp(slug: string) {
    setUserForm((f) => ({ ...f, allowedApps: f.allowedApps.includes(slug) ? f.allowedApps.filter((s) => s !== slug) : [...f.allowedApps, slug] }));
  }

  return (
    <>
      <h1 className="page-title">Admin</h1>
      <p className="page-sub">Manage the app directory and who can access which apps.</p>
      {msg && <div className={`notice ${msg.kind}`}>{msg.text}</div>}

      {/* Users */}
      <h2 className="page-title" style={{ fontSize: 18, marginTop: 24 }}>Users &amp; access</h2>
      <div className="panel">
        <strong>{userEditing ? `Edit ${userForm.email}` : "Add a user"}</strong>
        <label className="label">Email</label>
        <input className="input" value={userForm.email} disabled={userEditing} placeholder="user@digt.ch"
          onChange={(e) => setUserForm((f) => ({ ...f, email: e.target.value }))} />
        <label className="label">Name</label>
        <input className="input" value={userForm.name} placeholder="Jane Doe"
          onChange={(e) => setUserForm((f) => ({ ...f, name: e.target.value }))} />
        <label className="label">Allowed apps</label>
        <div className="row">
          {apps.length === 0 && <span className="page-sub">No apps yet — add one below.</span>}
          {apps.map((a) => (
            <label key={a.slug} className="row" style={{ gap: 6 }}>
              <input type="checkbox" checked={userForm.allowedApps.includes(a.slug)} onChange={() => toggleApp(a.slug)} />
              {a.slug}
            </label>
          ))}
        </div>
        <label className="row" style={{ gap: 6, marginTop: 12 }}>
          <input type="checkbox" checked={userForm.admin} onChange={(e) => setUserForm((f) => ({ ...f, admin: e.target.checked }))} />
          Admin (manage the hub + access all apps)
        </label>
        <label className="label">{userEditing ? "Set/replace password (optional)" : "Local password (optional — they can also use Google)"}</label>
        <input className="input" type="password" value={userForm.password} autoComplete="new-password"
          onChange={(e) => setUserForm((f) => ({ ...f, password: e.target.value }))} />
        <div className="row" style={{ marginTop: 16 }}>
          <button className="btn primary" onClick={saveUser} disabled={busy}>{userEditing ? "Save user" : "Add user"}</button>
          {userEditing && <button className="btn" onClick={() => { setUserForm(BLANK_USER); setUserEditing(false); }} disabled={busy}>Cancel</button>}
        </div>
      </div>
      <ul className="admin-list">
        {users.map((u) => (
          <li key={u.email} className="admin-item">
            {u.admin && <span className="badge active">admin</span>}
            <div className="meta">
              <strong>{u.name}</strong>
              <small>{u.email} · {u.admin ? "all apps" : (u.allowedApps.join(", ") || "no apps")} {u.hasPassword ? "· password" : ""}</small>
            </div>
            <button className="btn" disabled={busy} onClick={() => { setUserForm({ email: u.email, name: u.name, allowedApps: u.allowedApps, admin: u.admin, password: "" }); setUserEditing(true); window.scrollTo({ top: 0, behavior: "smooth" }); }}>Edit</button>
            <button className="btn danger" disabled={busy} onClick={() => removeUser(u.email)}>Remove</button>
          </li>
        ))}
      </ul>

      {/* Apps */}
      <h2 className="page-title" style={{ fontSize: 18, marginTop: 32 }}>App directory</h2>
      <div className="panel">
        <strong>{appEditing ? `Edit ${appForm.slug}` : "Add an app"}</strong>
        <label className="label">Slug (kebab-case, unique)</label>
        <input className="input" value={appForm.slug} disabled={appEditing} placeholder="invoice-ocr"
          onChange={(e) => setAppForm((f) => ({ ...f, slug: e.target.value }))} />
        <label className="label">Title</label>
        <input className="input" value={appForm.title} placeholder="Invoice OCR" onChange={(e) => setAppForm((f) => ({ ...f, title: e.target.value }))} />
        <label className="label">Description</label>
        <input className="input" value={appForm.description} onChange={(e) => setAppForm((f) => ({ ...f, description: e.target.value }))} />
        <label className="label">Path / URL</label>
        <input className="input" value={appForm.path} placeholder="/invoice-ocr" onChange={(e) => setAppForm((f) => ({ ...f, path: e.target.value }))} />
        <label className="label">Status</label>
        <select value={appForm.status} onChange={(e) => setAppForm((f) => ({ ...f, status: e.target.value as AppStatus }))}>
          <option value="active">active</option><option value="wip">wip</option><option value="offline">offline</option>
        </select>
        <div className="row" style={{ marginTop: 16 }}>
          <button className="btn primary" onClick={saveApp} disabled={busy}>{appEditing ? "Save app" : "Add app"}</button>
          {appEditing && <button className="btn" onClick={() => { setAppForm(BLANK_APP); setAppEditing(false); }} disabled={busy}>Cancel</button>}
        </div>
      </div>
      <ul className="admin-list">
        {apps.map((a) => (
          <li key={a.slug} className="admin-item">
            <span className={`badge ${a.status}`}>{a.status}</span>
            <div className="meta"><strong>{a.title}</strong><small>{a.slug} · {a.path}</small></div>
            <button className="btn" disabled={busy} onClick={() => { setAppForm(a); setAppEditing(true); window.scrollTo({ top: 0, behavior: "smooth" }); }}>Edit</button>
            <button className="btn danger" disabled={busy} onClick={() => removeApp(a.slug)}>Remove</button>
          </li>
        ))}
      </ul>
    </>
  );
}
