/* Impact Tracker · Forecasting - the intelligence modules.
   Grounded in window.OPS + window.DATA. Exports both views.            */

/* ============================ IMPACT TRACKER ============================ */
function ImpactTracker({ onOpen }) {
  const D = window.DATA, O = window.OPS, fmt = D.fmtMoney;
  const avg = Math.round(O.impact.reduce((s, x) => s + x.score, 0) / (O.impact.length || 1));
  const beneficiaries = O.impact.reduce((s, x) => s + x.beneficiaries, 0);
  const totalMs = D.orgs.reduce((s, o) => s + D.milestoneHealth(o.id).total, 0);
  const metMs = D.orgs.reduce((s, o) => s + D.milestoneHealth(o.id).met, 0);
  const byDomain = D.domains.map((dm) => {
    const list = O.impact.filter((x) => x.domain === dm.id);
    const a = list.length ? Math.round(list.reduce((s, x) => s + x.score, 0) / list.length) : 0;
    return { dm, avg: a, n: list.length };
  }).filter((x) => x.n).sort((a, b) => b.avg - a.avg);
  const band = (s) => s >= 80 ? "var(--good)" : s >= 60 ? "var(--accent)" : s >= 45 ? "var(--warn)" : "var(--rose)";
  const top = O.impact[0];

  return (
    <ModulePage icon="trendingUp" eyebrow="Intelligence" title="Impact Tracker"
      subtitle="Track outcomes against every grant, roll them into a portfolio impact index, and see the difference your funding makes."
      actions={<button className="btn"><Icon name="document" size={15} /> Draft impact story</button>}>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 18, marginBottom: 20 }}>
        <StatTile icon="trendingUp" label="Portfolio impact index" value={avg} sub="weighted average / 100" accent />
        <StatTile icon="users" label="People reached" value={beneficiaries.toLocaleString("en-GB")} sub="estimated beneficiaries" color="var(--good)" />
        <StatTile icon="check" label="Milestones met" value={`${metMs}/${totalMs}`} sub={`${Math.round((metMs / totalMs) * 100)}% delivered`} />
        <StatTile icon="target" label="Outcomes on track" value={O.impact.filter((x) => x.mh.verdict !== "behind").length} sub={`of ${O.impact.length} funded grants`} color="var(--info)" />
      </div>

      <div style={{ marginBottom: 20 }}>
        <AINote title="Highest leverage" onAction={() => top && onOpen(top.org)} actionLabel={top ? `Open ${D.byId[top.org].name}` : "Review"}>
          {top ? <span><strong>{D.byId[top.org].name}</strong> returns the strongest impact per pound ({top.score}/100, ~{top.beneficiaries.toLocaleString("en-GB")} reached on {fmt(top.awarded)}). A renewal here compounds outcomes faster than a new grant of the same size.</span> : "No funded grants to assess yet."}
        </AINote>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 20, alignItems: "start" }}>
        <ModulePanel title="Impact by grant" icon="trendingUp" right={<span className="badge mono">{O.impact.length}</span>}>
          <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
            {O.impact.map((x) => {
              const o = D.byId[x.org];
              return (
                <button key={x.org} className="focusable" onClick={() => onOpen(x.org)} style={{ display: "flex", alignItems: "center", gap: 12, width: "100%", textAlign: "left", padding: "10px 12px", border: "1px solid var(--border)", borderRadius: 11, background: "var(--surface-2)", cursor: "pointer" }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{o.name}</div>
                    <div style={{ fontSize: 11.5, color: "var(--text-muted)", marginTop: 4 }}>~{x.beneficiaries.toLocaleString("en-GB")} reached · {x.mh.met}/{x.mh.total} milestones</div>
                  </div>
                  <div style={{ width: 90, flex: "none" }}>
                    <div style={{ height: 6, borderRadius: 5, background: "var(--surface-3)", overflow: "hidden" }}><div style={{ width: x.score + "%", height: "100%", background: band(x.score), borderRadius: 5 }} /></div>
                  </div>
                  <span className="mono" style={{ fontSize: 14, fontWeight: 700, color: band(x.score), width: 26, textAlign: "right" }}>{x.score}</span>
                </button>
              );
            })}
          </div>
        </ModulePanel>

        <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
          <ModulePanel title="Impact by domain" icon="grid">
            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              {byDomain.map((x) => (
                <div key={x.dm.id} style={{ display: "flex", alignItems: "center", gap: 12 }}>
                  <div style={{ width: 116, flex: "none", display: "flex", alignItems: "center", gap: 7, fontSize: 12.5, color: "var(--text-muted)" }}><span style={{ width: 8, height: 8, borderRadius: 999, background: domainColor(x.dm.id) }} />{x.dm.label}</div>
                  <div style={{ flex: 1, height: 8, borderRadius: 5, background: "var(--surface-3)", overflow: "hidden" }}><div style={{ width: x.avg + "%", height: "100%", background: domainColor(x.dm.id), borderRadius: 5 }} /></div>
                  <span className="mono" style={{ width: 26, textAlign: "right", fontSize: 12.5, color: "var(--text-muted)" }}>{x.avg}</span>
                </div>
              ))}
            </div>
          </ModulePanel>
          <ModulePanel title="Outcome health" icon="target">
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              {[["met", "Delivered", "var(--good)"], ["on-track", "On track", "var(--info)"], ["at-risk", "At risk", "var(--warn)"], ["behind", "Behind", "var(--rose)"]].map(([v, label, c]) => {
                const n = O.impact.filter((x) => x.mh.verdict === v).length;
                return (
                  <div key={v} style={{ display: "flex", alignItems: "center", gap: 10 }}>
                    <span style={{ width: 9, height: 9, borderRadius: 999, background: c, flex: "none" }} />
                    <span style={{ flex: 1, fontSize: 13 }}>{label}</span>
                    <span className="mono" style={{ fontSize: 13, fontWeight: 600 }}>{n}</span>
                  </div>
                );
              })}
            </div>
          </ModulePanel>
        </div>
      </div>
    </ModulePage>
  );
}

