// Admin Console — superadmin control over the user base and subscriptions.
// Gated on data.isAdmin (server enforces /api/admin/* independently).

const ADMIN_STATUSES = [
  { id: "active", label: "Active", cls: "green" },
  { id: "trialing", label: "Trial", cls: "info" },
  { id: "comped", label: "Comped", cls: "purple" },
  { id: "past_due", label: "Past due", cls: "warn" },
  { id: "canceled", label: "Canceled", cls: "danger" }
];
const ADMIN_STATUS_MAP = Object.fromEntries(ADMIN_STATUSES.map((s) => [s.id, s]));

function adminFmtDate(value) {
  if (!value) return "—";
  try { return new Date(value).toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric" }); }
  catch (e) { return "—"; }
}
function adminRelative(value) {
  if (!value) return "never";
  const diff = Date.now() - new Date(value).getTime();
  if (isNaN(diff)) return "—";
  const day = 86400000;
  if (diff < day) return "today";
  if (diff < 2 * day) return "yesterday";
  if (diff < 30 * day) return `${Math.floor(diff / day)}d ago`;
  return adminFmtDate(value);
}

function AdminPage() {
  const hub = useClearCast();
  const data = hub.data || {};
  const [tab, setTab] = React.useState("overview");
  const [overview, setOverview] = React.useState(null);
  const [users, setUsers] = React.useState(null);
  const [plans, setPlans] = React.useState([]);
  const [me, setMe] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState("");
  const [busyId, setBusyId] = React.useState("");
  const [query, setQuery] = React.useState("");
  const [showCreate, setShowCreate] = React.useState(false);
  const [nu, setNu] = React.useState({ email: "", password: "", name: "", plan: "free" });

  const planPrice = React.useMemo(() => Object.fromEntries((plans || []).map((p) => [p.id, p.price])), [plans]);

  const loadOverview = React.useCallback(async () => {
    try { setOverview(await ClearCastAPI.adminOverview()); } catch (e) { /* keep prior */ }
  }, []);

  const load = React.useCallback(async () => {
    setLoading(true); setError("");
    try {
      const [ov, us] = await Promise.all([ClearCastAPI.adminOverview(), ClearCastAPI.adminUsers()]);
      setOverview(ov);
      setUsers(us.users || []);
      setPlans(us.plans || []);
      setMe(us.me || null);
    } catch (e) { setError(e.message || "Could not load admin data."); }
    finally { setLoading(false); }
  }, []);
  React.useEffect(() => { load(); }, [load]);

  if (!data.isAdmin) {
    return <div className="page"><div className="card" style={{ padding: 24 }}><b>Admin access required.</b><div className="muted" style={{ marginTop: 6, fontSize: 13 }}>Your account isn't an administrator.</div></div></div>;
  }

  const patchRow = (id, patch) => setUsers((us) => (us || []).map((u) => (u.id === id ? { ...u, ...patch } : u)));

  const setSub = async (u, patch) => {
    setBusyId(u.id);
    try {
      const r = await ClearCastAPI.adminSetSubscription({ userId: u.id, email: u.email, plan: patch.plan != null ? patch.plan : u.plan, status: patch.status != null ? patch.status : u.subStatus, note: patch.note != null ? patch.note : u.subNote });
      patchRow(u.id, { plan: r.subscription.plan, subStatus: r.subscription.status, subNote: r.subscription.note });
      hub.toast("Subscription updated");
      loadOverview();
    } catch (e) { hub.toast(e.message || "Update failed"); }
    finally { setBusyId(""); }
  };
  const toggleAdmin = async (u) => {
    if (u.adminLocked) { hub.toast("This admin is locked in server config and can't be changed here."); return; }
    setBusyId(u.id);
    try { await ClearCastAPI.adminSetRole(u.email, !u.isAdmin); patchRow(u.id, { isAdmin: !u.isAdmin }); hub.toast(!u.isAdmin ? `${u.email} is now an admin` : "Admin access revoked"); loadOverview(); }
    catch (e) { hub.toast(e.message || "Failed"); }
    finally { setBusyId(""); }
  };
  const toggleSuspend = async (u) => {
    setBusyId(u.id);
    try { await ClearCastAPI.adminSuspendUser(u.id, !u.banned); patchRow(u.id, { banned: !u.banned }); hub.toast(!u.banned ? "User suspended — they can't sign in" : "User reinstated"); loadOverview(); }
    catch (e) { hub.toast(e.message || "Failed"); }
    finally { setBusyId(""); }
  };
  const resetPw = async (u) => {
    const pw = window.prompt(`Set a temporary password for ${u.email} (min 8 characters). Share it with them — they can change it after signing in.`);
    if (!pw) return;
    setBusyId(u.id);
    try { await ClearCastAPI.adminSetPassword(u.id, pw); hub.toast("Temporary password set"); }
    catch (e) { hub.toast(e.message || "Failed"); }
    finally { setBusyId(""); }
  };
  const del = async (u) => {
    if (!window.confirm(`Permanently delete ${u.email}? This removes their login for good and can't be undone.`)) return;
    setBusyId(u.id);
    try { await ClearCastAPI.adminDeleteUser(u.id); setUsers((us) => (us || []).filter((x) => x.id !== u.id)); hub.toast("User deleted"); loadOverview(); }
    catch (e) { hub.toast(e.message || "Failed"); }
    finally { setBusyId(""); }
  };
  const createUser = async () => {
    if (!nu.email || nu.password.length < 8) { hub.toast("Enter an email and a password of 8+ characters"); return; }
    setBusyId("create");
    try { await ClearCastAPI.adminCreateUser(nu); hub.toast(`Created ${nu.email}`); setShowCreate(false); setNu({ email: "", password: "", name: "", plan: "free" }); await load(); }
    catch (e) { hub.toast(e.message || "Could not create user"); }
    finally { setBusyId(""); }
  };

  const filtered = (users || []).filter((u) => {
    if (!query.trim()) return true;
    const q = query.toLowerCase();
    return (u.email || "").toLowerCase().includes(q) || (u.name || "").toLowerCase().includes(q);
  });

  const StatusBadge = ({ id }) => {
    const s = ADMIN_STATUS_MAP[id] || { label: id, cls: "" };
    return <span className={`adm-status ${s.cls}`}>{s.label}</span>;
  };

  const PlanSelect = ({ u }) => (
    <select className="select adm-select" disabled={busyId === u.id} value={u.plan} onChange={(e) => setSub(u, { plan: e.target.value })}>
      {(plans || []).map((p) => <option key={p.id} value={p.id}>{p.name}{p.price ? ` · $${p.price}` : " · Free"}</option>)}
    </select>
  );
  const StatusSelect = ({ u }) => (
    <select className="select adm-select" disabled={busyId === u.id} value={u.subStatus} onChange={(e) => setSub(u, { status: e.target.value })}>
      {ADMIN_STATUSES.map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}
    </select>
  );

  return (
    <div className="page admin-page">
      <div className="admin-head">
        <div>
          <h1 style={{ fontSize: 22, fontWeight: 700, margin: 0 }}>Admin Console</h1>
          <p className="muted" style={{ margin: "4px 0 0", fontSize: 13 }}>Manage your user base and subscriptions{me ? ` · signed in as ${me}` : ""}.</p>
        </div>
        <button className="btn" onClick={load} disabled={loading}><Icon.Refresh width="14" height="14" /> Refresh</button>
      </div>

      <div className="admin-tabbar">
        {[["overview", "Overview"], ["users", "Users & Access"], ["subscriptions", "Subscriptions"]].map(([id, label]) => (
          <button key={id} className={`admin-tab ${tab === id ? "active" : ""}`} onClick={() => setTab(id)}>{label}</button>
        ))}
      </div>

      {error && <div className="card" style={{ padding: 16, borderColor: "var(--danger)", color: "var(--danger)" }}>{error}</div>}
      {loading && !users && <div className="card" style={{ padding: 24 }}>Loading admin data…</div>}

      {/* OVERVIEW */}
      {tab === "overview" && overview && (
        <>
          <div className="admin-metrics">
            <div className="admin-metric"><span>Total users</span><b>{overview.totalUsers}</b></div>
            <div className="admin-metric"><span>Active subscriptions</span><b>{overview.activeSubscriptions}</b></div>
            <div className="admin-metric accent"><span>Estimated MRR</span><b>${Number(overview.estimatedMrr || 0).toLocaleString()}</b><small>/ month</small></div>
            <div className="admin-metric"><span>New (30 days)</span><b>{overview.recentSignups}</b></div>
            <div className="admin-metric"><span>Admins</span><b>{overview.adminCount}</b></div>
            <div className="admin-metric"><span>Suspended</span><b>{overview.suspended || 0}</b></div>
          </div>
          <div className="card" style={{ padding: 20 }}>
            <h3 style={{ margin: "0 0 14px", fontSize: 15 }}>Plan distribution</h3>
            {(plans || []).map((p) => {
              const count = (overview.byPlan && overview.byPlan[p.id]) || 0;
              const pct = overview.totalUsers ? Math.round((count / overview.totalUsers) * 100) : 0;
              return (
                <div key={p.id} className="admin-planrow">
                  <div className="admin-planname">{p.name} <span className="muted">{p.price ? `$${p.price}/mo` : "Free"}</span></div>
                  <div className="admin-planbar"><span style={{ width: `${pct}%` }} /></div>
                  <div className="admin-plancount">{count} · {pct}%</div>
                </div>
              );
            })}
            <div className="muted" style={{ fontSize: 12, marginTop: 12 }}>MRR is an estimate from each user's assigned plan and status (active / trial / comped count toward active). Real payment collection (Stripe) is a separate step.</div>
          </div>
        </>
      )}

      {/* USERS & ACCESS */}
      {tab === "users" && users && (
        <>
          <div className="admin-toolbar">
            <div className="admin-search"><Icon.Search width="15" height="15" /><input className="input" placeholder="Search by name or email…" value={query} onChange={(e) => setQuery(e.target.value)} /></div>
            <button className="btn btn-primary" onClick={() => setShowCreate((s) => !s)}><Icon.Plus width="14" height="14" /> Add user</button>
          </div>
          {showCreate && (
            <div className="card admin-create" style={{ padding: 16 }}>
              <div className="admin-create-grid">
                <input className="input" placeholder="Email" value={nu.email} onChange={(e) => setNu({ ...nu, email: e.target.value })} />
                <input className="input" placeholder="Name (optional)" value={nu.name} onChange={(e) => setNu({ ...nu, name: e.target.value })} />
                <input className="input" type="text" placeholder="Temp password (8+)" value={nu.password} onChange={(e) => setNu({ ...nu, password: e.target.value })} />
                <select className="select" value={nu.plan} onChange={(e) => setNu({ ...nu, plan: e.target.value })}>{(plans || []).map((p) => <option key={p.id} value={p.id}>{p.name}</option>)}</select>
                <button className="btn btn-primary" disabled={busyId === "create"} onClick={createUser}>{busyId === "create" ? "Creating…" : "Create"}</button>
              </div>
              <div className="muted" style={{ fontSize: 11.5, marginTop: 8 }}>Creates a confirmed account they can sign in with immediately.</div>
            </div>
          )}
          <div className="card admin-table-wrap" style={{ padding: 0 }}>
            <div className="admin-table users">
              <div className="admin-trow admin-thead">
                <div>User</div><div>Plan</div><div>Status</div><div>Joined</div><div>Last active</div><div>Actions</div>
              </div>
              {filtered.map((u) => (
                <div key={u.id} className={`admin-trow ${u.banned ? "is-suspended" : ""}`}>
                  <div className="admin-user">
                    <div className="admin-avatar">{(u.name || u.email || "?").slice(0, 1).toUpperCase()}</div>
                    <div style={{ minWidth: 0 }}>
                      <div className="admin-uname">{u.name || "—"} {u.isAdmin && <span className="adm-status purple" title="Administrator">Admin</span>}{u.banned && <span className="adm-status danger">Suspended</span>}</div>
                      <div className="admin-uemail">{u.email}</div>
                    </div>
                  </div>
                  <div><PlanSelect u={u} /></div>
                  <div><StatusSelect u={u} /></div>
                  <div className="admin-muted">{adminFmtDate(u.createdAt)}</div>
                  <div className="admin-muted">{adminRelative(u.lastSignInAt)}</div>
                  <div className="admin-actions">
                    <button className="btn btn-ghost btn-sm" disabled={busyId === u.id || u.adminLocked} onClick={() => toggleAdmin(u)} title={u.isAdmin ? "Revoke admin" : "Make admin"}>{u.isAdmin ? "Revoke admin" : "Make admin"}</button>
                    <button className="btn btn-ghost btn-sm" disabled={busyId === u.id} onClick={() => toggleSuspend(u)}>{u.banned ? "Reinstate" : "Suspend"}</button>
                    <button className="btn btn-ghost btn-sm" disabled={busyId === u.id} onClick={() => resetPw(u)}>Reset password</button>
                    <button className="btn btn-ghost btn-sm admin-danger" disabled={busyId === u.id} onClick={() => del(u)}><Icon.Trash width="13" height="13" /></button>
                  </div>
                </div>
              ))}
              {!filtered.length && <div style={{ padding: 24, textAlign: "center" }} className="muted">No users match "{query}".</div>}
            </div>
          </div>
        </>
      )}

      {/* SUBSCRIPTIONS */}
      {tab === "subscriptions" && users && overview && (
        <>
          <div className="admin-metrics">
            <div className="admin-metric accent"><span>Estimated MRR</span><b>${Number(overview.estimatedMrr || 0).toLocaleString()}</b><small>/ month</small></div>
            <div className="admin-metric"><span>Active subscriptions</span><b>{overview.activeSubscriptions}</b></div>
            <div className="admin-metric"><span>Paying (non-free)</span><b>{(users || []).filter((u) => u.plan !== "free" && ["active", "trialing", "comped", "past_due"].includes(u.subStatus)).length}</b></div>
          </div>
          <div className="admin-toolbar">
            <div className="admin-search"><Icon.Search width="15" height="15" /><input className="input" placeholder="Search subscriptions…" value={query} onChange={(e) => setQuery(e.target.value)} /></div>
          </div>
          <div className="card admin-table-wrap" style={{ padding: 0 }}>
            <div className="admin-table subs">
              <div className="admin-trow admin-thead"><div>User</div><div>Plan</div><div>Status</div><div>MRR</div><div>Note</div></div>
              {filtered.map((u) => (
                <div key={u.id} className="admin-trow">
                  <div className="admin-user">
                    <div className="admin-avatar">{(u.name || u.email || "?").slice(0, 1).toUpperCase()}</div>
                    <div style={{ minWidth: 0 }}><div className="admin-uname">{u.name || "—"}</div><div className="admin-uemail">{u.email}</div></div>
                  </div>
                  <div><PlanSelect u={u} /></div>
                  <div><StatusSelect u={u} /></div>
                  <div className="admin-mrr">{["active", "trialing", "comped"].includes(u.subStatus) ? `$${planPrice[u.plan] || 0}` : <span className="muted">$0</span>}</div>
                  <div>
                    <input className="input adm-note" placeholder="Add a note…" defaultValue={u.subNote}
                      onBlur={(e) => { if (e.target.value !== u.subNote) setSub(u, { note: e.target.value }); }} />
                  </div>
                </div>
              ))}
              {!filtered.length && <div style={{ padding: 24, textAlign: "center" }} className="muted">No matches.</div>}
            </div>
          </div>
        </>
      )}
    </div>
  );
}

window.AdminPage = AdminPage;
