// Admin overlay — staff-gated. Five tabs:
//   Overview · Players · Subscriptions · Activity · Audit
//
// Staff detection in production: the session cookie carries a `staff` flag
// set server-side after verifying Discord guild role membership. In this
// prototype we read `localStorage.shovelhead.session.v1` plus a tweak.

// ── Synth admin data ─────────────────────────────────────────────────────
const ADMIN_PLAYERS_LIVE = [
  { name: "FrostByteFred",  steamId: "76561198042918233", joinedAgo: "2h 14m", tier: "outlaw",   country: "US", warns: 0, kdSession: "8/1"  },
  { name: "GravelMouth",    steamId: "76561198217004401", joinedAgo: "1h 02m", tier: null,       country: "CA", warns: 1, kdSession: "4/0"  },
  { name: "smokey_balboa",  steamId: "76561198009288176", joinedAgo: "44m",    tier: "survivor", country: "US", warns: 0, kdSession: "2/2"  },
  { name: "Hollow.Tide",    steamId: "76561198192377044", joinedAgo: "38m",    tier: "warlord",  country: "US", warns: 0, kdSession: "5/0"  },
  { name: "Mort.404",       steamId: "76561198311662091", joinedAgo: "27m",    tier: null,       country: "MX", warns: 0, kdSession: "1/3"  },
  { name: "Vinegar_Saint",  steamId: "76561198120553711", joinedAgo: "22m",    tier: null,       country: "US", warns: 0, kdSession: "0/0"  },
  { name: "Pyre_Walker",    steamId: "76561198033471128", joinedAgo: "18m",    tier: "outlaw",   country: "BR", warns: 2, kdSession: "3/1"  },
  { name: "rustbucket_69",  steamId: "76561198448009217", joinedAgo: "14m",    tier: null,       country: "US", warns: 0, kdSession: "0/2"  },
  { name: "Margot.Carrion", steamId: "76561198266118400", joinedAgo: "11m",    tier: "survivor", country: "GB", warns: 0, kdSession: "1/0"  },
  { name: "DEW.point",      steamId: "76561198501882773", joinedAgo: "6m",     tier: null,       country: "US", warns: 0, kdSession: "0/0"  },
];

const ADMIN_RECENT_PAYMENTS = [
  { id: "ch_3PqA1k…", t: "2 min ago",  amount: 10, status: "succeeded",  tier: "outlaw",   discord: "ColdSpoon_8a4",   steamId: "76561198192377044", method: "•••• 4242" },
  { id: "ch_3Pq2hX…", t: "14 min ago", amount:  5, status: "succeeded",  tier: "survivor", discord: "nightowl_qm3",    steamId: "76561198009288176", method: "•••• 0071" },
  { id: "ch_3Pq28R…", t: "1 hr ago",   amount: 20, status: "succeeded",  tier: "warlord",  discord: "palletjack_x99",  steamId: "76561198266118400", method: "•••• 8819" },
  { id: "ch_3Pq1ZP…", t: "2 hr ago",   amount: 10, status: "refunded",   tier: "outlaw",   discord: "gravelmouth_a1",  steamId: "76561198217004401", method: "•••• 4242" },
  { id: "ch_3Pq0Y2…", t: "3 hr ago",   amount: 10, status: "failed",     tier: "outlaw",   discord: "BoiledTurnip_z",  steamId: "76561198811402117", method: "•••• 0341", reason: "insufficient_funds" },
  { id: "ch_3Pq0Q8…", t: "5 hr ago",   amount:  5, status: "succeeded",  tier: "survivor", discord: "dustbin_2k4",     steamId: "76561198120553711", method: "•••• 1124" },
  { id: "ch_3Pq0Bm…", t: "8 hr ago",   amount: 20, status: "succeeded",  tier: "warlord",  discord: "Margot.Carrion",  steamId: "76561198266118400", method: "•••• 8819" },
  { id: "ch_3Pp9wL…", t: "11 hr ago",  amount: 10, status: "succeeded",  tier: "outlaw",   discord: "Pyre_Walker_x1",  steamId: "76561198033471128", method: "•••• 4242" },
];

