/* =============================================================
   page-batches.jsx — Batch progress
   ============================================================= */
function PageBatches({ model, onOpenSite }) {
  const { underlay } = model;

  const batches = React.useMemo(() => {
    return PRData.batchRollup(underlay);
  }, [underlay]);

  // G3: per-batch lifecycle distribution. We map every link in the batch to its site
  // (by siteName, lower-cased), and roll up the site's lifecycle phase.
  const sitesByName = React.useMemo(() => {
    const m = new Map();
    for (const s of (model.sites || [])) {
      if (s.siteName) m.set(s.siteName.toLowerCase(), s);
    }
    return m;
  }, [model.sites]);
  function lifecycleForBatch(b) {
    const counts = { complete: 0, "overlay-migrated": 0, "overlay-scheduled": 0, "overlay-ready": 0, "underlay-activated": 0, "underlay-delivery": 0, "underlay-ordering": 0, "underlay-not-started": 0, "isp-termination": 0, blocked: 0, "no-data": 0 };
    const sitesSeen = new Set();
    for (const u of (b.links || [])) {
      const sn = (u.siteName || "").toLowerCase();
      if (!sn || sitesSeen.has(sn)) continue;
      sitesSeen.add(sn);
      const site = sitesByName.get(sn);
      const phase = (site && site.lifecycle && site.lifecycle.lifecyclePhase) || "no-data";
      counts[phase] = (counts[phase] || 0) + 1;
    }
    return { counts, totalSites: sitesSeen.size };
  }
  const PHASE_COLORS = {
    "complete": "var(--ok)",
    "overlay-migrated": "var(--ok)",
    "overlay-scheduled": "var(--info)",
    "overlay-ready": "var(--info)",
    "underlay-activated": "var(--accent)",
    "underlay-delivery": "var(--warn)",
    "underlay-ordering": "var(--warn)",
    "underlay-not-started": "var(--ink-300)",
    "isp-termination": "var(--accent)",
    "blocked": "var(--risk)",
    "no-data": "var(--ink-200)",
  };

  return (
    <div className="page">
      <PageHeader
        title="Batches"
        subtitle="Rollout grouped by batch — progress, planned window, and risk per wave."
      />

      <div className="flex-col" style={{gap: 12}}>
        {batches.map((b) => {
          const okPct = b.total ? (b.activated / b.total) * 100 : 0;
          const buildPct = b.total ? (b.buildComplete / b.total) * 100 : 0;
          const orderedPct = b.total ? Math.max(0, ((b.ordered - b.buildComplete - b.activated) / b.total) * 100) : 0;
          return (
            <div key={b.key} className="card">
              <div style={{display:"flex", justifyContent:"space-between", alignItems: "flex-start", marginBottom: 12}}>
                <div>
                  <div style={{fontFamily: "var(--font-display)", fontSize: 18, fontWeight: 600, letterSpacing: "-0.015em"}}>{b.key}</div>
                  <div style={{fontSize: 12, color: "var(--ink-500)", marginTop: 2}}>
                    <span className="mono">{b.total}</span> links
                    {b.plannedMin && b.plannedMax && <> · planned {PRData.fmtDate(b.plannedMin)} → {PRData.fmtDate(b.plannedMax)}</>}
                    {b.rawBatches && b.rawBatches.size > 1 && (
                      <> · <span style={{color: "var(--ink-400)"}}>merged from {[...b.rawBatches].sort().join(", ")}</span></>
                    )}
                  </div>
                </div>
                <div style={{display: "flex", gap: 12, alignItems: "center"}}>
                  <Stat2 label="Activated" value={b.activated} tone="ok"/>
                  <Stat2 label="Build" value={b.buildComplete} tone="warn"/>
                  <Stat2 label="At risk" value={b.atRisk} tone={b.atRisk ? "risk" : "muted"}/>
                  <Stat2 label="Blocked" value={b.blocked} tone={b.blocked ? "warn" : "muted"}/>
                </div>
              </div>
              <div className="stack-bar" style={{height: 14}}>
                <span style={{width: okPct + "%", background: "var(--ok)"}}/>
                <span style={{width: buildPct + "%", background: "var(--warn)"}}/>
                <span style={{width: orderedPct + "%", background: "var(--info)"}}/>
              </div>
              <div style={{display: "flex", justifyContent:"space-between", fontSize: 11.5, marginTop: 6, color: "var(--ink-500)"}}>
                <span>{Math.round(okPct)}% activated · {Math.round(buildPct)}% build complete · {Math.round(orderedPct)}% ordered</span>
                <span className="mono" style={{color: "var(--ink-700)", fontWeight: 600}}>{b.activated + b.buildComplete}/{b.total} done or near</span>
              </div>
              {/* G3 — site-level lifecycle distribution for this batch */}
              {(() => {
                const { counts, totalSites } = lifecycleForBatch(b);
                if (!totalSites) return null;
                const phases = Object.entries(counts).filter(([, n]) => n > 0);
                return (
                  <div style={{marginTop: 12}}>
                    <div style={{fontSize: 10.5, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--ink-500)", marginBottom: 6}}>
                      Lifecycle of {totalSites} site{totalSites === 1 ? "" : "s"} in this batch
                    </div>
                    <div className="stack-bar" style={{height: 10}}>
                      {phases.map(([phase, n]) => (
                        <span key={phase} title={phase + " · " + n}
                              style={{width: ((n / totalSites) * 100) + "%", background: PHASE_COLORS[phase] || "var(--ink-300)"}}/>
                      ))}
                    </div>
                    <div className="flex gap-sm" style={{flexWrap: "wrap", marginTop: 6, fontSize: 11}}>
                      {phases.map(([phase, n]) => (
                        <span key={phase} style={{display: "inline-flex", alignItems: "center", gap: 4}}>
                          <span style={{width: 8, height: 8, borderRadius: 2, background: PHASE_COLORS[phase] || "var(--ink-300)"}}/>
                          <span style={{color: "var(--ink-700)"}}>{phase}</span>
                          <span className="mono" style={{color: "var(--ink-500)"}}>{n}</span>
                        </span>
                      ))}
                    </div>
                  </div>
                );
              })()}
              {b.links.length > 0 && (
                <details style={{marginTop: 14}}>
                  <summary style={{cursor: "pointer", fontSize: 12, color: "var(--ink-500)"}}>Show {b.links.length} links</summary>
                  <div style={{marginTop: 10, display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))", gap: 8}}>
                    {b.links.map((u) => (
                      <button key={u._id} onClick={() => onOpenSite({ site: { siteName: u.siteName, country: u.country, region: u.region, criticality: u.criticality }, link: u })}
                              style={{textAlign: "left", padding: "8px 10px", border: "1px solid var(--line-soft)", borderRadius: 8, background: "var(--bg-elev)", cursor: "pointer", fontSize: 12}}>
                        <div style={{display:"flex", justifyContent:"space-between", marginBottom: 2}}>
                          <span className="mono strong">{u.linkRef}</span>
                          <StatusCell value={u.circuitStatus} kind="circuit"/>
                        </div>
                        <div className="ellipsis" style={{fontSize: 11.5, color: "var(--ink-700)"}}>{u.siteName}</div>
                        <div className="muted" style={{fontSize: 10.5}}>{u.country} · {u.vendor}</div>
                      </button>
                    ))}
                  </div>
                </details>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

function Stat2({ label, value, tone }) {
  return (
    <div style={{textAlign: "right"}}>
      <div style={{fontSize: 10.5, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--ink-500)"}}>{label}</div>
      <div style={{
        fontFamily: "var(--font-display)",
        fontSize: 18, fontWeight: 600, letterSpacing: "-0.02em",
        color: tone === "ok" ? "var(--ok)" : tone === "risk" ? "var(--risk)" : tone === "warn" ? "var(--warn)" : "var(--ink-900)",
      }}>{value}</div>
    </div>
  );
}

window.PageBatches = PageBatches;
