// Coverage Gaps & UBO Completion — group view of orgs whose UBO ≥10% coverage
// is incomplete, sorted by AUM or fund-subscription readiness. Per-org card
// shows OrgChart mini-rendering with unverified UBO nodes pulsed/outlined.

function CoverageGaps({ orgs, auditorMode }) {
  const [sort, setSort] = React.useState("aum"); // "aum" | "ready" | "coverage"
  const [view, setView] = React.useState("blocked"); // "blocked" | "all"

  const sorted = React.useMemo(() => {
    let r = [...orgs];
    if (view === "blocked") r = r.filter(o => o.uboCoverage < 1.0);
    r.sort((a, b) => {
      if (sort === "aum")      return b.aum - a.aum;
      if (sort === "ready")    return (b.uboCoverage * b.aum) - (a.uboCoverage * a.aum);
      if (sort === "coverage") return a.uboCoverage - b.uboCoverage;
      return 0;
    });
    return r;
  }, [orgs, sort, view]);

  return (
    <>
      <div className="app-subheader">
        <div className="subheader-title">Coverage Gaps & <Term id="UBO">UBO</Term> Completion</div>
        <div className="subheader-meta">{orgs.filter(o => o.uboCoverage < 1).length} orgs incomplete · {formatUsd(orgs.filter(o => o.uboCoverage < 1).reduce((s,o) => s + o.aum, 0))} AUM blocked</div>
        <div className="subheader-spacer" />
        <Segmented value={view} onChange={setView} options={[
          { value: "blocked", label: "Blocked",  count: orgs.filter(o => o.uboCoverage < 1).length },
          { value: "all",     label: "All Orgs", count: orgs.length },
        ]} />
        <span style={{width:8}} />
        <Segmented value={sort} onChange={setSort} options={[
          { value: "aum",      label: "Sort: AUM" },
          { value: "ready",    label: "Subscription-ready" },
          { value: "coverage", label: "Lowest coverage" },
        ]} />
      </div>

      <div className="page-scroll">
        <div className="coverage-grid">
          {sorted.map(o => <OrgCard key={o.id} org={o} auditorMode={auditorMode} />)}
        </div>
      </div>
    </>
  );
}

function OrgCard({ org, auditorMode }) {
  const cov = org.uboCoverage;
  const tone = cov >= 0.9 ? "is-good" : cov === 0 ? "is-zero" : cov < 0.5 ? "is-bad" : "";
  return (
    <article className="org-card">
      <header className="org-card-hd">
        <Flag code={org.country} />
        <div>
          <div className="name">{org.name}</div>
          <div className="row" style={{gap:8}}>
            <span className="id">{org.id}</span>
            <span className="cell-kind-pill">KYB</span>
            {cov === 0 && <StatusPill status="rejected" label="Blocked" />}
            {cov > 0 && cov < 1 && <StatusPill status="pending" label="Incomplete" />}
            {cov >= 1 && <StatusPill status="approved" label="Complete" />}
          </div>
        </div>
        <span className="right">
          <ActionIcon icon={IEye} label="View org" />
          <ActionIcon icon={IDotsV} label="More" />
        </span>
      </header>

      <div className="org-card-body">
        <div className="org-meta">
          <div className="meta-row"><span className="k">AUM</span><span className="v mono">{formatUsd(org.aum)}</span></div>
          <div className="meta-row"><span className="k">Subscription</span><span className="v" style={{textAlign:"right", maxWidth:140, fontSize:11.5}}>{org.sub}</span></div>
          <div className="meta-row"><span className="k">UBO ≥10%</span><span className="v mono">{Math.round(cov*100)}%</span></div>
          <div className={`org-coverage-bar ${tone}`}>
            <div className="org-coverage-bar-fill" style={{ width: `${cov*100}%` }} />
          </div>
          <div className="meta-row" style={{marginTop:6}}>
            <span className="k">Verified</span>
            <span className="v">{org.ubos.filter(u => u.verified).length} / {org.ubos.length}</span>
          </div>
          <div className="meta-row">
            <span className="k">Last update</span>
            <span className="v mono fg-3">{["3d", "12d", "2d", "21d", "—", "8d"][Math.abs(org.id.charCodeAt(4))%6]} ago</span>
          </div>
        </div>

        <OrgChart org={org} />
      </div>

      <footer className="org-card-foot">
        <Mono dim>{org.ubos.filter(u => !u.verified).length} unverified UBO{org.ubos.filter(u=>!u.verified).length === 1 ? "" : "s"} blocking subscription</Mono>
        <span className="right">
          <Btn variant="outlined" size="xs" icon={ICopy}>Copy share link</Btn>
          <Btn variant="filled" size="xs" tone="accent" icon={ISend} disabled={auditorMode}>Send share link</Btn>
        </span>
      </footer>
    </article>
  );
}