const ADMIN_EVENTS = [
  { t: "00:42",  kind: "connect",    msg: "FrostByteFred connected from 76.x.x.x", color: "var(--good)" },
  { t: "00:38",  kind: "kill",       msg: "Hollow.Tide killed Mort.404 with M24 at 412m (Tisy ridge)", color: "var(--ink-2)" },
  { t: "00:31",  kind: "payment",    msg: "Outlaw subscription · ColdSpoon_8a4 · $10 · succeeded", color: "var(--accent)" },
  { t: "00:24",  kind: "ban",        msg: "Halberd banned RAT_KING_77 — duplicating exploit (clip in #appeals)", color: "var(--bad)" },
  { t: "00:18",  kind: "event",      msg: "Convoy ambush spawned at grid F5 (41,48)", color: "var(--accent-2)" },
  { t: "00:09",  kind: "disconnect", msg: "rustbucket_69 disconnected (combat log? — under 10min window)", color: "var(--bad)" },
  { t: "00:02",  kind: "connect",    msg: "DEW.point connected from 24.x.x.x", color: "var(--good)" },
];

const ADMIN_AUDIT = [
  { t: "2 min ago",  who: "Halberd",   what: "Granted Outlaw to ColdSpoon_8a4 (gift, 30d)" },
  { t: "14 min ago", who: "system",    what: "PayPal webhook · BILLING.SUBSCRIPTION.ACTIVATED · nightowl_qm3 · Survivor" },
  { t: "1 hr ago",   who: "Wren",      what: "Refunded $10 to gravelmouth_a1 (downtime compensation)" },
  { t: "1 hr ago",   who: "Wren",      what: "Revoked Outlaw from gravelmouth_a1 after refund" },
  { t: "2 hr ago",   who: "Cinder",    what: "Triggered Convoy event manually (F5)" },
  { t: "3 hr ago",   who: "Pallet",    what: "Banned RAT_KING_77 (24h, duping exploit)" },
  { t: "3 hr ago",   who: "Pallet",    what: "Force-resynced 14 Discord roles after webhook drop" },
  { t: "4 hr ago",   who: "system",    what: "BattleMetrics sync · 60/60 players · queue 7" },
  { t: "5 hr ago",   who: "Halberd",   what: "Approved ban appeal for ConcreteHymn (false positive)" },
];

const ADMIN_APPEALS = [
  { id: "A-2031", who: "ConcreteHymn",  steamId: "76561198018002441", filed: "5 hr ago",  status: "approved", reason: "BattlEye false positive — VAC clean, 1100h, clip provided" },
  { id: "A-2032", who: "RAT_KING_77",   steamId: "76561198811402117", filed: "3 hr ago",  status: "denied",   reason: "Duping clip is conclusive" },
  { id: "A-2033", who: "fugu.shogun",   steamId: "76561198302118876", filed: "1 hr ago",  status: "pending",  reason: "Claims combat log was a router crash, traceroute attached" },
];

// ── helpers ──────────────────────────────────────────────────────────────
function fmtTier(t) {
  if (!t) return <span style={{color:"var(--ink-4)"}}>—</span>;
  const found = TIERS.find(x => x.key === t);
  return <span style={{color: found?.color, fontFamily:"JetBrains Mono", fontSize:11, letterSpacing:"0.14em", textTransform:"uppercase"}}>★ {t}</span>;
}

function isStaff(session, mockStaff) {
  // Prototype rule: mockStaff tweak OR session.discord.staff flag set server-side
  // OR the owner-mode flag set via the ?adminmode=1 URL param (see app.jsx).
  // Production: backend checks the user's Discord guild role membership against
  // the "Admin" role on the ShovelHead.net Discord and sets session.discord.staff
  // = true. Client never trusts a self-set flag for ACTUAL security — the API
  // (backend/api-worker.js) requires ADMIN_SECRET to actually save anything.
  if (mockStaff) return true;
  if (!!session?.discord?.staff) return true;
  try {
    if (localStorage.getItem("shovelhead.adminUI") === "1") return true;
  } catch {}
  return false;
}

