/* =========================================================================
   Live ICP Tracker — Tuner, Signal Feed, Roster, Spend (internal)
   Exports: TunerView, SignalsView, RosterView, SpendView
   ========================================================================= */
const { useState: useStateB, useMemo: useMemoB, useEffect: useEffectB } = React;

/* ---------- Recent referral activity (from Supabase) ------------------- */
function timeAgo(ts) {
  const s = Math.floor((Date.now() - ts) / 1000);
  if (s < 60) return "just now";
  const m = Math.floor(s / 60); if (m < 60) return m + "m ago";
  const h = Math.floor(m / 60); if (h < 24) return h + "h ago";
  const d = Math.floor(h / 24); if (d < 7) return d + "d ago";
  return new Date(ts).toLocaleDateString(undefined, { month: "short", day: "numeric" });
}

function RecentReferralActivity() {
  const [rows, setRows] = useStateB([]);
  const [loaded, setLoaded] = useStateB(false);
  useEffectB(() => {
    let live = true;
    fetch("/api/referrals")
      .then(r => r.json())
      .then(d => { if (live) { setRows((d.referrals || []).slice(0, 6)); setLoaded(true); } })
      .catch(e => { console.log("[v0] load recent referrals failed:", e && e.message); if (live) setLoaded(true); });
    return () => { live = false; };
  }, []);

  return (
    <>
      <div className="sec-head"><h2>Recent referral activity</h2><span className="line"></span><span className="subtle" style={{ fontSize: 12 }}>{rows.length} recent</span></div>
      <div className="card" style={{ overflow: "hidden", marginBottom: 8 }}>
        {!loaded ? (
          <div className="muted" style={{ padding: "16px 18px", fontSize: 13 }}>Loading recent activity…</div>
        ) : rows.length === 0 ? (
          <div className="muted" style={{ padding: "16px 18px", fontSize: 13 }}>No intro requests or list posts yet. Request an intro from a company card, or post a saved list to referrals.</div>
        ) : (
          <table className="tbl">
            <thead><tr><th>Type</th><th>Subject</th><th>Note</th><th className="num">When</th></tr></thead>
            <tbody>
              {rows.map(r => (
                <tr key={r.id}>
                  <td>
                    <span className="chip" style={{ background: r.kind === "list" ? "var(--bg-accent-soft)" : "var(--bg-subtle, #F0EDE7)", color: r.kind === "list" ? "var(--c-malachyte-dark)" : "var(--text-default)" }}>
                      <Icon name={r.kind === "list" ? "share" : "users"} size={12} />
                      {r.kind === "list" ? "List post" : "Intro request"}
                    </span>
                  </td>
                  <td style={{ fontWeight: 500 }}>
                    {r.kind === "list" ? (r.listName || "Untitled list") : (r.accountName || "Account")}
                    {r.kind === "list" && r.accountCount != null && (
                      <span className="subtle" style={{ fontWeight: 400 }}>{" · " + r.accountCount + (r.accountCount === 1 ? " account" : " accounts")}</span>
                    )}
                  </td>
                  <td className="muted" style={{ fontSize: 12.5, maxWidth: 320 }}>{r.description ? r.description : <span className="subtle">—</span>}</td>
                  <td className="num muted" style={{ fontSize: 12.5 }}>{timeAgo(r.createdAt)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </>
  );
}

/* ---------- ICP Score Tuner -------------------------------------------- */
function TunerView({ onOpen }) {
  const I = window.ICP;
  const M = I.WEIGHT_META;
  const keys = ["revenueFit", "vendorVuln", "trafficScale", "catalogFit", "signalHeat", "warmPath", "strategicFit", "negative"];
  const [w, setW] = useStateB({ ...I.WEIGHTS });

  const total = keys.filter(k => k !== "negative").reduce((s, k) => s + w[k], 0);

  const ranked = useMemoB(() => {
    return I.ACCOUNTS.map(a => ({ a, base: a.score, live: I.scoreOf(a, w) }))
      .sort((x, y) => y.live - x.live);
  }, [w]);

  const reset = () => setW({ ...I.WEIGHTS });

  return (
    <div className="page">
      <div className="sec-head" style={{ marginTop: 0 }}>
        <h2>ICP score tuner</h2>
        <span className="line"></span>
        <button className="btn ghost sm" onClick={reset}><Icon name="refresh" size={14} />Reset to default</button>
      </div>
      <p className="muted" style={{ maxWidth: 720, marginBottom: 18 }}>
        Adjust the weights and watch the ranking re-sort live. The model is transparent on purpose — every account shows why it ranks where it does. Tune monthly against win/loss; lock a version and it re-scores all {I.META.totalList.toLocaleString()} accounts.
      </p>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 380px", gap: 18, alignItems: "start" }}>
        {/* sliders */}
        <div className="card pad">
          <div className="between" style={{ marginBottom: 6 }}>
            <span className="label-micro">Positive components</span>
            <span className="chip" style={{ background: total === 90 ? "var(--bg-accent-soft)" : "rgba(216,146,81,0.14)", color: total === 90 ? "var(--c-malachyte-dark)" : "#9A5B1E" }}>
              weights sum to {total}{total !== 90 ? " (was 90)" : ""}
            </span>
          </div>
          {keys.map(k => (
            <div className="tuner-row" key={k} style={k === "negative" ? { borderTop: "1px solid var(--border-default)", marginTop: 6 } : {}}>
              <div>
                <div className="nm" style={k === "negative" ? { color: "var(--st-danger)" } : {}}>{M[k].label}</div>
                <div className="nt">{M[k].note}</div>
              </div>
              <input className="sl" type="range" min="0" max={k === "negative" ? 15 : 30} value={w[k]}
                onChange={e => setW(p => ({ ...p, [k]: +e.target.value }))} />
              <div className="wval" style={k === "negative" ? { color: "var(--st-danger)" } : {}}>{k === "negative" ? "−" : ""}{w[k]}</div>
            </div>
          ))}
          <div className="row gap8 mt16">
            <button className="btn pri sm"><Icon name="check" size={14} />Lock this version & re-score</button>
            <button className="btn sm"><Icon name="copy" size={14} />Save as scenario</button>
          </div>
        </div>

        {/* live preview */}
        <div className="card pad">
          <div className="label-micro" style={{ marginBottom: 4 }}>Live re-rank preview</div>
          <div className="subtle" style={{ fontSize: 11.5, marginBottom: 12 }}>Top accounts under the current weights. Arrows show movement vs the locked model.</div>
          <div className="col">
            {ranked.slice(0, 10).map(({ a, base, live }, i) => {
              const baseRank = ranked.slice().sort((x, y) => y.base - x.base).findIndex(r => r.a.id === a.id);
              const delta = baseRank - i;
              return (
                <div key={a.id} className="row gap10" style={{ padding: "8px 0", borderBottom: "1px solid #F0EDE7", cursor: "pointer" }} onClick={() => onOpen(a)}>
                  <span className="rank">{i + 1}</span>
                  <Logo name={a.brand} src={a.logo} size="sm" />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontWeight: 500, fontSize: 13 }}>{a.brand}</div>
                    <div className="subtle" style={{ fontSize: 11 }}>{a.tier} · {I.fmtMoney(a.onlineRev)}</div>
                  </div>
                  {delta !== 0 && (
                    <span style={{ fontSize: 11, fontWeight: 500, color: delta > 0 ? "var(--c-malachyte)" : "var(--st-danger)" }}>
                      <Icon name={delta > 0 ? "up" : "down"} size={11} style={{ verticalAlign: -1 }} /> {Math.abs(delta)}
                    </span>
                  )}
                  <span className="score-num" style={{ minWidth: 26, textAlign: "right", color: live !== base ? "var(--c-malachyte)" : "inherit" }}>{live}</span>
                </div>
              );
            })}
          </div>
        </div>
      </div>

      <div className="banner info mt20">
        <Icon name="settings" size={16} style={{ color: "var(--st-info)" }} />
        <span>Score → Tier mapping is automatic but overridable. Tie-breakers: (1) warm-path strength, (2) signal heat, (3) revenue fit.</span>
      </div>
    </div>
  );
}

/* ---------- Live Signal / Trigger Feed --------------------------------- */
function SignalsView({ onOpen }) {
  const I = window.ICP;
  const [filter, setFilter] = useStateB("all");
  const feed = useMemoB(() => {
    const all = [];
    I.ACCOUNTS.forEach(a => a.signals.forEach(s => all.push({ ...s, account: a })));
    const order = { hot: 0, warm: 1, cool: 2 };
    return all.sort((x, y) => (order[x.heat] - order[y.heat]) || 0);
  }, []);
  const types = [
    { k: "all", l: "All" }, { k: "vendor", l: "Vendor swaps" }, { k: "role", l: "Role posts" },
    { k: "exec", l: "New execs" }, { k: "traffic", l: "Traffic" }, { k: "press", l: "Press" },
  ];
  const shown = filter === "all" ? feed : feed.filter(s => s.type === filter);
  const hotCount = feed.filter(s => s.heat === "hot").length;

  return (
    <div className="page">
      <div className="sec-head" style={{ marginTop: 0 }}>
        <h2>Live signal feed</h2>
        <span className="chip" style={{ background: "rgba(193,69,69,0.1)", color: "var(--st-danger)" }}><span className="dot" style={{ background: "var(--st-danger)" }}></span>{hotCount} red-hot</span>
        <span className="line"></span>
        <button className="btn sm"><Icon name="bell" size={14} />Slack alerts on</button>
      </div>
      <p className="muted" style={{ maxWidth: 720, marginBottom: 16 }}>
        Continuously-ranked events that suggest an account is in-market. Each lights up the account card and pings the owner in <span className="mono">#gtm-pipeline</span>. The exact moments we win.
      </p>

      <div className="seg" style={{ marginBottom: 14 }}>
        {types.map(t => <button key={t.k} className={filter === t.k ? "on" : ""} onClick={() => setFilter(t.k)}>{t.l}</button>)}
      </div>

      <div className="card pad">
        {shown.map((s, i) => (
          <div className="signal" key={i} style={{ padding: "14px 0", cursor: "pointer" }} onClick={() => onOpen(s.account)}>
            <SignalIcon type={s.type} heat={s.heat} />
            <div className="stx">
              <div className="row gap8" style={{ marginBottom: 3 }}>
                <Logo name={s.account.brand} src={s.account.logo} size="sm" />
                <span style={{ fontWeight: 500 }}>{s.account.brand}</span>
                <Tier t={s.account.tier} />
                {s.heat === "hot" && <span className="chip" style={{ background: "rgba(193,69,69,0.1)", color: "var(--st-danger)" }}>act now</span>}
              </div>
              <div style={{ fontSize: 13, color: "var(--wf-muted)" }}>{s.text}</div>
            </div>
            <div className="col" style={{ alignItems: "flex-end", gap: 8 }}>
              <span className="when">{s.date} ago</span>
              <button className="btn ghost sm" style={{ padding: "3px 8px" }}><Icon name="arrow" size={13} /></button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ---------- Warm-Intro / Referral-Partner Roster ----------------------- */
function RosterView({ onOpen }) {
  const I = window.ICP;
  const partners = I.PARTNERS;
  // pending warm-intro asks across accounts
  const asks = I.ACCOUNTS.filter(a => a.warmIntro.degree > 0).map(a => ({ a, intro: a.warmIntro }));

  return (
    <div className="page">
      <div className="sec-head" style={{ marginTop: 0 }}>
        <h2>Warm-intro & referral-partner roster</h2>
        <span className="line"></span>
        <button className="btn sm"><Icon name="plus" size={14} />Add partner</button>
      </div>
      <p className="muted" style={{ maxWidth: 760, marginBottom: 18 }}>
        Our CAB & advisor network — the people who open doors. We pay per qualified meeting by tier. Warm-path strength feeds directly into the ICP score, so a strong intro can lift an account's rank.
      </p>

      {/* partner cards */}
      <div className="grid-cards" style={{ marginBottom: 8 }}>
        {partners.map(p => (
          <div className="card acard" key={p.id} style={{ cursor: "default" }}>
            <div className="head">
              <Avatar name={p.name} />
              <div className="meta">
                <div style={{ fontWeight: 500 }}>{p.name}</div>
                <div className="subtle" style={{ fontSize: 11.5 }}>{p.org}</div>
              </div>
              <span className="chip" style={{ background: "var(--bg-accent-soft)", color: "var(--c-malachyte-dark)" }}>{p.relationship.split("-")[0]}°</span>
            </div>
            <div className="stat-row">
              <div className="stat"><span className="subtle">Warm paths</span><b>{p.paths}</b></div>
              <div className="stat"><span className="subtle">Hot now</span><b style={{ color: "var(--st-danger)" }}>{p.hotPaths}</b></div>
              <div className="stat"><span className="subtle">Meeting fee</span><b>{p.pricing.T1 === 0 ? "—" : "$" + (p.pricing.T1/1000) + "k+"}</b></div>
            </div>
            <div className="subtle" style={{ fontSize: 12, borderTop: "1px solid #F0EDE7", paddingTop: 9 }}>{p.note}</div>
          </div>
        ))}
      </div>

      {/* recent referral activity */}
      <RecentReferralActivity />

      {/* pending asks */}
      <div className="sec-head"><h2>Recommended intro requests</h2><span className="line"></span><span className="subtle" style={{ fontSize: 12 }}>{asks.length} pending</span></div>
      <div className="card" style={{ overflow: "hidden" }}>
        <table className="tbl">
          <thead><tr><th>Account</th><th>Introducer</th><th>Path</th><th className="num">Strength</th><th>Tier fee</th><th></th></tr></thead>
          <tbody>
            {asks.map(({ a, intro }) => (
              <tr key={a.id} onClick={() => onOpen(a)}>
                <td><div className="acct-cell"><Logo name={a.brand} src={a.logo} size="sm" /><span className="nm">{a.brand}</span></div></td>
                <td><div className="row gap8"><Avatar name={intro.introducer} /><span style={{ fontWeight: 500 }}>{intro.introducer}</span></div></td>
                <td className="muted" style={{ fontSize: 12.5, maxWidth: 280 }}>{intro.via}</td>
                <td className="num"><div className="row gap8" style={{ justifyContent: "flex-end" }}><div className="bar" style={{ width: 50 }}><i style={{ width: (intro.degree*10)+"%" }}></i></div>{intro.degree}/10</div></td>
                <td className="mono">${(a.spend.perMeeting/1000)}k</td>
                <td><button className="btn pri sm" onClick={e => e.stopPropagation()}>Request</button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

/* ---------- CAC & Referral-Spend Tracker ------------------------------- */
function SpendView() {
  const I = window.ICP;
  const S = I.SPEND;
  const otherTotal = S.other.reduce((s, o) => s + o.amount, 0);
  const meetingSpend = S.byTier.reduce((s, t) => s + t.spend, 0);
  const totalCommitted = meetingSpend + otherTotal;
  const cpm = meetingSpend / Math.max(1, S.paidMeetings);
  const cac = (totalCommitted) / Math.max(1, S.paidMeetings); // simplistic
  const remaining = S.budget - totalCommitted;

  const kpis = [
    { v: "$" + (totalCommitted/1000).toFixed(1) + "k", l: "Committed · " + S.quarter, d: <span className="muted">of ${(S.budget/1000)}k budget</span> },
    { v: S.paidMeetings, l: "Paid meetings booked", d: <span className="up">across 6 accounts</span> },
    { v: "$" + (cpm/1000).toFixed(1) + "k", l: "Avg cost / meeting", d: <span className="muted">blended across tiers</span> },
    { v: "$" + (S.pipelineInfluenced/1000).toFixed(1) + "M", l: "Pipeline influenced", d: <span className="up">{(S.pipelineInfluenced*1000/totalCommitted).toFixed(0)}× spend</span> },
  ];

  return (
    <div className="page">
      <div className="sec-head" style={{ marginTop: 0 }}>
        <h2>CAC & referral-spend tracker</h2>
        <span className="line"></span>
        <button className="btn sm"><Icon name="download" size={14} />Export to finance</button>
      </div>
      <p className="muted" style={{ maxWidth: 720, marginBottom: 18 }}>
        The list, the leads, and the money in one place. Referral-program spend by tier sits alongside the accounts it influenced, so we always know our cost to acquire a meeting — and a customer.
      </p>

      <div className="kpis" style={{ marginBottom: 8 }}>
        {kpis.map((x, i) => (
          <div className="kpi" key={i}>
            <div className="v">{x.v}</div>
            <div className="l">{x.l}</div>
            <div className="d">{x.d}</div>
          </div>
        ))}
      </div>

      {/* budget bar */}
      <div className="card pad mt16">
        <div className="between" style={{ marginBottom: 8 }}>
          <span className="label-micro">Budget utilization · {S.quarter}</span>
          <span className="subtle" style={{ fontSize: 12 }}>${(totalCommitted/1000).toFixed(1)}k committed · ${(remaining/1000).toFixed(1)}k remaining</span>
        </div>
        <div className="bar" style={{ height: 14 }}>
          <i style={{ width: (meetingSpend/S.budget*100)+"%", background: "var(--c-malachyte)", float: "left" }}></i>
          <i style={{ width: (otherTotal/S.budget*100)+"%", background: "var(--c-lavender)", float: "left" }}></i>
        </div>
        <div className="row gap16 mt8">
          <span className="row gap6" style={{ fontSize: 12 }}><span className="dot" style={{ width: 9, height: 9, borderRadius: 2, background: "var(--c-malachyte)", display: "inline-block" }}></span>Meeting fees ${(meetingSpend/1000).toFixed(1)}k</span>
          <span className="row gap6" style={{ fontSize: 12 }}><span className="dot" style={{ width: 9, height: 9, borderRadius: 2, background: "var(--c-lavender)", display: "inline-block" }}></span>CAB retainer + tools ${(otherTotal/1000).toFixed(1)}k</span>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginTop: 16 }}>
        {/* by tier */}
        <div className="card pad">
          <div className="label-micro" style={{ marginBottom: 12 }}>Referral spend by tier</div>
          <table className="tbl" style={{ fontSize: 13 }}>
            <thead><tr><th>Tier</th><th className="num">Fee/mtg</th><th className="num">Meetings</th><th className="num">Spend</th><th className="num">Pipeline</th></tr></thead>
            <tbody>
              {S.byTier.map(t => (
                <tr key={t.tier} style={{ cursor: "default" }}>
                  <td><Tier t={t.tier} /></td>
                  <td className="num mono">${(t.perMeeting/1000)}k</td>
                  <td className="num">{t.meetings}</td>
                  <td className="num">${(t.spend/1000).toFixed(1)}k</td>
                  <td className="num">{t.influenced ? "$" + (t.influenced/1000).toFixed(1) + "M" : "—"}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        {/* other line items */}
        <div className="card pad">
          <div className="label-micro" style={{ marginBottom: 12 }}>Program & tooling spend</div>
          {S.other.map((o, i) => (
            <div className="between" key={i} style={{ padding: "11px 0", borderBottom: "1px solid #F0EDE7" }}>
              <span>{o.label}</span>
              <span style={{ fontWeight: 500 }}>${(o.amount/1000).toFixed(1)}k</span>
            </div>
          ))}
          <div className="between" style={{ padding: "11px 0" }}>
            <span className="muted">Decision pending</span>
            <span className="chip" style={{ background: "rgba(216,146,81,0.14)", color: "#9A5B1E" }}>SimilarWeb Sales Intel — adopt?</span>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { TunerView, SignalsView, RosterView, SpendView });