// Mini OrgChart: org centered, UBO nodes radiating below.
// Unverified nodes pulse + outlined; sub-entities (other orgs) drawn as squares.
function OrgChart({ org }) {
  const W = 360, H = 200;
  const cx = W / 2, cy = 50;
  const ubos = org.ubos;
  const radius = 130;
  return (
    <div className="org-chart">
      <svg width="100%" viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMid meet" style={{display:"block"}}>
        {/* Connection lines */}
        {ubos.map((u, i) => {
          const t = ubos.length === 1 ? 0.5 : i / (ubos.length - 1);
          const x = 30 + t * (W - 60);
          const y = 160;
          return (
            <line key={`l-${i}`} x1={cx} y1={cy + 14} x2={x} y2={y - 14}
              stroke="var(--line-strong)" strokeWidth={1} strokeDasharray={u.verified ? "" : "3 3"} />
          );
        })}

        {/* Org root */}
        <g>
          <rect x={cx - 56} y={cy - 14} width="112" height="28" rx="6"
            fill="var(--bg-elev)" stroke="var(--fg-2)" strokeWidth="1.2" />
          <text x={cx} y={cy + 4} textAnchor="middle" fontFamily="var(--font-sans)" fontSize="11" fontWeight="600" fill="var(--fg)">
            {org.name.length > 18 ? org.name.slice(0, 17) + "…" : org.name}
          </text>
        </g>

        {/* UBO nodes */}
        {ubos.map((u, i) => {
          const t = ubos.length === 1 ? 0.5 : i / (ubos.length - 1);
          const x = 30 + t * (W - 60);
          const y = 160;
          const isSub = u.sub;
          const ver = u.verified;
          return (
            <g key={`n-${i}`}>
              {/* Pulse for unverified */}
              {!ver && (
                <circle cx={x} cy={y} r={18} fill="none" stroke="var(--amber)" strokeWidth="1" opacity="0.4">
                  <animate attributeName="r" from="14" to="22" dur="1.8s" repeatCount="indefinite" />
                  <animate attributeName="opacity" from="0.6" to="0" dur="1.8s" repeatCount="indefinite" />
                </circle>
              )}
              {isSub ? (
                <rect x={x - 14} y={y - 14} width="28" height="28" rx="4"
                  fill={ver ? "var(--green-bg)" : "var(--amber-bg)"}
                  stroke={ver ? "var(--green)" : "var(--amber)"} strokeWidth="1.2"
                  strokeDasharray={ver ? "" : "3 2"} />
              ) : (
                <circle cx={x} cy={y} r={14}
                  fill={ver ? "var(--green-bg)" : "var(--amber-bg)"}
                  stroke={ver ? "var(--green)" : "var(--amber)"} strokeWidth="1.2"
                  strokeDasharray={ver ? "" : "3 2"} />
              )}
              <text x={x} y={y + 4} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fontWeight="600"
                fill={ver ? "var(--green-fg)" : "var(--amber-fg)"}>
                {u.pct}%
              </text>
              <text x={x} y={y + 28} textAnchor="middle" fontFamily="var(--font-sans)" fontSize="9.5"
                fill="var(--fg-3)" style={{ pointerEvents: "none" }}>
                {(u.name.length > 14 ? u.name.slice(0, 13) + "…" : u.name)}
              </text>
              {!ver && (
                <text x={x} y={y - 22} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="8.5" fill="var(--amber-fg)" fontWeight="600">
                  UNVERIFIED
                </text>
              )}
            </g>
          );
        })}
      </svg>
    </div>
  );
}

Object.assign(window, { CoverageGaps });