// ── Admin overlay ────────────────────────────────────────────────────────
function AdminOverlay({ open, onClose }) {
  const [tab, setTab] = React.useState("overview");
  const [q, setQ] = React.useState("");

  if (!open) return null;

  return (
    <div className="admin-overlay">
      <div className="admin-shell">
        <header className="admin-header">
          <div className="admin-brand">
            <ShovelMark size={20} color="var(--accent)" />
            <span className="admin-title">SHOVELHEAD<span style={{color:"var(--accent)"}}>.</span>ADMIN</span>
            <span className="admin-pill">STAFF</span>
          </div>
          <div className="admin-tabs">
            {[
              ["overview", "Overview"],
              ["map",      "Live Map"],
              ["players",  "Players"],
              ["subs",     "Subscriptions"],
              ["activity", "Activity"],
              ["appeals",  "Appeals"],
              ["audit",    "Audit"],
              ["settings", "Settings"],
              ["notif",    "Notifications"],
            ].map(([k, l]) => (
              <button key={k} className={"admin-tab" + (tab === k ? " on" : "")} onClick={() => setTab(k)}>{l}</button>
            ))}
          </div>
          <button className="admin-close" onClick={onClose}>EXIT ADMIN ✕</button>
        </header>

        <main className="admin-body">
          {tab === "overview"  && <AdminOverview />}
          {tab === "map"       && <AdminMap />}
          {tab === "players"   && <AdminPlayers q={q} setQ={setQ} />}
          {tab === "subs"      && <AdminSubs    q={q} setQ={setQ} />}
          {tab === "activity"  && <AdminActivity />}
          {tab === "appeals"   && <AdminAppeals />}
          {tab === "audit"     && <AdminAudit />}
          {tab === "settings"  && <AdminSettings />}
          {tab === "notif"     && <AdminNotifications />}
        </main>
      </div>
    </div>
  );
}

// ── Overview ─────────────────────────────────────────────────────────────
function AdminOverview() {
  const totals = {
    online:    ADMIN_PLAYERS_LIVE.length,
    queue:     7,
    activeSubs: 47,
    mrr:        470,
    pendingAppeals: ADMIN_APPEALS.filter(a => a.status === "pending").length,
    failedToday: ADMIN_RECENT_PAYMENTS.filter(p => p.status === "failed").length,
  };
  return (
    <>
      <div className="admin-stats">
        {[
          { k: "ONLINE",         v: totals.online + "/" + SERVER.slots, color: "var(--good)" },
          { k: "IN QUEUE",       v: totals.queue, color: "var(--accent)" },
          { k: "ACTIVE SUBS",    v: totals.activeSubs, color: "var(--ink)" },
          { k: "MRR (USD)",      v: "$" + totals.mrr, color: "var(--ink)" },
          { k: "PENDING APPEALS",v: totals.pendingAppeals, color: totals.pendingAppeals > 0 ? "var(--bad)" : "var(--ink-4)" },
          { k: "FAILED CHARGES", v: totals.failedToday + " · 24h", color: totals.failedToday > 0 ? "var(--bad)" : "var(--ink-4)" },
        ].map(s => (
          <div key={s.k} className="admin-stat">
            <div className="k">{s.k}</div>
            <div className="v" style={{color: s.color}}>{s.v}</div>
          </div>
        ))}
      </div>

      <div className="admin-cols">
        <section className="admin-panel">
          <header><h3>Recent payments</h3><a className="admin-link" onClick={()=>{}}>view all →</a></header>
          <div className="admin-list">
            {ADMIN_RECENT_PAYMENTS.slice(0,5).map(p => (
              <div key={p.id} className="admin-list-row">
                <span className={"admin-dot " + p.status}></span>
                <span className="admin-mono">{p.t}</span>
                <span style={{flex:1}}>{p.discord}</span>
                {fmtTier(p.tier)}
                <span className="admin-mono" style={{color: p.status === "succeeded" ? "var(--good)" : p.status === "refunded" ? "var(--accent-2)" : "var(--bad)"}}>
                  {p.status === "succeeded" ? "+" : p.status === "refunded" ? "−" : "×"}${p.amount}
                </span>
              </div>
            ))}
          </div>
        </section>

        <section className="admin-panel">
          <header><h3>Recent activity</h3></header>
          <div className="admin-list">
            {ADMIN_EVENTS.slice(0,6).map((e, i) => (
              <div key={i} className="admin-list-row">
                <span className="admin-mono" style={{color:"var(--ink-3)"}}>+{e.t}</span>
                <span className="admin-mono" style={{color: e.color, fontSize:10, letterSpacing:"0.14em",textTransform:"uppercase",width:90}}>{e.kind}</span>
                <span style={{flex:1, fontSize:13}}>{e.msg}</span>
              </div>
            ))}
          </div>
        </section>
      </div>
    </>
  );
}

