const { useState, useEffect, useMemo } = React;

/* Admin — Waitlist management (people who signed up on the pre-launch site).
   All data + mutations are server-gated by require_admin(). */

const WL_USE_CASES = [
  ["broker",    "Brokerage / tenant rep"],
  ["b2b_sales", "B2B sales"],
  ["vendor",    "Vendor prospecting"],
  ["investor",  "Investment / diligence"],
  ["analyst",   "Analyst"],
  ["research",  "Research"],
  ["other",     "Other"],
];
const WL_USE_LABEL = Object.fromEntries(WL_USE_CASES);

function AdminWaitlistPage({ go }) {
  const ciq = window.ContactIQ ? window.ContactIQ.useContactIQ() : { isAuthed: false, isAdmin: false };

  const [rows, setRows]     = useState([]);
  const [stats, setStats]   = useState(null);
  const [loading, setLoading] = useState(false);
  const [query, setQuery]   = useState("");
  const [useF, setUseF]     = useState("all");
  const [statusF, setStatusF] = useState("all");
  const [busy, setBusy]     = useState(null);   // id currently mutating
  const [msg, setMsg]       = useState("");

  const load = async () => {
    if (!ciq.isAdmin || !window.ContactIQ) return;
    setLoading(true);
    const [list, st] = await Promise.all([
      window.ContactIQ.adminWaitlistList({
        search:  query || null,
        useCase: useF === "all" ? null : useF,
        status:  statusF === "all" ? null : statusF,
        limit:   1000,
      }),
      window.ContactIQ.adminWaitlistStats("extension"),
    ]);
    setRows(list || []);
    setStats(st || null);
    setLoading(false);
  };

  useEffect(() => { load(); /* eslint-disable-next-line */ }, [ciq.isAdmin, useF, statusF]);
  // debounce search
  useEffect(() => {
    if (!ciq.isAdmin) return;
    const t = setTimeout(load, 300);
    return () => clearTimeout(t);
    /* eslint-disable-next-line */
  }, [query]);

  // Authenticated non-admin → hard block.
  if (ciq.isAuthed && !ciq.isAdmin) {
    return (
      <>
        <div className="work-head">
          <div className="col" style={{ gap: 2 }}>
            <div className="title">Waitlist</div>
            <div className="sub">Admin access required.</div>
          </div>
        </div>
        <div className="work-body">
          <div className="dash-empty">
            <div className="dash-empty-icon"><I.Mail style={{ width: 36, height: 36 }}/></div>
            <h3 style={{ font: "600 18px var(--font-sans)", letterSpacing: "-0.01em" }}>Admins only</h3>
            <p className="dim" style={{ maxWidth: 380, textAlign: "center", lineHeight: 1.55, fontSize: 13 }}>
              You're signed in, but your account doesn't have the <span className="mono">admin</span> role.
            </p>
          </div>
        </div>
      </>
    );
  }
  // Unauthenticated preview → prompt to sign in (no mock data for real signups).
  if (!ciq.isAuthed) {
    return (
      <>
        <div className="work-head">
          <div className="col" style={{ gap: 2 }}>
            <div className="title">Waitlist</div>
            <div className="sub">Sign in as an admin to view and manage waitlist signups.</div>
          </div>
        </div>
        <div className="work-body">
          <div className="dash-empty">
            <div className="dash-empty-icon"><I.Mail style={{ width: 36, height: 36 }}/></div>
            <h3 style={{ font: "600 18px var(--font-sans)", letterSpacing: "-0.01em" }}>Sign in required</h3>
            <p className="dim" style={{ maxWidth: 380, textAlign: "center", lineHeight: 1.55, fontSize: 13 }}>
              Waitlist data is private. <a className="lnk" onClick={() => go("login")}>Sign in</a> with an admin account.
            </p>
          </div>
        </div>
      </>
    );
  }

  const flash = (m) => { setMsg(m); setTimeout(() => setMsg(""), 1800); };

  const setFlag = async (row, patch) => {
    setBusy(row.id);
    try {
      await window.ContactIQ.adminWaitlistSet(row.id, patch);
      setRows(rs => rs.map(r => r.id === row.id ? { ...r, ...patch } : r));
      flash("Saved ✓");
    } catch (e) { flash("Failed: " + (e.message || e)); }
    finally { setBusy(null); }
  };

  const del = async (row) => {
    if (!window.confirm("Remove " + row.email + " from the waitlist? This can't be undone.")) return;
    setBusy(row.id);
    try {
      await window.ContactIQ.adminWaitlistDelete(row.id);
      setRows(rs => rs.filter(r => r.id !== row.id));
      flash("Deleted ✓");
    } catch (e) { flash("Failed: " + (e.message || e)); }
    finally { setBusy(null); }
  };

  const exportCsv = () => {
    const cols = ["email","company","use_case","team_size","browser","referral_code","referred_by","referral_count","utm_source","utm_campaign","confirmed","unsubscribed","created_at"];
    const esc = (v) => '"' + String(v == null ? "" : v).replace(/"/g, '""') + '"';
    const lines = [cols.join(",")].concat(rows.map(r => cols.map(c => esc(r[c])).join(",")));
    const blob = new Blob([lines.join("\n")], { type: "text/csv" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = "waitlist-" + new Date().toISOString().slice(0, 10) + ".csv";
    a.click();
    URL.revokeObjectURL(a.href);
  };

  const fmtDate = (s) => { try { return new Date(s).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }); } catch (_) { return s; } };

  return (
    <>
      <div className="work-head">
        <div className="col" style={{ gap: 2 }}>
          <div className="title">Waitlist <span className="mono dim" style={{ fontSize: 14 }}>· {stats ? stats.total : rows.length}</span></div>
          <div className="sub">People who reserved a spot on the pre-launch site. Manage, confirm, or remove.</div>
        </div>
        <div className="spacer"/>
        <div className="row tight">
          <button className="btn sm" onClick={load}><I.Refresh/> Refresh</button>
          <button className="btn sm" onClick={exportCsv} disabled={!rows.length}><I.Download/> Export CSV</button>
          {msg && <span className="dim" style={{ fontSize: 11, marginLeft: 4 }}>{msg}</span>}
        </div>
      </div>

      <div className="work-body">
        {/* Stat tiles */}
        <div className="admin-plan-tiles">
          <WlTile label="Total"        n={stats ? stats.total : "—"}/>
          <WlTile label="Last 24h"     n={stats ? stats.last_24h : "—"} c="var(--accent)"/>
          <WlTile label="Last 7 days"  n={stats ? stats.last_7d : "—"} c="var(--accent)"/>
          <WlTile label="Via referral" n={stats ? stats.via_referral : "—"} c="var(--green)"/>
          <WlTile label="Confirmed"    n={stats ? stats.confirmed : "—"} c="var(--green)"/>
        </div>

        {/* Filters */}
        <div className="dash-filters" style={{ marginTop: 16 }}>
          <input className="input search sm" style={{ width: 260 }}
            placeholder="Search email, company, or source…"
            value={query} onChange={e => setQuery(e.target.value)}/>
          <FilterPicker label="Use case" value={useF} setValue={setUseF}
            options={[["all","Any"]].concat(WL_USE_CASES)}/>
          <FilterPicker label="Status" value={statusF} setValue={setStatusF}
            options={[["all","Any"],["pending","Pending"],["confirmed","Confirmed"],["unsubscribed","Unsubscribed"]]}/>
          <span className="spacer"/>
          <span className="dim mono" style={{ fontSize: 11 }}>{loading ? "Loading…" : rows.length + " shown"}</span>
        </div>

        {/* Table */}
        <div className="card" style={{ marginTop: 12, overflow: "hidden" }}>
          <table className="tbl admin-tbl">
            <thead>
              <tr>
                <th>Person</th>
                <th style={{ width: 150 }}>Use case</th>
                <th style={{ width: 80 }}>Team</th>
                <th style={{ width: 90 }}>Browser</th>
                <th style={{ width: 70, textAlign: "right" }}>Refs</th>
                <th style={{ width: 120 }}>Source</th>
                <th style={{ width: 100 }}>Joined</th>
                <th style={{ width: 110 }}>Status</th>
                <th style={{ width: 190 }}>&nbsp;</th>
              </tr>
            </thead>
            <tbody>
              {rows.map(r => (
                <tr key={r.id} className={r.unsubscribed ? "dim" : ""}>
                  <td>
                    <div className="col" style={{ gap: 1 }}>
                      <div className="mono" style={{ fontSize: 12, fontWeight: 600, color: "var(--fg-1)" }}>{r.email}</div>
                      {r.company && <div className="dim" style={{ fontSize: 10.5 }}>{r.company}</div>}
                    </div>
                  </td>
                  <td style={{ fontSize: 12 }}>{WL_USE_LABEL[r.use_case] || r.use_case || "—"}</td>
                  <td className="mono dim" style={{ fontSize: 11 }}>{r.team_size || "—"}</td>
                  <td className="mono dim" style={{ fontSize: 11 }}>{r.browser || "—"}</td>
                  <td className="num"><span className="mono">{r.referral_count || 0}</span></td>
                  <td className="mono dim" style={{ fontSize: 10.5 }}>{r.utm_source || (r.referred_by ? "referral" : "direct")}</td>
                  <td className="mono dim" style={{ fontSize: 11 }}>{fmtDate(r.created_at)}</td>
                  <td>
                    {r.unsubscribed
                      ? <span className="pill" style={{ fontSize: 9 }}>Unsub</span>
                      : r.confirmed
                        ? <span className="pill green" style={{ fontSize: 9 }}>Confirmed</span>
                        : <span className="pill accent" style={{ fontSize: 9 }}>Pending</span>}
                  </td>
                  <td>
                    <div className="row tight" style={{ justifyContent: "flex-end", opacity: busy === r.id ? 0.5 : 1 }}>
                      {!r.confirmed
                        ? <button className="btn sm" title="Mark confirmed" onClick={() => setFlag(r, { confirmed: true })}><I.Check/></button>
                        : <button className="btn ghost sm" title="Unconfirm" onClick={() => setFlag(r, { confirmed: false })}>Unconfirm</button>}
                      {!r.unsubscribed
                        ? <button className="btn ghost sm" title="Unsubscribe" onClick={() => setFlag(r, { unsubscribed: true })}>Unsub</button>
                        : <button className="btn sm" title="Resubscribe" onClick={() => setFlag(r, { unsubscribed: false })}>Resub</button>}
                      <button className="btn ghost danger sm" title="Delete" onClick={() => del(r)}><I.X/></button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          {!loading && rows.length === 0 && (
            <div style={{ padding: 32, textAlign: "center" }} className="dim">No signups match these filters.</div>
          )}
        </div>
      </div>
    </>
  );
}

function WlTile({ label, n, c }) {
  return (
    <div className="plan-tile" style={{ cursor: "default" }}>
      {c && <span className="plan-tile-dot" style={{ background: c }}/>}
      <span className="mono" style={{ font: "700 22px var(--font-mono)", letterSpacing: "-0.02em" }}>
        {typeof n === "number" ? n.toLocaleString() : n}
      </span>
      <span className="dim" style={{ fontSize: 11 }}>{label}</span>
    </div>
  );
}

window.AdminWaitlistPage = AdminWaitlistPage;
