// =================================================================
// screens-runhistory.jsx — Scoring-run "wayback" history.
//
//   RunHistoryScreen — /run-history (superadmin + consultant)
//
// Calendar of dates that have a captured scoring run (marked with score),
// two-date compare (per-factor movement), and a company outcomes log.
// Fully self-contained; backend at /api/v1/tenants/{tenant}/scoring/...
// Capture is superadmin-gated (System Settings → Wayback capture) and OFF
// by default, so an empty calendar is the expected pre-activation state.
// =================================================================

const RH_BAND_COLOR = {
  category_authority:     "var(--good)",
  emerging_authority:     "var(--accent)",
  visible_underleveraged: "var(--warn)",
  low_trust_density:      "#b88a00",
  weak_authority:         "var(--bad)",
};
const RH_MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const RH_DOW = ["S", "M", "T", "W", "T", "F", "S"];

const rhPad = (n) => String(n).padStart(2, "0");
const rhKey = (y, m, d) => `${y}-${rhPad(m + 1)}-${rhPad(d)}`;

// Build the [year, month] pairs for the trailing `count` months (oldest → newest).
const rhRecentMonths = (count) => {
  const now = new Date();
  const out = [];
  for (let i = count - 1; i >= 0; i--) {
    const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
    out.push([d.getFullYear(), d.getMonth()]);
  }
  return out;
};

// ---------- One month grid ----------
const RhMonth = ({ year, month, marks, selected, onPick }) => {
  const first = new Date(year, month, 1).getDay();
  const days = new Date(year, month + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < first; i++) cells.push(null);
  for (let d = 1; d <= days; d++) cells.push(d);

  return (
    <div style={{ border: "1px solid var(--line)", borderRadius: 10, padding: 12, background: "var(--panel)" }}>
      <div style={{ fontWeight: 600, fontSize: 13, marginBottom: 8 }}>{RH_MONTHS[month]} {year}</div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 3 }}>
        {RH_DOW.map((d, i) => (
          <div key={`h${i}`} style={{ textAlign: "center", fontSize: 10, color: "var(--muted-2)", paddingBottom: 2 }}>{d}</div>
        ))}
        {cells.map((d, i) => {
          if (d === null) return <div key={`e${i}`}/>;
          const k = rhKey(year, month, d);
          const mark = marks[k];
          const isSel = selected.includes(k);
          const base = {
            height: 30, borderRadius: 6, display: "flex", alignItems: "center", justifyContent: "center",
            fontSize: 12, position: "relative",
          };
          if (!mark) {
            return <div key={k} style={{ ...base, color: "var(--muted-2)" }}>{d}</div>;
          }
          const color = RH_BAND_COLOR[mark.score_band] || "var(--accent)";
          return (
            <button
              key={k}
              title={`${k} · score ${mark.final_score ?? "—"}${mark.run_count > 1 ? ` · ${mark.run_count} runs` : ""}`}
              onClick={() => onPick(k)}
              style={{
                ...base, cursor: "pointer", fontWeight: 600,
                border: isSel ? "2px solid var(--accent)" : "1px solid var(--line)",
                background: isSel ? "var(--accent-soft)" : "var(--panel-2)",
                color: "var(--ink)",
              }}
            >
              {d}
              <span style={{
                position: "absolute", bottom: 3, left: "50%", transform: "translateX(-50%)",
                width: 5, height: 5, borderRadius: "50%", background: color,
              }}/>
            </button>
          );
        })}
      </div>
    </div>
  );
};

