/* Stratum Leads — Operations Console. Lead Intelligence: the source-discovery
   + scoring pipeline dashboard. Ported (UI/UX only) from the stale
   `stratum-lead-intelligence` concept — 100% mock, shaped to the Phase-2 read
   models (source_run_status, run_exception) so wiring is a drop-in.

   Workflow bridge: this surface produces freshly-scored candidates and hands
   them to Lead Review (leadops) via onPublishToReview — the same queue the
   verify/reject page consumes. That is the seam where the discovery workflow
   and the review workflow meet. */

/* Design-system components — each Babel script has its own scope, so every
   ops-*.jsx file must destructure what it needs from the namespace. */
const { NavItem, IconButton, Tabs, Button, Field, Card, Metric, StatusChip, TierBadge, ContactQuality, ProgressBar, SegmentedControl, Switch, EmptyState } = window.StratumLeadsDesignSystem_6367ed;

const { I, Spinner } = window.OpsShared;

const clone = (x) => JSON.parse(JSON.stringify(x));

const STAGE_TONE = { ok: "success", warn: "warning", blocked: "danger" };
const SOURCE_TONE = { healthy: "success", degraded: "warning", blocked: "danger" };
const SOURCE_LABEL = { healthy: "Healthy", degraded: "Degraded", blocked: "Blocked" };

const usdK = (n) => n ? "$" + Math.round(n / 1000).toLocaleString() + "k" : "—";

/* ---------------- Pipeline strip ---------------- */
function PipelineStrip({ pipeline, run, activeStage }) {
  return (
    <div style={{ display: "flex", alignItems: "stretch", gap: 0, overflowX: "auto", paddingBottom: 4 }}>
      {pipeline.map((s, i) => {
        const isActive = run === "running" && i === activeStage;
        const isDone = run === "done" || run === "running" && i < activeStage;
        const dotTone = STAGE_TONE[s.status] || "neutral";
        return (
          <React.Fragment key={s.key}>
            <div style={{ flex: "1 0 150px", minWidth: 150, border: "1px solid var(--border)", borderRadius: "var(--radius-md)", padding: "12px 14px", background: isActive ? "var(--accent-soft)" : "var(--surface)", borderColor: isActive ? "var(--accent)" : "var(--border)", transition: "background var(--dur-fast), border-color var(--dur-fast)", display: "grid", gap: 6, alignContent: "start" }}>
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 }}>
                <span style={{ width: 30, height: 30, display: "grid", placeItems: "center", borderRadius: "50%", background: isActive ? "var(--surface)" : "var(--accent-soft)", color: "var(--accent)", flexShrink: 0 }}>
                  {isActive ? <Spinner size={15} /> : I(s.icon, { width: 15 })}
                </span>
                {isDone ? I("check", { width: 15, color: "var(--success)" }) : <span style={{ width: 7, height: 7, borderRadius: "50%", background: `var(--${dotTone})` }} />}
              </div>
              <span style={{ fontSize: 11, color: "var(--text-muted)", fontWeight: 600 }}>{s.label}</span>
              <strong style={{ fontSize: 20, fontWeight: 800, fontVariantNumeric: "tabular-nums", lineHeight: 1 }}>{s.count.toLocaleString()}</strong>
              <span style={{ fontSize: 10.5, color: "var(--text-subtle)" }}>{s.note}</span>
            </div>
            {i < pipeline.length - 1 &&
            <div style={{ flex: "0 0 22px", display: "grid", placeItems: "center", color: "var(--text-subtle)" }}>{I("chevron-right", { width: 16 })}</div>
            }
          </React.Fragment>);

      })}
    </div>);

}

/* ---------------- Tier distribution ---------------- */
function TierDistribution({ dist }) {
  const max = Math.max(...dist.map((d) => d.count), 1);
  const total = dist.reduce((a, d) => a + d.count, 0);
  return (
    <div style={{ display: "grid", gap: 10 }}>
      {dist.map((d) => {
        const pct = Math.round(d.count / max * 100);
        const share = Math.round(d.count / total * 100);
        return (
          <div key={d.tier} style={{ display: "grid", gridTemplateColumns: "48px 1fr auto", alignItems: "center", gap: 12 }}>
            <TierBadge tier={d.tier} />
            <div style={{ height: 10, borderRadius: "var(--radius-pill)", background: "var(--surface-sunken)", overflow: "hidden" }}>
              <div style={{ width: `${pct}%`, height: "100%", borderRadius: "var(--radius-pill)", background: "var(--accent)", transition: "width 0.6s cubic-bezier(.22,.7,.2,1)" }} />
            </div>
            <span style={{ fontSize: 12.5, color: "var(--text-muted)", fontVariantNumeric: "tabular-nums", minWidth: 74, textAlign: "right" }}>{d.count} · {share}%</span>
          </div>);

      })}
    </div>);

}

