/* Voyage Fleet — Components Catalog + Audit Log. */

const { useState: useS_c, useMemo: useMemo_c } = React;

/* ════════════ MODULES CATALOG ════════════ */
function ModulesCatalog({ params }) {
  const F = window.FLEET;
  const sel = F.MODULES.find(m => m.id === params.id) || F.MODULES[0];
  const versions = useMemo_c(() => {
    const p = sel.latest.split(".").map(Number);
    return Array.from({ length: 6 }, (_, i) => {
      const v = [...p]; v[2] = Math.max(0, p[2] - i);
      const type = i === 0 ? "patch" : i % 3 === 0 ? "minor" : "patch";
      return { v: v.join("."), date: `${3 + i * 9} ${["May", "Apr", "Apr", "Mar", "Mar", "Feb"][i]} 2026`, type, migrations: i % 3 === 0 ? 2 : i === 1 ? 1 : 0, tenants: Math.max(1, Math.floor(sel.tenants / (i + 1.4))) };
    });
  }, [sel.id]);

  return (
    <div style={{ display: "flex", minHeight: 0, flex: 1 }}>
      <div style={{ width: 300, flexShrink: 0, borderRight: "1px solid var(--jrni-color-surface-border)", background: "white", overflowY: "auto" }}>
        <div style={{ padding: "16px 16px 10px" }}>
          <h1 style={{ margin: 0, fontSize: 17, fontWeight: 700, color: "var(--jrni-color-neutral-1)" }}>Components</h1>
          <p style={{ margin: "2px 0 0", fontSize: 12, color: "var(--jrni-color-text-soft)" }}>{F.MODULES.length} Voyage components</p>
        </div>
        <div style={{ padding: "0 8px 12px" }}>
          {F.MODULES.map(m => (
            <button key={m.id} onClick={() => navigate("/modules", { id: m.id })} style={{ display: "block", width: "100%", textAlign: "left", padding: "10px 12px", borderRadius: 8, border: "none", cursor: "pointer", background: sel.id === m.id ? "var(--jrni-color-primary-4)" : "transparent", marginBottom: 2, fontFamily: "var(--jrni-font-family-sans)" }}>
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 }}>
                <span style={{ fontFamily: "var(--jrni-font-family-sans)", fontSize: 13, fontWeight: 600, color: sel.id === m.id ? "var(--jrni-color-primary-1)" : "var(--jrni-color-neutral-1)" }}>{m.display}</span>
                <Mono>{m.latest}</Mono>
              </div>
              <div style={{ fontSize: 11, color: "var(--jrni-color-text-soft)", marginTop: 3, fontFamily: "var(--jrni-font-family-mono)" }}>{m.name}</div>
              <div style={{ fontSize: 11.5, color: "var(--jrni-color-text-soft)", marginTop: 2 }}>{m.tenants} tenants · {m.cat}</div>
            </button>
          ))}
        </div>
      </div>

      <div style={{ flex: 1, minWidth: 0, overflowY: "auto", padding: "20px 24px 28px", display: "flex", flexDirection: "column", gap: 16 }}>
        <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 16 }}>
          <div>
            <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <h2 style={{ margin: 0, fontSize: 20, fontWeight: 700, color: "var(--jrni-color-neutral-1)" }}>{sel.display}</h2>
              <Mono color="var(--jrni-color-neutral-2)">{sel.name}</Mono>
              <Mono color="var(--jrni-color-semantic-green-1)">{sel.latest}</Mono>
              <Pill tone="neutral">{sel.cat}</Pill>
            </div>
            <p style={{ margin: "8px 0 0", fontSize: 13.5, color: "var(--jrni-color-text-soft)", maxWidth: 560, lineHeight: 1.5 }}>{sel.desc}</p>
            <div style={{ display: "flex", gap: 14, marginTop: 10 }}>
              <a href="#" onClick={e => e.preventDefault()} style={{ fontSize: 12.5, color: "var(--jrni-color-primary-1)", fontWeight: 500, display: "inline-flex", gap: 5, alignItems: "center" }}><Icons.Box size={13} />npm registry<Icons.External size={11} /></a>
              <a href="#" onClick={e => e.preventDefault()} style={{ fontSize: 12.5, color: "var(--jrni-color-primary-1)", fontWeight: 500, display: "inline-flex", gap: 5, alignItems: "center" }}><Icons.Github size={13} />GitHub source<Icons.External size={11} /></a>
            </div>
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            <ClaudeCodeLink path={`voyage-platform/packages/${sel.id}/RELEASE_NOTES.md`} label="Deprecate a version" variant="button" />
            <ClaudeCodeLink command={`voyage-fleet publish ${sel.id}@<next>`} label="Publish in Claude Code" variant="button" tone="primary" />
          </div>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, alignItems: "start" }}>
          <Card padding={16}>
            <SectionLabel>Dependencies</SectionLabel>
            <div style={{ display: "flex", flexDirection: "column", gap: 8, marginTop: 6 }}>
              <div style={{ fontSize: 11.5, color: "var(--jrni-color-text-soft)" }}>Depends on</div>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>{["notifications", "integrations"].map(d => <Mono key={d} color="var(--jrni-color-neutral-1)">@voyage/{d}</Mono>)}</div>
              <div style={{ fontSize: 11.5, color: "var(--jrni-color-text-soft)", marginTop: 6 }}>Depended on by</div>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>{["reporting-events", "kiosk"].map(d => <Mono key={d} color="var(--jrni-color-neutral-1)">@voyage/{d}</Mono>)}</div>
            </div>
          </Card>
          <Card padding={16}>
            <SectionLabel action={<button onClick={() => navigate("/releases", { view: "compat" })} style={{ background: "none", border: "none", color: "var(--jrni-color-primary-1)", fontSize: 12, fontWeight: 600, cursor: "pointer" }}>Full matrix →</button>}>Compatibility</SectionLabel>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 8 }}>
              {F.COMPAT.cols.filter(c => c !== sel.id).map(c => {
                const v = (F.COMPAT.grid[sel.id] && F.COMPAT.grid[sel.id][c]) || "ok";
                const cfg = { ok: ["var(--jrni-color-semantic-green-2)", "var(--jrni-color-semantic-green-1)", <Icons.Check size={11} />], migrate: ["var(--jrni-color-semantic-orange-2)", "var(--jrni-color-semantic-orange-1)", <span style={{ fontWeight: 700 }}>~</span>], incompatible: ["var(--jrni-color-semantic-red-2)", "var(--jrni-color-semantic-red-1)", <Icons.X size={10} />] }[v] || ["var(--jrni-color-semantic-green-2)", "var(--jrni-color-semantic-green-1)", <Icons.Check size={11} />];
                return <Tooltip key={c} label={`${sel.display} ↔ ${F.modDisplay(c)}: ${v === "ok" ? "Compatible" : v === "migrate" ? "Requires migration" : "Incompatible"}`}><span style={{ display: "inline-flex", alignItems: "center", gap: 5, fontSize: 11.5, padding: "2px 8px", borderRadius: 999, background: cfg[0], color: cfg[1], fontFamily: "var(--jrni-font-family-mono)", fontWeight: 600 }}>{cfg[2]}{c}</span></Tooltip>;
              })}
            </div>
            <div style={{ marginTop: 10, display: "flex", gap: 12, fontSize: 11, color: "var(--jrni-color-text-soft)" }}>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 4 }}><Icons.Check size={10} color="var(--jrni-color-semantic-green-1)" />compatible</span>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 4 }}><span style={{ color: "var(--jrni-color-semantic-orange-1)", fontWeight: 700 }}>~</span>requires migration</span>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 4 }}><Icons.X size={10} color="var(--jrni-color-semantic-red-1)" />incompatible</span>
            </div>
          </Card>
        </div>

        <Card padding={0} style={{ overflow: "hidden" }}>
          <div style={{ padding: "10px 16px", borderBottom: "1px solid var(--jrni-color-surface-border)", fontSize: 13, fontWeight: 600 }}>Published versions</div>
          <table style={{ width: "100%", borderCollapse: "collapse" }}>
            <thead><tr style={{ background: "var(--jrni-color-surface-card-soft)", borderBottom: "1px solid var(--jrni-color-surface-border)" }}>{["Version", "Released", "Type", "Migrations", "Tenants", ""].map((h, i) => <th key={i} style={thStyle}>{h}</th>)}</tr></thead>
            <tbody>{versions.map((v, i) => (
              <tr key={v.v} style={{ borderBottom: i < versions.length - 1 ? "1px solid var(--jrni-color-surface-border)" : "none" }}>
                <td style={{ padding: "9px 14px" }}><span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}><Mono color="var(--jrni-color-neutral-1)">{v.v}</Mono>{i === 0 ? <Pill tone="success">latest</Pill> : null}</span></td>
                <td style={{ padding: "0 14px", fontSize: 12.5, color: "var(--jrni-color-neutral-2)" }}>{v.date}</td>
                <td style={{ padding: "0 14px" }}><Pill tone={v.type === "minor" ? "warning" : "info"}>{v.type}</Pill></td>
                <td style={{ padding: "0 14px", fontSize: 12.5, color: "var(--jrni-color-neutral-2)" }}>{v.migrations || "—"}</td>
                <td style={{ padding: "0 14px", fontSize: 12.5, color: "var(--jrni-color-neutral-2)" }}>{v.tenants}</td>
                <td style={{ padding: "0 14px", textAlign: "right" }}><button style={{ background: "none", border: "none", color: "var(--jrni-color-primary-1)", fontSize: 12.5, fontWeight: 600, cursor: "pointer" }}>Changelog</button></td>
              </tr>
            ))}</tbody>
          </table>
        </Card>
      </div>
    </div>
  );
}