/* ============================ FORECASTING ============================ */
function Forecasting({ onOpen }) {
  const D = window.DATA, O = window.OPS, fmt = D.fmtMoney;
  const maxV = Math.max(...O.forecastSeries.flatMap((s) => [s.committed, s.projected]));
  const nextQ = O.forecastSeries[0];
  const runwayQ = Math.max(1, Math.round(O.reserves / (nextQ.projected || 1)));

  return (
    <ModulePage icon="globe" eyebrow="Intelligence" title="Forecasting"
      subtitle="Model future funding scenarios, predict which relationships are cooling, and anticipate demand before it lands on your desk."
      actions={<button className="btn"><Icon name="sliders" size={15} /> Adjust scenario</button>}>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 18, marginBottom: 20 }}>
        <StatTile icon="funding" label={`Projected ${nextQ.q}`} value={fmt(nextQ.projected)} sub="modelled commitment" accent />
        <StatTile icon="layers" label="Reserve runway" value={`~${runwayQ} qtrs`} sub="at projected pace" />
        <StatTile icon="signal" label="At-risk relationships" value={O.atRisk.length} sub="predicted to cool" color="var(--rose)" />
        <StatTile icon="trendingUp" label="Top rising demand" value={O.demandByDomain[0] ? O.demandByDomain[0].label.split(" ")[0] : "-"} sub={O.demandByDomain[0] ? `index ${O.demandByDomain[0].demandIndex}` : ""} color="var(--warn)" />
      </div>

      <div style={{ marginBottom: 20 }}>
        <AINote title="Scenario insight">
          Projected commitments outpace committed spend by <strong>{fmt(nextQ.projected - nextQ.committed)}</strong> next quarter. Demand is rising fastest in
          <strong> {O.demandByDomain[0] ? O.demandByDomain[0].label : "-"}</strong> - consider opening a targeted round there before reserves tighten.
        </AINote>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr", gap: 20, alignItems: "start" }}>
        <ModulePanel title="Commitment forecast" icon="analytics" right={<span style={{ display: "inline-flex", gap: 14, fontSize: 11.5, color: "var(--text-muted)" }}><span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}><span style={{ width: 10, height: 10, borderRadius: 3, background: "var(--surface-3)" }} />Committed</span><span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}><span style={{ width: 10, height: 10, borderRadius: 3, background: "var(--accent)" }} />Projected</span></span>}>
          <div style={{ display: "flex", alignItems: "flex-end", gap: 20, height: 220, padding: "8px 4px 0" }}>
            {O.forecastSeries.map((s) => (
              <div key={s.q} style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", gap: 8 }}>
                <div style={{ flex: 1, width: "100%", display: "flex", alignItems: "flex-end", justifyContent: "center", gap: 6 }}>
                  <div title={fmt(s.committed)} style={{ width: 26, height: (s.committed / maxV * 100) + "%", background: "var(--surface-3)", borderRadius: "5px 5px 0 0" }} />
                  <div title={fmt(s.projected)} style={{ width: 26, height: (s.projected / maxV * 100) + "%", background: "var(--accent)", borderRadius: "5px 5px 0 0" }} />
                </div>
                <div style={{ fontSize: 11.5, color: "var(--text-muted)", fontWeight: 600 }}>{s.q}</div>
              </div>
            ))}
          </div>
        </ModulePanel>

        <ModulePanel title="Demand by domain" icon="globe">
          <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
            {O.demandByDomain.map((x) => (
              <div key={x.domain} style={{ display: "flex", alignItems: "center", gap: 11 }}>
                <div style={{ width: 110, flex: "none", display: "flex", alignItems: "center", gap: 7, fontSize: 12.5, color: "var(--text-muted)" }}><span style={{ width: 8, height: 8, borderRadius: 999, background: domainColor(x.domain) }} />{x.label}</div>
                <div style={{ flex: 1, height: 8, borderRadius: 5, background: "var(--surface-3)", overflow: "hidden" }}><div style={{ width: x.demandIndex + "%", height: "100%", background: domainColor(x.domain), borderRadius: 5 }} /></div>
                <span className="mono" style={{ width: 44, textAlign: "right", fontSize: 11.5, color: x.trend >= 0 ? "var(--good)" : "var(--rose)" }}>{x.trend >= 0 ? "+" : ""}{x.trend}%</span>
              </div>
            ))}
          </div>
        </ModulePanel>
      </div>

      <ModulePanel title="Relationships predicted to cool" icon="signal" iconColor="var(--rose)" style={{ marginTop: 20 }} right={<span className="badge mono">{O.atRisk.length}</span>}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 10 }}>
          {O.atRisk.map((x) => {
            const o = D.byId[x.org];
            return (
              <button key={x.org} className="focusable" onClick={() => onOpen(x.org)} style={{ display: "flex", alignItems: "center", gap: 11, padding: "11px 13px", border: "1px solid var(--border)", borderRadius: 11, background: "var(--surface-2)", cursor: "pointer", textAlign: "left" }}>
                <span style={{ width: 8, height: 8, borderRadius: 999, background: domainColor(o.domain), flex: "none" }} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, fontWeight: 600 }}>{o.name}</div>
                  <div style={{ fontSize: 11.5, color: "var(--text-muted)" }}>{x.reason}</div>
                </div>
                <span className="mono" style={{ fontSize: 12, color: "var(--rose)" }}>{x.confidence}%</span>
              </button>
            );
          })}
        </div>
      </ModulePanel>
    </ModulePage>
  );
}

window.ImpactTracker = ImpactTracker;
window.Forecasting = Forecasting;
