/* =============================================================
   page-isp.jsx — Legacy ISP termination tracker
   Shows legacy links that have been terminated, plus the
   current status of the replacement underlay link (joined on
   Link Ref / Site Name).
   ============================================================= */
function PageIsp({ model, onOpenSite, onOpenInPM, role }) {
  const [search, setSearch] = React.useState("");
  const [filters, setFilters] = React.useState({});
  const [editingRow, setEditingRow] = React.useState(null);
  const [pageLimit, setPageLimit] = React.useState(250);
  const canEdit = role === "engineer" || role === "po" || role === "admin";

  // Enrich each ISP row with its replacement link's status from canonical relationships.
  const enriched = React.useMemo(() => PRData.enrichIspRows(model), [model]);

  // Distinct filter options
  const opts = React.useMemo(() => {
    return {
      region: PRData.uniqueValues(enriched, "region"),
      country: PRData.uniqueValues(enriched, "country"),
      isp: PRData.uniqueValues(enriched, "isp"),
      terminated: ["Yes", "No", "In Progress"],
    };
  }, [enriched]);

  const filtered = React.useMemo(() => {
    const s = search.trim().toLowerCase();
    return enriched.filter((r) => {
      if (filters.region && r.region !== filters.region) return false;
      if (filters.country && r.country !== filters.country) return false;
      if (filters.isp && r.isp !== filters.isp) return false;
      if (filters.terminated && r.terminated !== filters.terminated) return false;
      if (s) {
        const hay = [r.linkRef, r.linkNum, r.siteName, r.isp, r.circuitId, r.country, r.lead, r.comments].join(" ").toLowerCase();
        if (!hay.includes(s)) return false;
      }
      return true;
    });
  }, [enriched, filters, search]);

  // Reset the render cap when the result set changes so search/filter always
  // starts from an interactive budget (matches PM editor pagination intent).
  React.useEffect(() => { setPageLimit(250); }, [filters, search]);

  // KPIs from the FULL isp dataset (not filtered)
  const fullStats = model.kpi || PRData.ispStats(model.isp);

  // Replacement status mix (only rows with a known replacement)
  const replacementMix = React.useMemo(() => {
    const m = new Map();
    for (const r of enriched) {
      const status = r.replacement ? (r.replacement.circuitStatus || "Not Started") : "No replacement matched";
      m.set(status, (m.get(status) || 0) + 1);
    }
    return [...m.entries()].sort((a, b) => b[1] - a[1])
      .map(([label, value]) => ({
        label, value,
        color: label.toLowerCase() === "activated" ? "var(--ok)"
          : label.toLowerCase().includes("build complete") ? "var(--warn)"
          : label === "No replacement matched" ? "var(--ink-300)"
          : "var(--accent)",
      }));
  }, [enriched]);

  // ISP carrier breakdown
  const ispMix = React.useMemo(() => {
    const m = new Map();
    for (const r of enriched) if (r.isp) m.set(r.isp, (m.get(r.isp) || 0) + 1);
    return [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10)
      .map(([label, value]) => ({ label, value }));
  }, [enriched]);

  const columns = [
    { key: "linkRef", label: "Legacy Ref", width: 90, cellClass: "mono strong", render: (r) => r.linkRef || <span className="muted">—</span> },
    { key: "linkNum", label: "Link #", width: 80, cellClass: "mono", render: (r) => r.linkNum || <span className="muted">—</span> },
    { key: "siteName", label: "Site", render: (r) => (
        <div style={{display:"flex", flexDirection: "column"}}>
          <span className="strong">{r.siteName || "—"}</span>
          <span className="muted" style={{fontSize: 11}}>{r.country} · {r.region}</span>
        </div>
      )},
    { key: "isp", label: "Legacy ISP", width: 130, render: (r) => r.isp ? <Pill kind="muted">{r.isp}</Pill> : <span className="muted">—</span> },
    { key: "circuitId", label: "Circuit ID", width: 150, cellClass: "mono", render: (r) => r.circuitId || <span className="muted">—</span> },
    { key: "terminated", label: "Terminated?", width: 120, render: (r) => {
        if (r.terminated === "Yes") return <Pill kind="ok">Terminated</Pill>;
        if (r.terminated === "In Progress") return <Pill kind="warn">In Progress</Pill>;
        if (r.terminated === "No") return <Pill kind="muted">Active</Pill>;
        return <span className="muted">—</span>;
      },
      sortVal: (r) => r.terminated === "Yes" ? 3 : r.terminated === "In Progress" ? 2 : r.terminated === "No" ? 1 : 0 },
    { key: "terminationDate", label: "Term. date", width: 110, cellClass: "mono",
      render: (r) => PRData.fmtDate(r.terminationDate), sortVal: (r) => r.terminationDate },
    { key: "finalBilling", label: "Final billing", width: 110, cellClass: "mono",
      render: (r) => PRData.fmtDate(r.finalBilling), sortVal: (r) => r.finalBilling },
    { key: "comments", label: "CR note", width: 150,
      render: (r) => r.comments ? <span title={r.comments}>{String(r.comments).slice(0, 34)}</span> : <span className="muted">â€”</span>,
      sortVal: (r) => r.comments || "" },
    { key: "newStatus", label: "New link status", render: (r) => {
        if (!r.replacement) return <span className="muted" style={{fontSize: 12}}>No replacement matched</span>;
        return (
          <div style={{display:"flex", flexDirection: "column", gap: 2}}>
            <StatusCell value={r.replacement.circuitStatus} kind="circuit"/>
            <span className="muted" style={{fontSize: 11}}>
              new ref <span className="mono">{r.replacement.linkRef}</span>
              {r.replacement.vendor ? ` · ${r.replacement.vendor}` : ""}
            </span>
          </div>
        );
      },
      sortVal: (r) => r.replacement ? r.replacement.circuitStatus : "" },
    { key: "relationshipWarnings", label: "Warnings", width: 120, render: (r) => <RelationshipWarningCell row={r}/>, sortVal: (r) => (r._relationshipWarnings || []).length },
    { key: "lead", label: "Lead", width: 90, render: (r) => r.lead || <span className="muted">—</span> },
    { key: "_actions", label: "Actions", width: 168, sortable: false, render: (r) => (
        <div className="flex gap-sm" onClick={(e) => e.stopPropagation()}>
          {canEdit && <button className="btn" style={{ padding: "2px 8px", fontSize: 11 }} onClick={() => setEditingRow(r)}><Glyph name="edit" size={11}/> Edit status</button>}
          {onOpenInPM && <button className="btn ghost" style={{ padding: "2px 8px", fontSize: 11 }} onClick={() => onOpenInPM("isp", r.linkRef || r.linkNum || r.circuitId)}>Open in PM</button>}
        </div>
      ) },
  ];

  return (
    <div className="page">
      <PageHeader
        title="ISP termination"
        subtitle="Legacy circuits and their decommission status — joined with the replacement underlay link."
        right={
          <div className="flex gap-sm">
            <SearchInput value={search} onChange={setSearch} placeholder="Search ref, site, ISP, circuit ID…"/>
          </div>
        }
      />

      <div className="grid g-4 mb-md">
        <KPI accent label="Legacy circuits" value={(fullStats.ispTotal || 0).toLocaleString()} hint="validated ISP rows" delta=""/>
        <KPI label="Terminated" value={(fullStats.ispTerminated || 0).toLocaleString()} hint={`${Math.round(((fullStats.ispTerminated || 0)/Math.max(1,fullStats.ispTotal || 0))*100)}%`} delta="legacy fully decommissioned"/>
        <KPI label="Termination in progress" value={(fullStats.ispInProgress || 0).toLocaleString()} hint="awaiting cutover / billing close"/>
        <KPI label="Still active" value={(fullStats.ispActive || 0).toLocaleString()} hint="legacy circuit still live"/>
      </div>

      <div className="flex gap-sm mb-md" style={{flexWrap: "wrap"}}>
        <FilterSelect label="Region" value={filters.region} onChange={(v) => setFilters({ ...filters, region: v })} options={opts.region}/>
        <FilterSelect label="Country" value={filters.country} onChange={(v) => setFilters({ ...filters, country: v })} options={opts.country}/>
        <FilterSelect label="Legacy ISP" value={filters.isp} onChange={(v) => setFilters({ ...filters, isp: v })} options={opts.isp}/>
        <FilterSelect label="Status" value={filters.terminated} onChange={(v) => setFilters({ ...filters, terminated: v })} options={opts.terminated}/>
        {(filters.region||filters.country||filters.isp||filters.terminated||search) && (
          <button className="btn ghost" onClick={() => { setFilters({}); setSearch(""); }} style={{fontSize: 11.5}}>Clear all</button>
        )}
      </div>

      <div className="grid g-2 mb-md">
        <div className="card">
          <div className="card-h">
            <div className="title">New link status after termination</div>
            <div className="hint">replacement circuit · current state</div>
          </div>
          <BarChart data={replacementMix} />
        </div>
        <div className="card">
          <div className="card-h">
            <div className="title">Legacy ISP carriers</div>
            <div className="hint">top 10 by circuit count</div>
          </div>
          {ispMix.length === 0 ? <Empty title="No ISP data."/> : <BarChart data={ispMix} accent="var(--info)"/>}
        </div>
      </div>

      <div className="table-wrap">
        <div className="table-toolbar">
          <span className="mono" style={{fontSize: 11.5, color: "var(--ink-500)"}}>{filtered.length.toLocaleString()} of {(fullStats.ispTotal || 0).toLocaleString()} legacy circuits</span>
          <span style={{flex: 1}}/>
          <span style={{fontSize: 11.5, color: "var(--ink-400)"}}>
            {filtered.length > pageLimit ? `Showing first ${pageLimit} · ` : ""}Click a row to open the site
          </span>
        </div>
        <DataTable columns={columns} rows={filtered.slice(0, pageLimit)}
          onRowClick={(r) => r.replacement
            ? onOpenSite({ site: { siteName: r.replacement.siteName, country: r.replacement.country, region: r.replacement.region }, link: r.replacement, isp: r })
            : onOpenSite({ site: { siteName: r.siteName, siteCode: r.siteCode, country: r.country, region: r.region }, isp: r })
          }
          maxHeight={"60vh"}/>
        {filtered.length > pageLimit && (
          <div style={{ textAlign: "center", padding: 10 }}>
            <button className="btn" onClick={() => setPageLimit(pageLimit + 250)}>Load 250 more…</button>
          </div>
        )}
      </div>

      {editingRow && (
        <TrackerRowEditor
          row={editingRow}
          entity="isp"
          idResolver={(r) => PRData.resolveOperationalEntityId("isp", r, model)}
          fields={[
            { key: "terminated", label: "Terminated?", type: "enum", options: ["Yes", "No", "In Progress"] },
            { key: "terminationDate", label: "Termination date", type: "date" },
            { key: "finalBilling", label: "Final billing date", type: "date" },
            { key: "lead", label: "Termination lead", type: "text" },
            { key: "comments", label: "CR / comments", type: "longtext" },
          ]}
          canEdit={canEdit}
          openInPM={onOpenInPM}
          onClose={() => setEditingRow(null)}
          onSaved={() => {/* GA-13: autosave — model re-renders via PMClient.subscribe; editor stays open */}}
        />
      )}
    </div>
  );
}

window.PageIsp = PageIsp;
