/* Reports & Analytics - board-ready charts from the live ecosystem.
   Funding by domain, relationship mix, funding gap, milestone health,
   reach distribution, year-on-year, top grantees. Exports: Reports.
   All SVG charts, no deps.                                              */

function ReportCard({ title, sub, right, children, span }) {
  return (
    <div className="card" style={{ padding: 18, gridColumn: span ? `span ${span}` : "auto" }}>
      <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", marginBottom: 16, gap: 12 }}>
        <div>
          <div style={{ fontSize: 14, fontWeight: 650 }}>{title}</div>
          {sub && <div style={{ fontSize: 12, color: "var(--text-muted)", marginTop: 2 }}>{sub}</div>}
        </div>
        {right}
      </div>
      {children}
    </div>
  );
}

function Stat({ value, label, delta, deltaUp }) {
  return (
    <div>
      <div className="mono" style={{ fontSize: 25, fontWeight: 600, letterSpacing: "-0.03em", lineHeight: 1 }}>{value}</div>
      <div style={{ fontSize: 12, color: "var(--text-muted)", marginTop: 5 }}>{label}</div>
      {delta && <div style={{ fontSize: 11.5, color: deltaUp ? "var(--good)" : "var(--text-faint)", marginTop: 3, display: "inline-flex", alignItems: "center", gap: 3 }}>{deltaUp ? "▲" : "�ible"} {delta}</div>}
    </div>
  );
}

/* horizontal bar list */
function HBars({ rows, max, fmt }) {
  const m = max || Math.max(...rows.map((r) => r.value)) || 1;
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 11 }}>
      {rows.map((r, i) => (
        <div key={i} style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <div style={{ width: 132, flex: "none", display: "flex", alignItems: "center", gap: 7, fontSize: 12.5, color: "var(--text-muted)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
            {r.dot && <span style={{ width: 8, height: 8, borderRadius: 999, background: r.dot, flex: "none" }} />}{r.label}
          </div>
          <div style={{ flex: 1, height: 12, borderRadius: 6, background: "var(--surface-3)", overflow: "hidden" }}>
            <div style={{ width: (r.value / m * 100) + "%", height: "100%", background: r.color || "var(--accent)", borderRadius: 6 }} />
          </div>
          <div className="mono" style={{ width: 58, textAlign: "right", fontSize: 12, color: "var(--text-muted)" }}>{fmt ? fmt(r.value) : r.value}</div>
        </div>
      ))}
    </div>
  );
}

