/* global React, AppShell, Icon, TENANT_TABS */
// ════════════════════════════════════════════════════════════════
// Network Topology, the artistic showpiece. AppShell (Networks →
// Topology) wrapping a layered SVG map: tinted site zones, glowing
// device nodes, gradient bezier links with flowing packets, plus
// glass overlay panels (controls, node detail, legend, minimap).
// ════════════════════════════════════════════════════════════════
const { AppShell, Icon } = window;

// node glyphs (centered on 0,0; ~ -9..9)
function NodeGlyph({ t }) {
  const s = { fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (t) {
    case "cloud": return <path d="M-8 3 a5 5 0 0 1 1 -9.6 a6.5 6.5 0 0 1 12 1 a4.3 4.3 0 0 1 -0.3 8.6 Z" {...s} />;
    case "fw": return <path d="M0 -9 L8 -6 V0 C8 5 4.6 8 0 9.4 C-4.6 8 -8 5 -8 0 V-6 Z" {...s} />;
    case "router": return <g {...s}><rect x="-9" y="-2" width="18" height="9" rx="2" /><path d="M-5 -2 V-7 M0 -2 V-9 M5 -2 V-7" /></g>;
    case "switch": return <g {...s}><rect x="-9" y="-4" width="18" height="8" rx="2" /><path d="M-5.5 4 V7 M-1.8 4 V7 M1.8 4 V7 M5.5 4 V7" /></g>;
    case "server": return <g {...s}><rect x="-8" y="-8.5" width="16" height="7" rx="1.6" /><rect x="-8" y="1.5" width="16" height="7" rx="1.6" /><path d="M-5 -5h.01M-5 5h.01" /></g>;
    case "k8s": return <g {...s}><path d="M0 -9 L8 -4.5 V4.5 L0 9 L-8 4.5 V-4.5 Z" /><path d="M-8 -4.5 L0 0 L8 -4.5 M0 0 V9" /></g>;
    case "db": return <g {...s}><ellipse cx="0" cy="-6" rx="8" ry="3" /><path d="M-8 -6 V6 a8 3 0 0 0 16 0 V-6 M-8 0 a8 3 0 0 0 16 0" /></g>;
    case "vm": return <g {...s}><rect x="-9" y="-7" width="18" height="13" rx="2.4" /><path d="M-4 9h8M0 6v3" /></g>;
    default: return <circle r="7" {...s} />;
  }
}

function TopologyMapArt({ height = 600 }) {
  // ── layout (viewBox 1100 x 640) ──
  const N = {
    wan:    { x: 550, y: 52,  t: "cloud",  l: "internet", c: "#60bce0", st: "ok" },
    fw:     { x: 550, y: 138, t: "fw",     l: "fw-edge-01", c: "#a78bfa", st: "ok" },
    corea:  { x: 360, y: 226, t: "router", l: "core-rtr-a", c: "#a78bfa", st: "ok", sel: true },
    coreb:  { x: 740, y: 226, t: "router", l: "core-rtr-b", c: "#a78bfa", st: "ok" },
    da1:    { x: 215, y: 350, t: "switch", l: "dist-a1", c: "#34d399", st: "ok" },
    da2:    { x: 405, y: 350, t: "switch", l: "dist-b1", c: "#f0a060", st: "warn" },
    dc1:    { x: 695, y: 350, t: "switch", l: "dist-c1", c: "#34d399", st: "ok" },
    dc2:    { x: 885, y: 350, t: "switch", l: "dist-d1", c: "#34d399", st: "ok" },
    s1:     { x: 150, y: 478, t: "server", l: "node-01", c: "#34d399", st: "ok" },
    s2:     { x: 250, y: 478, t: "server", l: "node-02", c: "#34d399", st: "ok" },
    k8e:    { x: 360, y: 478, t: "k8s",    l: "k8s-east", c: "#34d399", st: "ok" },
    sane:   { x: 455, y: 478, t: "db",     l: "san-e1", c: "#34d399", st: "ok" },
    v1:     { x: 640, y: 478, t: "vm",     l: "vm-prod-01", c: "#34d399", st: "ok" },
    v2:     { x: 735, y: 478, t: "vm",     l: "vm-prod-02", c: "#34d399", st: "ok" },
    sw:     { x: 835, y: 478, t: "server", l: "node-09", c: "#34d399", st: "ok" },
    nasw:   { x: 935, y: 478, t: "db",     l: "nas-w1", c: "#34d399", st: "ok" },
  };
  const links = [
    ["wan", "fw", "trunk"], ["fw", "corea", ""], ["fw", "coreb", ""], ["corea", "coreb", "trunk"],
    ["corea", "da1", ""], ["corea", "da2", ""], ["coreb", "dc1", ""], ["coreb", "dc2", ""],
    ["da1", "s1", ""], ["da1", "s2", ""], ["da2", "k8e", ""], ["da2", "sane", ""],
    ["dc1", "v1", ""], ["dc1", "v2", ""], ["dc2", "sw", ""], ["dc2", "nasw", ""],
  ];
  const path = (a, b) => {
    const A = N[a], B = N[b];
    const mx = (A.x + B.x) / 2, my = (A.y + B.y) / 2;
    const dx = (B.x - A.x), dy = (B.y - A.y);
    // perpendicular bow for organic curve
    const k = 0.12;
    const cx = mx - dy * k, cy = my + dx * k;
    return `M${A.x} ${A.y} Q${cx} ${cy} ${B.x} ${B.y}`;
  };
  const flowLinks = [["fw", "corea"], ["corea", "coreb"], ["coreb", "dc1"], ["da1", "s2"], ["dc2", "nasw"]];
  const zones = [
    { x: 95, y: 170, w: 430, h: 360, c: "#34d399", l: "DC-East", sub: "842 devices · 4 racks" },
    { x: 575, y: 170, w: 430, h: 360, c: "#60bce0", l: "DC-West", sub: "214 devices · 3 racks" },
  ];

  return (
    <svg viewBox="0 0 1100 640" width="100%" height={height} style={{ display: "block" }} preserveAspectRatio="xMidYMid meet">
      <defs>
        <radialGradient id="topo-glow" cx="50%" cy="34%" r="62%">
          <stop offset="0%" stopColor="rgba(145,128,212,0.20)" /><stop offset="55%" stopColor="rgba(109,40,217,0.06)" /><stop offset="100%" stopColor="rgba(145,128,212,0)" />
        </radialGradient>
        <linearGradient id="link-grad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#a78bfa" stopOpacity="0.85" /><stop offset="100%" stopColor="#34d399" stopOpacity="0.55" />
        </linearGradient>
        <linearGradient id="trunk-grad" x1="0" y1="0" x2="1" y2="0">
          <stop offset="0%" stopColor="#a78bfa" /><stop offset="100%" stopColor="#60bce0" />
        </linearGradient>
        <filter id="node-glow" x="-80%" y="-80%" width="260%" height="260%"><feGaussianBlur stdDeviation="3.4" result="b" /><feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge></filter>
        <filter id="soft-glow" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="7" /></filter>
      </defs>

      {/* base */}
      <rect x="0" y="0" width="1100" height="640" fill="#08080A" />
      <rect x="0" y="0" width="1100" height="640" fill="url(#topo-glow)" />
      {/* fine grid */}
      <g opacity="0.5">
        {Array.from({ length: 28 }, (_, i) => <line key={`v${i}`} x1={i * 40} y1="0" x2={i * 40} y2="640" stroke="rgba(242,242,244,0.035)" strokeWidth="1" />)}
        {Array.from({ length: 16 }, (_, i) => <line key={`h${i}`} x1="0" y1={i * 40} x2="1100" y2={i * 40} stroke="rgba(242,242,244,0.035)" strokeWidth="1" />)}
      </g>
      {/* decorative contour rings behind cores */}
      {[N.corea, N.coreb].map((c, i) => (
        <g key={i} opacity="0.5">
          {[60, 96, 132].map(r => <circle key={r} cx={c.x} cy={c.y} r={r} fill="none" stroke="rgba(145,128,212,0.07)" strokeWidth="1" />)}
        </g>
      ))}

      {/* zones */}
      {zones.map(z => (
        <g key={z.l}>
          <rect x={z.x} y={z.y} width={z.w} height={z.h} rx="22" fill={`${z.c}07`} stroke={`${z.c}33`} strokeWidth="1.2" strokeDasharray="2 7" />
          <rect x={z.x + 14} y={z.y - 13} width={z.l.length * 9 + 130} height="26" rx="13" fill="#0d0d12" stroke={`${z.c}40`} strokeWidth="1" />
          <circle cx={z.x + 28} cy={z.y} r="3.5" fill={z.c} />
          <text x={z.x + 40} y={z.y + 1} dominantBaseline="middle" fill="#ECEAF4" fontFamily="var(--sans)" fontSize="13" fontWeight="600">{z.l}</text>
          <text x={z.x + 40 + z.l.length * 8.5} y={z.y + 1} dominantBaseline="middle" fill="#706F7A" fontFamily="var(--mono)" fontSize="10.5">· {z.sub}</text>
        </g>
      ))}

      {/* links */}
      {links.map(([a, b, kind], i) => (
        <path key={i} d={path(a, b)} fill="none" stroke={kind === "trunk" ? "url(#trunk-grad)" : "url(#link-grad)"} strokeWidth={kind === "trunk" ? 3 : 1.5} strokeOpacity={kind === "trunk" ? 0.9 : 0.55} strokeLinecap="round" />
      ))}
      {/* trunk label */}
      <g>
        <rect x="516" y="214" width="68" height="22" rx="11" fill="#0d0d12" stroke="rgba(145,128,212,0.35)" strokeWidth="1" />
        <text x="550" y="226" textAnchor="middle" dominantBaseline="middle" fill="#bdb0f6" fontFamily="var(--mono)" fontSize="10">10 GbE</text>
      </g>
      {/* flowing packets */}
      {flowLinks.map(([a, b], i) => (
        <circle key={i} r="2.6" fill={i % 2 ? "#34d399" : "#a78bfa"}>
          <animateMotion dur={`${2.4 + i * 0.4}s`} repeatCount="indefinite" path={path(a, b)} />
        </circle>
      ))}

      {/* nodes */}
      {Object.entries(N).map(([id, n]) => {
        const stc = n.st === "warn" ? "#f0a060" : n.st === "down" ? "#f06080" : "#34d399";
        return (
          <g key={id} transform={`translate(${n.x} ${n.y})`}>
            {n.sel && <circle r="30" fill="none" stroke="#a78bfa" strokeWidth="1.4" strokeDasharray="3 4" opacity="0.8"><animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="14s" repeatCount="indefinite" /></circle>}
            {n.sel && <circle r="30" fill="#a78bfa" opacity="0.10" filter="url(#soft-glow)" />}
            <circle r="21" fill={`${n.c}10`} stroke={`${n.c}40`} strokeWidth="1" />
            <circle r="15" fill="#101016" stroke={n.c} strokeWidth="1.5" />
            <g color={n.c} fill={n.c} filter="url(#node-glow)" transform="scale(0.82)"><NodeGlyph t={n.t} /></g>
            <circle cx="12" cy="-12" r="3.4" fill={stc} stroke="#08080A" strokeWidth="1.4" />
            <text y="34" textAnchor="middle" fill="#9490a8" fontFamily="var(--mono)" fontSize="10">{n.l}</text>
          </g>
        );
      })}
    </svg>
  );
}

function GlassPanel({ children, style }) {
  return <div style={{ position: "absolute", background: "rgba(13,13,18,0.72)", backdropFilter: "blur(14px)", border: "1px solid rgba(242,242,244,0.10)", borderRadius: 12, ...style }}>{children}</div>;
}

function TopologyPageMock() {
  const legend = [["#a78bfa", "Router / firewall"], ["#34d399", "Switch · healthy"], ["#f0a060", "Switch · warning"], ["#60bce0", "WAN / edge"]];
  return (
    <AppShell scopeIcon="graph" entityName="Northwind Trading" pageName="topology" tabs={window.TENANT_TABS} activeTab="network" breadcrumb={["Networks", "Topology"]} avatar="AR">
      <div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 16 }}>
          <div>
            <div style={{ fontSize: 22, fontWeight: 600, color: "#ECEAF4" }}>Topology</div>
            <div style={{ fontSize: 13.5, color: "var(--tx-2)", marginTop: 3 }}>Live map of sites, devices, and links, discovered and drawn automatically by NIMS.</div>
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            {["Layout: Hierarchical", "Overlay: VLAN", "Live"].map((c, i) => (
              <span key={c} style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12, fontFamily: "var(--mono)", padding: "6px 12px", borderRadius: 8, border: `1px solid ${i === 2 ? "rgba(52,211,153,0.4)" : "var(--divider)"}`, color: i === 2 ? "#34d399" : "var(--tx-2)" }}>
                {i === 2 && <span style={{ width: 6, height: 6, borderRadius: 99, background: "#34d399", boxShadow: "0 0 7px #34d399" }} />}{c}
              </span>
            ))}
          </div>
        </div>

        {/* map stage */}
        <div style={{ position: "relative", borderRadius: 14, overflow: "hidden", border: "1px solid var(--hair)", background: "#08080A" }}>
          <TopologyMapArt height={600} />

          {/* selected node detail (top-right) */}
          <GlassPanel style={{ top: 16, right: 16, width: 248, padding: 16 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 12 }}>
              <span style={{ width: 30, height: 30, borderRadius: 8, background: "rgba(167,139,250,0.16)", border: "1px solid rgba(167,139,250,0.4)", display: "flex", alignItems: "center", justifyContent: "center", color: "#a78bfa" }}><Icon name="router" size={17} /></span>
              <div>
                <div className="mono" style={{ fontSize: 13, color: "#fff", fontWeight: 600 }}>core-rtr-a</div>
                <div className="mono" style={{ fontSize: 10.5, color: "var(--tx-3)" }}>10.0.0.1 · DC-East</div>
              </div>
              <span style={{ marginLeft: "auto", width: 7, height: 7, borderRadius: 99, background: "#34d399", boxShadow: "0 0 8px #34d399" }} />
            </div>
            {[["Vendor", "Cisco IOS-XE"], ["Model", "Catalyst 8500"], ["Throughput", "9.8 Gbps"], ["VLANs", "10 · 20 · 30 · 40"], ["Uptime", "142d 7h"]].map(([k, v]) => (
              <div key={k} style={{ display: "flex", justifyContent: "space-between", padding: "5px 0", borderBottom: "1px solid var(--divider-2)" }}>
                <span style={{ fontSize: 11.5, color: "var(--tx-3)" }}>{k}</span>
                <span className="mono" style={{ fontSize: 11.5, color: "var(--tx)" }}>{v}</span>
              </div>
            ))}
          </GlassPanel>

          {/* legend (bottom-left) */}
          <GlassPanel style={{ bottom: 16, left: 16, padding: "12px 14px" }}>
            <div className="mono" style={{ fontSize: 9.5, letterSpacing: ".1em", textTransform: "uppercase", color: "var(--tx-3)", marginBottom: 9 }}>Legend</div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "6px 18px" }}>
              {legend.map(([c, l]) => (
                <div key={l} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 11.5, color: "var(--tx-2)" }}>
                  <span style={{ width: 9, height: 9, borderRadius: 99, background: c, flexShrink: 0 }} />{l}
                </div>
              ))}
            </div>
          </GlassPanel>

          {/* minimap + zoom (bottom-right) */}
          <GlassPanel style={{ bottom: 16, right: 16, padding: 8 }}>
            <svg width="150" height="86" viewBox="0 0 1100 640" style={{ display: "block", borderRadius: 6, background: "rgba(8,8,10,0.6)" }}>
              <rect x="95" y="170" width="430" height="360" rx="22" fill="rgba(52,211,153,0.08)" stroke="rgba(52,211,153,0.3)" strokeWidth="3" />
              <rect x="575" y="170" width="430" height="360" rx="22" fill="rgba(96,188,224,0.08)" stroke="rgba(96,188,224,0.3)" strokeWidth="3" />
              <circle cx="360" cy="226" r="16" fill="#a78bfa" /><circle cx="740" cy="226" r="16" fill="#a78bfa" /><circle cx="550" cy="138" r="14" fill="#60bce0" />
              <rect x="20" y="40" width="640" height="430" fill="none" stroke="rgba(242,242,244,0.5)" strokeWidth="4" strokeDasharray="14 10" />
            </svg>
            <div style={{ display: "flex", gap: 6, marginTop: 8, justifyContent: "center" }}>
              {["−", "⤢", "+"].map(z => <span key={z} className="mono" style={{ width: 26, height: 26, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 6, border: "1px solid var(--divider)", color: "var(--tx-2)", fontSize: 13 }}>{z}</span>)}
            </div>
          </GlassPanel>

          {/* scope hint (top-left) */}
          <GlassPanel style={{ top: 16, left: 16, padding: "8px 12px" }}>
            <span className="mono" style={{ fontSize: 10.5, color: "var(--tx-3)" }}>16 nodes · 16 links · 2 sites</span>
          </GlassPanel>
        </div>
      </div>
    </AppShell>
  );
}

Object.assign(window, { TopologyPageMock, TopologyMapArt });