/* ════════════ AUDIT LOG ════════════ */
function AuditLog({ params }) {
  const F = window.FLEET;
  const [open, setOpen] = useS_c(null);
  const [f, setF] = useS_c({ actor: "all", outcome: "all" });
  const rows = F.AUDIT.filter(a => {
    if (f.actor === "bot" && !a.isBot) return false;
    if (f.actor === "operator" && a.isBot) return false;
    if (f.outcome !== "all" && a.outcome !== f.outcome) return false;
    return true;
  });
  return (
    <div style={{ flex: 1, overflowY: "auto", padding: "20px 24px 28px", display: "flex", flexDirection: "column", gap: 16 }}>
      <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
        <div>
          <h1 style={{ margin: 0, fontSize: 22, fontWeight: 700, color: "var(--jrni-color-neutral-1)", letterSpacing: -0.3 }}>Audit Log</h1>
          <p style={{ margin: "3px 0 0", fontSize: 13.5, color: "var(--jrni-color-text-soft)" }}>Compliance-grade trail of every operator and automation action. Read-only.</p>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <Button variant="secondary" size="md" icon={<Icons.Csv size={13} />}>Export CSV</Button>
          <Button variant="secondary" size="md" icon={<Icons.Download size={13} />}>Export JSON</Button>
        </div>
      </div>
      <div style={{ display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center" }}>
        <Segmented value={f.actor} onChange={v => setF(s => ({ ...s, actor: v }))} options={[{ value: "all", label: "All actors" }, { value: "operator", label: "Operators" }, { value: "bot", label: "Automation" }]} />
        <Segmented value={f.outcome} onChange={v => setF(s => ({ ...s, outcome: v }))} options={[{ value: "all", label: "All outcomes" }, { value: "success", label: "Success" }, { value: "failure", label: "Failure" }]} />
        <div style={{ position: "relative", width: 200 }}>
          <span style={{ position: "absolute", left: 10, top: 9, pointerEvents: "none" }}><Icons.Search size={13} color="var(--jrni-color-neutral-3)" /></span>
          <input placeholder="Request ID…" style={{ height: 32, width: "100%", boxSizing: "border-box", padding: "0 10px 0 30px", borderRadius: 6, border: "1px solid var(--jrni-color-neutral-4)", background: "white", fontSize: 12.5, fontFamily: "var(--jrni-font-family-mono)", outline: "none", boxShadow: "var(--jrni-shadow-chrome)" }} />
        </div>
      </div>
      <Card padding={0} style={{ overflow: "hidden" }}>
        <table style={{ width: "100%", borderCollapse: "collapse" }}>
          <thead><tr style={{ background: "var(--jrni-color-surface-card-soft)", borderBottom: "1px solid var(--jrni-color-surface-border)" }}>{["When", "Actor", "Action", "Target", "Outcome", "Request ID", ""].map((h, i) => <th key={i} style={thStyle}>{h}</th>)}</tr></thead>
          <tbody>{rows.slice(0, 30).map((a, i) => (
            <React.Fragment key={a.id}>
              <tr onClick={() => setOpen(open === a.id ? null : a.id)} style={{ borderBottom: "1px solid var(--jrni-color-surface-border)", cursor: "pointer" }}>
                <td style={{ padding: "9px 14px", fontSize: 12.5, color: "var(--jrni-color-neutral-2)", whiteSpace: "nowrap" }}>{a.time}</td>
                <td style={{ padding: "0 14px" }}><ActorChip name={a.actor} isBot={a.isBot} size="sm" /></td>
                <td style={{ padding: "0 14px" }}><Pill tone={a.sev === "destructive" ? "danger" : a.sev === "change" ? "warning" : "neutral"}>{a.action}</Pill></td>
                <td style={{ padding: "0 14px", fontFamily: "var(--jrni-font-family-mono)", fontSize: 12.5, color: a.target === "fleet-wide" ? "var(--jrni-color-text-soft)" : "var(--jrni-color-neutral-1)" }}>{a.target}</td>
                <td style={{ padding: "0 14px" }}>{a.outcome === "success" ? <Pill tone="success">Success</Pill> : <Pill tone="danger">Failure</Pill>}</td>
                <td style={{ padding: "0 14px" }}><Mono>{a.reqId}</Mono></td>
                <td style={{ padding: "0 14px", textAlign: "right" }}><Icons.Chevron dir={open === a.id ? "up" : "down"} size={12} color="var(--jrni-color-neutral-3)" /></td>
              </tr>
              {open === a.id ? (
                <tr><td colSpan={7} style={{ padding: "14px 16px", background: "var(--jrni-color-surface-card-soft)" }}>
                  <div style={{ display: "flex", gap: 32, flexWrap: "wrap" }}>
                    <div><div style={subLbl}>Originating IP</div><Mono color="var(--jrni-color-neutral-1)">10.4.21.{(i * 7) % 254}</Mono></div>
                    <div><div style={subLbl}>Session</div><Mono color="var(--jrni-color-neutral-1)">sess_{a.reqId.slice(4)}</Mono></div>
                    {a.pr ? <div><div style={subLbl}>Pull request</div><Mono color="var(--jrni-color-primary-1)">{a.pr}</Mono></div> : null}
                    <div style={{ flex: 1, minWidth: 200 }}>
                      <div style={subLbl}>Payload (before → after)</div>
                      <div style={{ marginTop: 4, fontFamily: "var(--jrni-font-family-mono)", fontSize: 11.5, color: "var(--jrni-color-neutral-2)", background: "white", border: "1px solid var(--jrni-color-surface-border)", borderRadius: 6, padding: "8px 10px" }}>{`{ "version": "v1.3.0" } → { "version": "v1.4.2" }`}</div>
                    </div>
                  </div>
                </td></tr>
              ) : null}
            </React.Fragment>
          ))}</tbody>
        </table>
      </Card>
    </div>
  );
}

Object.assign(window, { ModulesCatalog, AuditLog });