/* donut */
function Donut({ segments, size = 132, label, sub }) {
  const total = segments.reduce((s, x) => s + x.value, 0) || 1;
  const r = (size - 22) / 2, c = 2 * Math.PI * r;
  let acc = 0;
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 18 }}>
      <div style={{ position: "relative", width: size, height: size, flex: "none" }}>
        <svg width={size} height={size} style={{ transform: "rotate(-90deg)" }}>
          {segments.map((s, i) => {
            const frac = s.value / total, dash = c * frac, gap = c - dash, off = -acc * c;
            acc += frac;
            return <circle key={i} cx={size / 2} cy={size / 2} r={r} fill="none" stroke={s.color} strokeWidth="14" strokeDasharray={`${dash} ${gap}`} strokeDashoffset={off} />;
          })}
        </svg>
        <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", textAlign: "center" }}>
          <div><div className="mono" style={{ fontSize: 22, fontWeight: 650, lineHeight: 1 }}>{label}</div>{sub && <div style={{ fontSize: 10.5, color: "var(--text-faint)" }}>{sub}</div>}</div>
        </div>
      </div>
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {segments.map((s, i) => (
          <div key={i} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12.5 }}>
            <span style={{ width: 10, height: 10, borderRadius: 3, background: s.color, flex: "none" }} />
            <span style={{ color: "var(--text-muted)" }}>{s.label}</span>
            <span className="mono" style={{ marginLeft: "auto", fontWeight: 600 }}>{s.value}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

/* grouped column chart (year-on-year) */
function Columns({ groups, series }) {
  const W = 460, H = 180, padB = 26, padL = 8;
  const max = Math.max(...groups.flatMap((g) => series.map((s) => g[s.key]))) || 1;
  const gw = (W - padL) / groups.length;
  const bw = Math.min(26, (gw - 14) / series.length);
  return (
    <svg width="100%" viewBox={`0 0 ${W} ${H}`} style={{ display: "block" }}>
      {[0, 0.5, 1].map((t, i) => <line key={i} x1={padL} y1={(H - padB) * (1 - t)} x2={W} y2={(H - padB) * (1 - t)} stroke="var(--border)" strokeWidth="1" />)}
      {groups.map((g, gi) => (
        <g key={gi} transform={`translate(${padL + gi * gw}, 0)`}>
          {series.map((s, si) => {
            const h = (g[s.key] / max) * (H - padB - 8);
            const x = (gw - bw * series.length - (series.length - 1) * 4) / 2 + si * (bw + 4);
            return <rect key={si} x={x} y={H - padB - h} width={bw} height={h} rx="3" fill={s.color} />;
          })}
          <text x={gw / 2} y={H - 9} textAnchor="middle" fontSize="11" fill="var(--text-muted)" className="mono">{g.label}</text>
        </g>
      ))}
    </svg>
  );
}

function Reports({ onOpen, onNavigate }) {
  const D = window.DATA;
  const fmtMoney = D.fmtMoney;
  const totalAwarded = D.orgs.reduce((s, o) => s + (o.funding ? o.funding.awarded : 0), 0);

  // funding by domain
  const byDomain = D.domains.map((d) => ({
    label: d.label, dot: domainColor(d.id), color: domainColor(d.id),
    value: D.orgs.filter((o) => o.domain === d.id).reduce((s, o) => s + (o.funding ? o.funding.awarded : 0), 0),
  })).sort((a, b) => b.value - a.value);

  // relationship mix
  const relSeg = [
    { label: "Grantees", value: D.orgs.filter((o) => o.relationship === "Grantee").length, color: "var(--info)" },
    { label: "Supporters", value: D.orgs.filter((o) => o.relationship === "Active supporter").length, color: "var(--good)" },
    { label: "Prospects", value: D.orgs.filter((o) => o.relationship === "Prospect").length, color: "var(--warn)" },
  ];
  // reach mix
  const reachSeg = [
    { label: "Global", value: D.orgs.filter((o) => o.reach === "Global").length, color: "var(--accent)" },
    { label: "National", value: D.orgs.filter((o) => o.reach === "National").length, color: "var(--info)" },
    { label: "Local", value: D.orgs.filter((o) => o.reach === "Local").length, color: "var(--good)" },
  ];

  // funding gap by domain
  const gapByDomain = D.domains.map((d) => ({
    label: d.label, dot: domainColor(d.id), color: "var(--rose)",
    value: D.orgs.filter((o) => o.domain === d.id).reduce((s, o) => s + D.orgGap(o), 0),
  })).filter((r) => r.value > 0).sort((a, b) => b.value - a.value);

  // milestone health
  const mh = { met: 0, "on-track": 0, "at-risk": 0, behind: 0 };
  D.orgs.forEach((o) => { mh[D.milestoneHealth(o.id).verdict] = (mh[D.milestoneHealth(o.id).verdict] || 0) + 1; });
  const mhSeg = [
    { label: "All met", value: mh.met || 0, color: "var(--good)" },
    { label: "On track", value: mh["on-track"] || 0, color: "var(--info)" },
    { label: "At risk", value: mh["at-risk"] || 0, color: "var(--warn)" },
    { label: "Behind", value: mh.behind || 0, color: "var(--rose)" },
  ];

  // year on year (projects by year, count + value via parent org awarded share is rough; use counts)
  const years = [...new Set(D.projects.map((p) => p.year))].sort();
  const yoy = years.map((y) => ({
    label: y,
    grants: D.projects.filter((p) => p.year === y && (p.type === "Grant" || p.type === "Sponsorship")).length,
    proposals: D.projects.filter((p) => p.year === y && p.type === "Proposal").length,
  }));

  // top grantees by funding
  const topGrantees = [...D.orgs].filter((o) => o.funded).sort((a, b) => b.funding.awarded - a.funding.awarded).slice(0, 6)
    .map((o) => ({ label: o.name, dot: domainColor(o.domain), color: domainColor(o.domain), value: o.funding.awarded, id: o.id }));

  return (
    <div style={{ position: "absolute", inset: 0, overflow: "auto", background: "var(--bg)" }}>
      <div style={{ maxWidth: 1200, margin: "0 auto", padding: "30px 30px 60px" }}>
        {/* header */}
        <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 16, flexWrap: "wrap", marginBottom: 20 }}>
          <div>
            <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 4 }}>
              <div style={{ width: 30, height: 30, borderRadius: 8, display: "grid", placeItems: "center", background: "var(--accent-soft)", color: "var(--accent)" }}><Icon name="analytics" size={17} /></div>
              <div className="display" style={{ fontSize: 27 }}>Reports &amp; Analytics</div>
            </div>
            <div style={{ fontSize: 13.5, color: "var(--text-muted)" }}>Board-ready insight across the whole ecosystem · FY 2024-26.</div>
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn btn-sm"><Icon name="calendar" size={14} /> FY 2024-26</button>
            <button className="btn btn-sm btn-primary"><Icon name="document" size={14} /> Export board pack</button>
          </div>
        </div>

        {/* KPI strip */}
        <div className="card" style={{ padding: 20, marginBottom: 16, display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 14 }}>
          <Stat value={fmtMoney(totalAwarded)} label="Total awarded" delta="vs FY24" deltaUp />
          <Stat value={fmtMoney(D.totalGap())} label="Open funding gap" />
          <Stat value={`${D.counts.funded}/${D.counts.orgs}`} label="Funded organisations" />
          <Stat value={D.counts.projects} label="Projects tracked" />
          <Stat value={`${Math.round((mh.met || 0) / D.counts.orgs * 100)}%`} label="Grantees fully on milestone" />
        </div>

        {/* charts grid */}
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
          <ReportCard title="Funding by domain" sub="Total awarded to date" span={2}>
            <HBars rows={byDomain} fmt={fmtMoney} />
          </ReportCard>

          <ReportCard title="Relationship mix" sub={`${D.counts.orgs} organisations`}>
            <Donut segments={relSeg} label={D.counts.orgs} sub="orgs" />
          </ReportCard>

          <ReportCard title="Reach distribution">
            <Donut segments={reachSeg} label={reachSeg[0].value + reachSeg[1].value + reachSeg[2].value} sub="orgs" />
          </ReportCard>

          <ReportCard title="Open funding gap by domain" sub="Where unmet need concentrates">
            {gapByDomain.length ? <HBars rows={gapByDomain} fmt={fmtMoney} /> : <div style={{ fontSize: 13, color: "var(--text-faint)" }}>No open gaps.</div>}
          </ReportCard>

          <ReportCard title="Milestone health" sub="Across all grantees">
            <Donut segments={mhSeg} label={mh.met || 0} sub="all met" />
          </ReportCard>

          <ReportCard title="Grants year-on-year" sub="Grants & sponsorships vs proposals"
            right={<div style={{ display: "flex", gap: 12, fontSize: 11.5, color: "var(--text-muted)" }}>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}><span style={{ width: 9, height: 9, borderRadius: 2, background: "var(--accent)" }} /> Grants</span>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}><span style={{ width: 9, height: 9, borderRadius: 2, background: "var(--info)" }} /> Proposals</span>
            </div>}>
            <Columns groups={yoy} series={[{ key: "grants", color: "var(--accent)" }, { key: "proposals", color: "var(--info)" }]} />
          </ReportCard>

          <ReportCard title="Top grantees by funding" sub="Largest commitments">
            <div style={{ display: "flex", flexDirection: "column", gap: 9 }}>
              {topGrantees.map((g, i) => (
                <button key={i} className="focusable" onClick={() => onOpen(g.id)} style={{ display: "flex", alignItems: "center", gap: 11, width: "100%", textAlign: "left", padding: "2px 0", border: "none", background: "none", cursor: "pointer" }}>
                  <div style={{ width: 116, flex: "none", display: "flex", alignItems: "center", gap: 7, fontSize: 12.5, color: "var(--text)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}><span style={{ width: 8, height: 8, borderRadius: 999, background: g.dot, flex: "none" }} />{g.label}</div>
                  <div style={{ flex: 1, height: 11, borderRadius: 6, background: "var(--surface-3)", overflow: "hidden" }}><div style={{ width: (g.value / topGrantees[0].value * 100) + "%", height: "100%", background: g.color, borderRadius: 6 }} /></div>
                  <div className="mono" style={{ width: 52, textAlign: "right", fontSize: 12, color: "var(--text-muted)" }}>{fmtMoney(g.value)}</div>
                </button>
              ))}
            </div>
          </ReportCard>
        </div>

        {/* AI summary */}
        <div className="card" style={{ padding: 18, marginTop: 16, position: "relative", overflow: "hidden" }}>
          <div style={{ position: "absolute", top: -40, right: -20, width: 220, height: 160, borderRadius: 999, background: "radial-gradient(circle, var(--accent-soft-2), transparent 70%)", opacity: 0.7, pointerEvents: "none" }} />
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 11, position: "relative" }}>
            <Icon name="spark" size={16} style={{ color: "var(--accent)" }} />
            <span style={{ fontSize: 14, fontWeight: 650 }}>AI narrative summary</span>
            <span className="badge" style={{ background: "var(--accent-soft)", color: "var(--accent)", borderColor: "transparent", fontSize: 10 }}>AI</span>
          </div>
          <div style={{ fontSize: 13.5, lineHeight: 1.65, color: "var(--text-muted)", position: "relative", maxWidth: 820 }}>
            The fund has committed <strong style={{ color: "var(--text)" }}>{fmtMoney(totalAwarded)}</strong> across {D.counts.funded} organisations, concentrated in <strong style={{ color: "var(--text)" }}>{byDomain[0].label}</strong> and <strong style={{ color: "var(--text)" }}>{byDomain[1].label}</strong>. There is an open gap of <strong style={{ color: "var(--text)" }}>{fmtMoney(D.totalGap())}</strong> - most acute in {gapByDomain[0] ? gapByDomain[0].label : "-"}. {mh.behind || 0} grantee{(mh.behind || 0) === 1 ? "" : "s"} {(mh.behind || 0) === 1 ? "is" : "are"} behind on milestones and warrant a delivery review before re-funding.
          </div>
        </div>
      </div>
    </div>
  );
}

window.Reports = Reports;