/* ---------------- Source run-status table ---------------- */
function SourceTable({ sources }) {
  return (
    <div style={{ overflowX: "auto" }}>
      <div style={{ minWidth: 720 }}>
        <div style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr 0.9fr 0.7fr 0.7fr 1fr", gap: 12, padding: "0 12px 10px", fontSize: 11, fontWeight: 700, color: "var(--text-subtle)", textTransform: "uppercase", letterSpacing: "0.03em" }}>
          <span>Source</span><span>Type</span><span>Method</span><span style={{ textAlign: "right" }}>Found</span><span style={{ textAlign: "right" }}>New</span><span>Status</span>
        </div>
        {sources.map((s, i) =>
        <div key={s.id} style={{ display: "grid", gridTemplateColumns: "1.6fr 1fr 0.9fr 0.7fr 0.7fr 1fr", gap: 12, alignItems: "center", padding: "12px", borderTop: "1px solid var(--border-subtle)" }}>
            <span style={{ minWidth: 0 }}>
              <strong style={{ display: "block", fontSize: 13, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{s.name}</strong>
              <span style={{ fontSize: 11.5, color: "var(--text-muted)" }}>{s.region}</span>
              {s.issue && <span style={{ display: "block", fontSize: 11, color: `var(--${SOURCE_TONE[s.status]})`, marginTop: 3 }}>{s.issue}</span>}
            </span>
            <span style={{ fontSize: 12.5, color: "var(--text-muted)" }}>{s.kind}</span>
            <StatusChip tone={s.method === "Playwright" ? "violet" : "neutral"}>{s.method}</StatusChip>
            <span style={{ fontSize: 12.5, textAlign: "right", fontVariantNumeric: "tabular-nums" }}>{s.discovered}</span>
            <span style={{ fontSize: 12.5, textAlign: "right", fontVariantNumeric: "tabular-nums", fontWeight: 700 }}>{s.newCount}</span>
            <span style={{ display: "flex", flexDirection: "column", gap: 2 }}>
              <StatusChip tone={SOURCE_TONE[s.status]} dot>{SOURCE_LABEL[s.status]}</StatusChip>
              <span style={{ fontSize: 10.5, color: "var(--text-subtle)" }}>{s.lastRun} · next {s.nextRun}</span>
            </span>
          </div>
        )}
      </div>
    </div>);

}

/* ---------------- Candidate batch → Lead Review ---------------- */
function CandidateBatch({ candidates, onSend, onOpenReview, sentBatch }) {
  if (candidates.length === 0) {
    return (
      <EmptyState
        icon={sentBatch ? "check-circle-2" : "inbox"}
        title={sentBatch ? `${sentBatch} sent to Lead Review` : "Batch cleared"}
        message={sentBatch ? "The scored batch is now in the verify/reject queue." : "Run a source intelligence pass to score a fresh batch."}
        action={sentBatch ? <Button size="sm" variant="secondary" icon={I("arrow-right", { width: 15 })} onClick={onOpenReview}>Open Lead Review</Button> : null} />);

  }
  return (
    <div style={{ display: "grid", gap: 10 }}>
      <div style={{ maxHeight: 260, overflowY: "auto", display: "grid", gap: 8 }}>
        {candidates.map((c) =>
        <div key={c.id} style={{ display: "grid", gridTemplateColumns: "auto 1fr auto", alignItems: "center", gap: 10, padding: "8px 10px", border: "1px solid var(--border-subtle)", borderRadius: "var(--radius-sm)", background: "var(--surface)" }}>
            <TierBadge tier={c.tier} />
            <span style={{ minWidth: 0 }}>
              <strong style={{ display: "block", fontSize: 12.5, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{c.address}</strong>
              <span style={{ fontSize: 11, color: "var(--text-muted)" }}>{c.cityZip} · {c.trigger}</span>
            </span>
            <span style={{ display: "grid", justifyItems: "end", gap: 1, whiteSpace: "nowrap" }}>
              <strong style={{ fontSize: 12.5, fontVariantNumeric: "tabular-nums" }}>{c.score}<span style={{ color: "var(--text-subtle)", fontWeight: 600 }}>/100</span></strong>
              <span style={{ fontSize: 10.5, color: "var(--text-subtle)" }}>{usdK(c.estValue)}</span>
            </span>
          </div>
        )}
      </div>
      <Button variant="primary" fullWidth icon={I("upload-cloud", { width: 16 })} onClick={onSend}>
        Send {candidates.length} to Lead Review
      </Button>
    </div>);

}

/* ---------------- Page ---------------- */
function LeadIntelPage({ intel, onPublishToReview, onNavigate, reviewPendingCount }) {
  const [equityFloor, setEquityFloor] = React.useState(intel.equityFloor);
  const [run, setRun] = React.useState("idle");
  const [activeStage, setActiveStage] = React.useState(-1);
  const [candidates, setCandidates] = React.useState(() => clone(intel.candidates));
  const [lastRun, setLastRun] = React.useState(() => clone(intel.lastRun));
  const [sentBatch, setSentBatch] = React.useState(0);
  const timers = React.useRef([]);
  React.useEffect(refresh, [run, activeStage, candidates.length, sentBatch]);
  React.useEffect(() => () => timers.current.forEach(clearTimeout), []);

  const running = run === "running";

  const runPass = () => {
    if (running) return;
    timers.current.forEach(clearTimeout);
    timers.current = [];
    setRun("running");
    setActiveStage(0);
    setSentBatch(0);
    const stepMs = 520;
    intel.pipeline.forEach((_, i) => {
      timers.current.push(setTimeout(() => setActiveStage(i), i * stepMs));
    });
    timers.current.push(setTimeout(() => {
      setRun("done");
      setActiveStage(intel.pipeline.length - 1);
      setLastRun((r) => ({ ...r, at: "Just now" }));
      setCandidates(clone(intel.candidates));
    }, intel.pipeline.length * stepMs));
  };

  const sendToReview = () => {
    if (candidates.length === 0) return;
    onPublishToReview(candidates);
    setSentBatch(candidates.length);
    setCandidates([]);
  };

  return (
    <div style={{ padding: 24, width: "100%", maxWidth: "var(--page-max)" }}>
      <PageHeader
        eyebrow="Lead Operations"
        title="Lead Intelligence"
        description="Source discovery through scoring, in one pass. Freshly-scored leads flow straight into Lead Review."
        actions={
        <Button variant="primary" disabled={running} icon={running ? <Spinner size={14} /> : I("radar", { width: 15 })} onClick={runPass}>
            {running ? "Running pass…" : "Run Source Intelligence Pass"}
          </Button>
        } />

      <Reveal style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px,1fr))", gap: 14, marginBottom: 22 }}>
        <Metric icon={I("database")} value={lastRun.scanned.toLocaleString()} label="Records scanned" accent="violet" />
        <Metric icon={I("filter")} value={lastRun.eligible.toLocaleString()} label="Eligible leads" accent="cyan" />
        <Metric icon={I("layers")} value={lastRun.inPipeline.toLocaleString()} label="In pipeline" accent="violet" />
        <Metric icon={I("sparkles")} value={candidates.length} label="New candidates" accent="amber" />
        <div role="button" tabIndex={0} title="Open Lead Review" onClick={() => onNavigate("leadops")} onKeyDown={(e) => {if (e.key === "Enter" || e.key === " ") {e.preventDefault();onNavigate("leadops");}}} style={{ display: "grid", cursor: "pointer" }}>
          <Metric icon={I("list-checks")} value={reviewPendingCount != null ? reviewPendingCount : "—"} label="Awaiting review" accent="green" />
        </div>
      </Reveal>

      <Reveal delay={60}>
        <Card
          title="Discovery → scoring pipeline"
          note={`Last pass ${lastRun.at} · ${lastRun.durationLabel} · ${intel.model}`}
          actions={
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
              <span style={{ fontSize: 11.5, color: "var(--text-muted)", fontWeight: 600 }} title="Minimum estimated equity for a raw record to enter the pipeline.">Equity floor</span>
              <SegmentedControl value={String(equityFloor)} onChange={(v) => setEquityFloor(Number(v))} options={[{ value: "25000", label: "$25k" }, { value: "50000", label: "$50k" }, { value: "100000", label: "$100k" }]} />
            </div>
          }>
          <PipelineStrip pipeline={intel.pipeline} run={run} activeStage={activeStage} />
        </Card>
      </Reveal>

      <Reveal delay={100} style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20, alignItems: "start", marginTop: 20 }}>
        <Card title="Tier distribution" note={`${intel.tierDistribution.reduce((a, d) => a + d.count, 0)} scored leads, banded`}>
          <TierDistribution dist={intel.tierDistribution} />
        </Card>
        <Card
          title="New scored leads"
          note={reviewPendingCount != null ? `${reviewPendingCount} already awaiting review` : "Ready to hand to Lead Review"}
          actions={candidates.length > 0 ? <StatusChip tone="success" dot>{candidates.length} new</StatusChip> : null}>
          <CandidateBatch candidates={candidates} onSend={sendToReview} onOpenReview={() => onNavigate("leadops")} sentBatch={sentBatch} />
        </Card>
      </Reveal>

      <Reveal delay={140} style={{ marginTop: 20 }}>
        <Card title="Sources" note="Per source / county / adapter — run health and yield">
          <SourceTable sources={intel.sources} />
        </Card>
      </Reveal>
    </div>);

}

Object.assign(window, { OpsIntel: { LeadIntelPage } });