// ── Players ──────────────────────────────────────────────────────────────
function AdminPlayers({ q, setQ }) {
  const [selected, setSelected] = React.useState(new Set());
  const rows = ADMIN_PLAYERS_LIVE.filter(p =>
    !q || p.name.toLowerCase().includes(q.toLowerCase()) || p.steamId.includes(q)
  );
  const allSelected = rows.length > 0 && rows.every(r => selected.has(r.steamId));
  const toggleOne = (id) => {
    setSelected(s => { const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n; });
  };
  const toggleAll = () => {
    setSelected(s => {
      if (allSelected) return new Set();
      return new Set(rows.map(r => r.steamId));
    });
  };
  const clearSel = () => setSelected(new Set());

  return (
    <>
      <div className="admin-toolbar">
        <input className="admin-search" placeholder="Search by name, Steam ID, or Discord username…" value={q} onChange={e => setQ(e.target.value)} />
        <div className="admin-mono" style={{color:"var(--ink-3)"}}>{rows.length} ONLINE · {selected.size} SELECTED</div>
      </div>

      {selected.size > 0 && (
        <div className="admin-bulk-bar">
          <div className="admin-bulk-info">
            <strong>{selected.size}</strong> selected · 
            <button className="admin-link" onClick={clearSel} style={{marginLeft:8}}>clear</button>
          </div>
          <div className="admin-actions">
            <button className="admin-btn">DM ALL</button>
            <button className="admin-btn">WARN ALL</button>
            <button className="admin-btn">KICK ALL</button>
            <button className="admin-btn">BROADCAST</button>
            <button className="admin-btn danger">BAN ALL</button>
          </div>
        </div>
      )}

      <div className="admin-table">
        <div className="admin-row head with-check">
          <div className="admin-check-cell">
            <input type="checkbox" checked={allSelected} onChange={toggleAll} />
          </div>
          <div>PLAYER</div>
          <div>STEAM ID</div>
          <div>JOINED</div>
          <div>SESSION</div>
          <div>TIER</div>
          <div>WARNS</div>
          <div style={{textAlign:"right"}}>ACTIONS</div>
        </div>
        {rows.map(p => (
          <div key={p.steamId} className={"admin-row with-check" + (selected.has(p.steamId) ? " sel" : "")}>
            <div className="admin-check-cell">
              <input type="checkbox" checked={selected.has(p.steamId)} onChange={() => toggleOne(p.steamId)} />
            </div>
            <div className="admin-cell-name">
              <span className="admin-flag">{p.country}</span>
              <strong>{p.name}</strong>
            </div>
            <div className="admin-mono">{p.steamId}</div>
            <div>{p.joinedAgo}</div>
            <div className="admin-mono">{p.kdSession}</div>
            <div>{fmtTier(p.tier)}</div>
            <div>
              {p.warns === 0 ? <span style={{color:"var(--ink-4)"}}>—</span> :
                <span style={{color: p.warns > 1 ? "var(--bad)" : "var(--accent-2)"}}>×{p.warns}</span>}
            </div>
            <div className="admin-actions">
              <button className="admin-btn">DM</button>
              <button className="admin-btn">KICK</button>
              <button className="admin-btn danger">BAN</button>
            </div>
          </div>
        ))}
      </div>
    </>
  );
}

// ── Subscriptions ────────────────────────────────────────────────────────
function AdminSubs({ q, setQ }) {
  const rows = ADMIN_RECENT_PAYMENTS.filter(p =>
    !q || p.discord.toLowerCase().includes(q.toLowerCase()) || p.steamId.includes(q)
  );
  return (
    <>
      <div className="admin-toolbar">
        <input className="admin-search" placeholder="Search subscriptions by Discord or Steam ID…" value={q} onChange={e => setQ(e.target.value)} />
        <div className="admin-toolbar-actions">
          <button className="admin-btn">EXPORT CSV</button>
          <button className="admin-btn">GRANT GIFT</button>
        </div>
      </div>

      <div className="admin-table">
        <div className="admin-row head subs">
          <div>STATUS</div>
          <div>WHEN</div>
          <div>DISCORD</div>
          <div>STEAM</div>
          <div>TIER</div>
          <div>METHOD</div>
          <div style={{textAlign:"right"}}>AMT</div>
          <div style={{textAlign:"right"}}>ACTIONS</div>
        </div>
        {rows.map(p => (
          <div key={p.id} className="admin-row subs">
            <div>
              <span className={"admin-status " + p.status}>{p.status.toUpperCase()}</span>
            </div>
            <div className="admin-mono">{p.t}</div>
            <div><strong>{p.discord}</strong></div>
            <div className="admin-mono" style={{fontSize:11}}>{p.steamId}</div>
            <div>{fmtTier(p.tier)}</div>
            <div className="admin-mono" style={{color:"var(--ink-3)"}}>{p.method}</div>
            <div className="admin-mono" style={{textAlign:"right",color: p.status==="succeeded"?"var(--good)":p.status==="refunded"?"var(--accent-2)":"var(--bad)"}}>
              ${p.amount}
            </div>
            <div className="admin-actions">
              <button className="admin-btn">VIEW PAYPAL</button>
              {p.status === "succeeded"  && <button className="admin-btn">REFUND</button>}
              {p.status === "failed"     && <button className="admin-btn">RETRY</button>}
              <button className="admin-btn">SYNC ROLE</button>
            </div>
          </div>
        ))}
      </div>

      {rows.find(r => r.status === "failed") && (
        <div className="admin-callout warn">
          <strong>{rows.filter(r => r.status === "failed").length} failed charge(s) in window.</strong> PayPal auto-retries failed subscription payments for up to 7 days. After that the subscription is suspended, tier is auto-revoked, and the user is notified via Discord DM.
        </div>
      )}
    </>
  );
}