const RunHistoryScreen = () => {
  const [companies, setCompanies] = React.useState([]);
  const [companyId, setCompanyId] = React.useState("");
  const [selected, setSelected] = React.useState([]);   // up to 2 YYYY-MM-DD
  const [compare, setCompare] = React.useState(null);
  const [comparing, setComparing] = React.useState(false);
  const [cmpErr, setCmpErr] = React.useState(null);

  // Companies for the active tenant (reuses the standard list endpoint).
  React.useEffect(() => {
    let alive = true;
    window.api.tcall("listCompanies")
      .then((rows) => { if (alive) setCompanies(Array.isArray(rows) ? rows : []); })
      .catch(() => { if (alive) setCompanies([]); });
    return () => { alive = false; };
  }, [window.session?.tenantId]);

  const months = rhRecentMonths(6);
  const fromD = rhKey(months[0][0], months[0][1], 1);
  const now = new Date();
  const toD = rhKey(now.getFullYear(), now.getMonth(), now.getDate());

  // Calendar markers (DB-only; cheap). Empty until a company is picked.
  const { rows: calRows, live, loading } = useLive(
    () => companyId
      ? window.api.tcall("scoringRunsCalendar", { companyId }, null, { qs: `?from=${fromD}&to=${toD}` })
      : Promise.resolve([]),
    [],
    [window.session?.tenantId, companyId],
  );
  const calendar = Array.isArray(calRows) ? calRows : [];
  const marks = React.useMemo(() => {
    const m = {};
    calendar.forEach((r) => { m[r.run_date] = r; });
    return m;
  }, [calendar]);

  // Outcomes log.
  const { rows: outRows, refresh: refreshOutcomes } = useLive(
    () => companyId ? window.api.tcall("companyOutcomes", { companyId }) : Promise.resolve([]),
    [],
    [window.session?.tenantId, companyId],
  );
  const outcomes = Array.isArray(outRows) ? outRows : [];

  const companyOpts = [
    { label: "Select a company…", value: "" },
    ...companies.map((c) => ({ label: c.is_client ? `${c.name} (client)` : c.name, value: c.id })),
  ];

  const resetSelection = () => { setSelected([]); setCompare(null); setCmpErr(null); };

  const pickDate = (k) => {
    setCompare(null); setCmpErr(null);
    setSelected((prev) => {
      if (prev.includes(k)) return prev.filter((x) => x !== k);
      if (prev.length >= 2) return [prev[1], k];   // keep the most recent two
      return [...prev, k];
    });
  };

  // Auto-compare once two dates are picked.
  React.useEffect(() => {
    if (selected.length !== 2 || !companyId) return;
    const [a, b] = [...selected].sort();   // chronological: a = earlier, b = later
    setComparing(true); setCmpErr(null);
    window.api.tcall("scoringRunCompare", { companyId }, null, { qs: `?date_a=${a}&date_b=${b}` })
      .then((res) => setCompare(res))
      .catch(() => setCmpErr("Could not load the comparison for those dates."))
      .finally(() => setComparing(false));
  }, [selected, companyId]);

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "var(--gap)" }}>
      <ScreenHeader
        icon={<IconList size={22}/>}
        title="Run History"
        subtitle="Wayback record of scoring runs — pick two marked dates to compare."
        right={
          <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
            <div style={{ width: 240 }}>
              <Select value={companyId} onChange={(v) => { setCompanyId(v); resetSelection(); }} options={companyOpts}/>
            </div>
            {companyId && <LiveBadge live={live} loading={loading}/>}
          </div>
        }/>

      {!companyId ? (
        <Card>
          <EmptyState icon={<IconBuilding size={32}/>} title="Pick a company"
            description="Choose a company to see its captured scoring runs on the calendar."/>
        </Card>
      ) : (
        <>
          <Card title="Run calendar" subtitle="Dots mark dates with a captured run; color = score band. Click two dates to compare.">
            {loading ? (
              <div style={{ padding: 24, color: "var(--muted)", fontSize: 13 }}>Loading…</div>
            ) : calendar.length === 0 ? (
              <EmptyState icon={<IconList size={32}/>} title="No runs captured yet"
                description="Runs are archived only after a superadmin enables Wayback capture (System Settings) and an assessment is scored."/>
            ) : (
              <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))", gap: 12 }}>
                {months.map(([y, m]) => (
                  <RhMonth key={`${y}-${m}`} year={y} month={m} marks={marks} selected={selected} onPick={pickDate}/>
                ))}
              </div>
            )}
            {selected.length > 0 && (
              <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: 14, flexWrap: "wrap" }}>
                <span style={{ fontSize: 13, color: "var(--muted)" }}>Selected:</span>
                {selected.map((s) => (
                  <span key={s} style={{ fontSize: 12, fontFamily: "var(--mono)", padding: "3px 8px",
                    borderRadius: 12, background: "var(--accent-soft)", color: "var(--accent)" }}>{s}</span>
                ))}
                <Btn kind="secondary" size="sm" onClick={resetSelection}>Clear</Btn>
                {selected.length === 1 && <span style={{ fontSize: 12, color: "var(--muted-2)" }}>Pick one more date to compare.</span>}
              </div>
            )}
          </Card>

          {(comparing || compare || cmpErr) && (
            <Card title="Comparison"
              subtitle={compare ? `${compare.run_a.run_date} → ${compare.run_b.run_date}` : null}>
              {comparing ? (
                <div style={{ padding: 16, color: "var(--muted)", fontSize: 13 }}>Comparing…</div>
              ) : cmpErr ? (
                <Banner tone="warn" icon={<IconInfo size={16}/>}>{cmpErr}</Banner>
              ) : compare ? (
                <RhCompare compare={compare}/>
              ) : null}
            </Card>
          )}

          <Card title="Outcomes"
            subtitle="Funding, acquisition and other events — recorded to correlate with score trajectory."
            action={null}>
            <RhOutcomes companyId={companyId} outcomes={outcomes} onAdded={refreshOutcomes}/>
          </Card>
        </>
      )}
    </div>
  );
};

// ---------- Compare panel ----------
const RhCompare = ({ compare }) => {
  const a = compare.run_a, b = compare.run_b;
  const delta = compare.score_delta;
  const dColor = delta == null ? "var(--muted)" : delta >= 0 ? "var(--good)" : "var(--bad)";
  const moves = (compare.factor_moves || []).filter((m) => Math.abs(m.delta) > 0.001);

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 16, flexWrap: "wrap" }}>
        <div style={{ fontSize: 13, color: "var(--muted)" }}>
          Overall&nbsp;
          <span style={{ fontFamily: "var(--mono)" }}>{a.final_score ?? "—"} → {b.final_score ?? "—"}</span>
        </div>
        <div style={{ fontWeight: 700, fontSize: 18, color: dColor }}>
          {delta == null ? "—" : `${delta >= 0 ? "+" : ""}${delta.toFixed(1)}`}
        </div>
        {(a.archived || b.archived) && (
          <span style={{ fontSize: 11, color: "var(--muted-2)" }}>
            (rehydrated from archive)
          </span>
        )}
      </div>

      {moves.length === 0 ? (
        <div style={{ fontSize: 13, color: "var(--muted)" }}>No factor-level changes between these runs.</div>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
          {moves.map((m) => (
            <div key={m.factor_key} style={{ display: "flex", alignItems: "center", justifyContent: "space-between",
              gap: 12, fontSize: 13, padding: "4px 0", borderBottom: "1px solid var(--line-2)" }}>
              <span>{m.label} <span style={{ color: "var(--muted-2)", fontSize: 11 }}>· {m.layer}</span></span>
              <span style={{ display: "flex", alignItems: "center", gap: 10, flexShrink: 0 }}>
                <span style={{ fontFamily: "var(--mono)", fontSize: 12, color: "var(--muted)" }}>
                  {m.from_score.toFixed(1)}→{m.to_score.toFixed(1)}
                </span>
                <span style={{ color: m.delta >= 0 ? "var(--good)" : "var(--bad)", fontWeight: 600, minWidth: 42, textAlign: "right" }}>
                  {m.delta >= 0 ? "+" : ""}{m.delta.toFixed(1)}
                </span>
              </span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

// ---------- Outcomes list + add form ----------
const RH_OUTCOME_TYPES = [
  { label: "Funding round", value: "funding_round" },
  { label: "Acquisition", value: "acquisition" },
  { label: "IPO", value: "ipo" },
  { label: "Shutdown", value: "shutdown" },
  { label: "Other", value: "other" },
];

const RhOutcomes = ({ companyId, outcomes, onAdded }) => {
  const [open, setOpen] = React.useState(false);
  const [form, setForm] = React.useState({ event_type: "funding_round", event_date: "", round_label: "", amount: "", currency: "USD", notes: "" });
  const [saving, setSaving] = React.useState(false);
  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));
  const canSave = form.event_date && !saving;

  const submit = async () => {
    setSaving(true);
    try {
      const body = {
        event_type: form.event_type,
        event_date: new Date(form.event_date).toISOString(),
        round_label: form.round_label || null,
        amount: form.amount ? Number(form.amount) : null,
        currency: form.currency || null,
        notes: form.notes || null,
      };
      await window.api.tcall("companyOutcomesCreate", { companyId }, body);
      window.__toast && window.__toast("Outcome recorded");
      setOpen(false);
      setForm({ event_type: "funding_round", event_date: "", round_label: "", amount: "", currency: "USD", notes: "" });
      onAdded && onAdded();
    } catch (e) {
      window.__toast && window.__toast("Could not save outcome", "warn");
    } finally {
      setSaving(false);
    }
  };

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <div style={{ display: "flex", justifyContent: "flex-end" }}>
        <Btn kind={open ? "secondary" : "primary"} size="sm" onClick={() => setOpen((o) => !o)}>
          {open ? "Cancel" : "Add outcome"}
        </Btn>
      </div>

      {open && (
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", gap: 10,
          padding: 14, border: "1px solid var(--line)", borderRadius: 10, background: "var(--panel-2)" }}>
          <FormField label="Type">
            <Select value={form.event_type} onChange={(v) => set("event_type", v)} options={RH_OUTCOME_TYPES}/>
          </FormField>
          <FormField label="Date">
            <Input type="date" value={form.event_date} onChange={(e) => set("event_date", e.target.value)}/>
          </FormField>
          <FormField label="Round / label">
            <Input value={form.round_label} onChange={(e) => set("round_label", e.target.value)} placeholder="series_a"/>
          </FormField>
          <FormField label="Amount">
            <Input type="number" value={form.amount} onChange={(e) => set("amount", e.target.value)} placeholder="5000000"/>
          </FormField>
          <FormField label="Currency">
            <Input value={form.currency} onChange={(e) => set("currency", e.target.value)} placeholder="USD"/>
          </FormField>
          <FormField label="Notes">
            <Input value={form.notes} onChange={(e) => set("notes", e.target.value)} placeholder="Led by…"/>
          </FormField>
          <div style={{ gridColumn: "1 / -1", display: "flex", justifyContent: "flex-end" }}>
            <Btn kind="primary" size="sm" disabled={!canSave} onClick={submit}>{saving ? "Saving…" : "Save outcome"}</Btn>
          </div>
        </div>
      )}

      {outcomes.length === 0 ? (
        <div style={{ fontSize: 13, color: "var(--muted)", padding: "8px 0" }}>No outcomes recorded yet.</div>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
          {outcomes.map((o) => (
            <div key={o.id} style={{ display: "flex", alignItems: "center", justifyContent: "space-between",
              gap: 12, fontSize: 13, padding: "6px 0", borderBottom: "1px solid var(--line-2)" }}>
              <span>
                <strong style={{ textTransform: "capitalize" }}>{(o.event_type || "").replace(/_/g, " ")}</strong>
                {o.round_label ? ` · ${o.round_label}` : ""}
                {o.notes ? <span style={{ color: "var(--muted)" }}> — {o.notes}</span> : null}
              </span>
              <span style={{ display: "flex", gap: 12, alignItems: "center", flexShrink: 0, color: "var(--muted)" }}>
                {o.amount != null && <span style={{ fontFamily: "var(--mono)" }}>{o.currency || ""} {Number(o.amount).toLocaleString()}</span>}
                <span>{(o.event_date || "").slice(0, 10)}</span>
              </span>
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

Object.assign(window, { RunHistoryScreen });