// ── Activity ─────────────────────────────────────────────────────────────
function AdminActivity() {
  return (
    <>
      <div className="admin-toolbar">
        <div className="admin-filters">
          {["all","connects","kills","payments","bans","events"].map(k => (
            <button key={k} className={"chip" + (k === "all" ? " on" : "")}>{k.toUpperCase()}</button>
          ))}
        </div>
        <div className="admin-mono" style={{color:"var(--ink-3)"}}>STREAMING · 12 EVENTS / MIN</div>
      </div>
      <div className="admin-stream">
        {ADMIN_EVENTS.map((e, i) => (
          <div key={i} className="admin-stream-row">
            <div className="admin-mono" style={{color:"var(--ink-3)",width:80}}>+{e.t}</div>
            <div className="admin-mono" style={{color: e.color, width:100, fontSize:10, letterSpacing:"0.14em",textTransform:"uppercase"}}>{e.kind}</div>
            <div style={{flex:1}}>{e.msg}</div>
          </div>
        ))}
      </div>
    </>
  );
}

// ── Appeals ──────────────────────────────────────────────────────────────
function AdminAppeals() {
  return (
    <>
      <div className="admin-toolbar">
        <div className="admin-mono" style={{color:"var(--ink-3)"}}>BAN APPEAL QUEUE</div>
        <div className="admin-mono" style={{color:"var(--accent)"}}>{ADMIN_APPEALS.filter(a => a.status==="pending").length} PENDING</div>
      </div>
      <div className="admin-cards">
        {ADMIN_APPEALS.map(a => (
          <div key={a.id} className={"admin-card status-" + a.status}>
            <div className="admin-card-head">
              <span className="admin-mono" style={{color:"var(--ink-3)"}}>{a.id}</span>
              <span className={"admin-status " + (a.status === "approved" ? "succeeded" : a.status === "denied" ? "failed" : "pending")}>
                {a.status.toUpperCase()}
              </span>
            </div>
            <div className="admin-card-name">{a.who}</div>
            <div className="admin-mono" style={{color:"var(--ink-3)",fontSize:11,marginBottom:8}}>{a.steamId} · filed {a.filed}</div>
            <div style={{fontSize:13, color:"var(--ink-2)", marginBottom:12}}>{a.reason}</div>
            {a.status === "pending" && (
              <div className="admin-actions">
                <button className="admin-btn">APPROVE & UNBAN</button>
                <button className="admin-btn danger">DENY</button>
                <button className="admin-btn">ASK FOR EVIDENCE</button>
              </div>
            )}
          </div>
        ))}
      </div>
    </>
  );
}

// ── Audit ────────────────────────────────────────────────────────────────
function AdminAudit() {
  return (
    <>
      <div className="admin-toolbar">
        <div className="admin-mono" style={{color:"var(--ink-3)"}}>STAFF AUDIT LOG · LAST 24h</div>
        <button className="admin-btn">EXPORT</button>
      </div>
      <div className="admin-audit">
        {ADMIN_AUDIT.map((a, i) => (
          <div key={i} className="admin-audit-row">
            <div className="admin-mono" style={{color:"var(--ink-3)",width:120}}>{a.t}</div>
            <div className="admin-mono" style={{width:120, color: a.who === "system" ? "var(--ink-4)" : "var(--accent)", textTransform:"uppercase", letterSpacing:"0.12em", fontSize:11}}>
              {a.who}
            </div>
            <div style={{flex:1, fontSize:13}}>{a.what}</div>
          </div>
        ))}
      </div>
    </>
  );
}

window.AdminOverlay = AdminOverlay;
window.isStaff = isStaff;
