// ENGINEER VIEW — systems topology for engineers
const { useState } = React;

const SERVICES = [
  { name: "orchestrator",   type: "Railway Worker",   role: "Primary interface · routes exchanges · assembles context · dispatches to specialists", status: "live" },
  { name: "FalkorDB",       type: "Railway Database",  role: "Graph storage · OpenCypher · vector search at 384 dims · append-only write target", status: "live" },
  { name: "write-workers",  type: "Railway Workers",   role: "Write-time consolidation · decompose · tag · embed · write · stateless + horizontal", status: "live" },
  { name: "append-workers", type: "Railway Workers",   role: "Taxonomy re-tag · correction appends · Insight generation · background traversal", status: "live" },
  { name: "auditor",        type: "Railway Worker",    role: "Async classification audit · samples write-worker output · human escalation queue", status: "live" },
  { name: "cataloger",      type: "Railway Worker",    role: "Session cataloger · predictive state model · lateral awareness · one step behind", status: "live" },
  { name: "insight-library",type: "Railway Web",       role: "Read-only Insight graph browse · filterable by context · time · entity", status: "live" },
];

const STATUS_META = {
  live: { label: "LIVE", color: "#3dd68c", bg: "rgba(61,214,140,0.1)" },
};

const GRAPH_NODES = [
  { id: "user",    x: 60,  y: 50,  label: "User",    color: "#38d4c8" },
  { id: "session", x: 200, y: 50,  label: "Session", color: "#38d4c8" },
  { id: "message", x: 340, y: 50,  label: "Message", color: "#38d4c8" },
  { id: "chunk",   x: 480, y: 50,  label: "Chunk",   color: "#9d7ee8" },
  { id: "context", x: 590, y: 140, label: "Context", color: "#e8a84c" },
  { id: "topic",   x: 480, y: 140, label: "Topic",   color: "#e8a84c" },
  { id: "entity",  x: 370, y: 140, label: "Entity",  color: "#e8a84c" },
  { id: "insight", x: 590, y: 0,   label: "Insight ★", color: "#3dd68c" },
];

const GRAPH_EDGES = [
  { from: "user",    to: "session", label: "PARTICIPATED_IN", color: "#38d4c8" },
  { from: "session", to: "message", label: "CONTAINS",        color: "#38d4c8" },
  { from: "message", to: "chunk",   label: "CONTAINS",        color: "#38d4c8" },
  { from: "chunk",   to: "context", label: "IN_CONTEXT",      color: "#e8a84c" },
  { from: "chunk",   to: "topic",   label: "TAGGED",          color: "#e8a84c" },
  { from: "chunk",   to: "entity",  label: "MENTIONS",        color: "#e8a84c" },
  { from: "insight", to: "chunk",   label: "DERIVED_FROM ★",  color: "#3dd68c", planned: true },
  { from: "insight", to: "context", label: "IN_CONTEXT ★",    color: "#3dd68c", planned: true },
];

const ABAC_RULES = [
  { title: "Write access", body: "Cara cluster only. No agent writes to the graph directly. Graph topology is owned by consolidation workers, not agents." },
  { title: "Read access — Orchestrator", body: "Full traversal within the principal's graph. Cross-context reads within the user's access profile." },
  { title: "Read access — Specialists", body: "Scoped to permitted contexts. Specialist A reads business_deal context. Specialist B reads operational context. Cross-contamination structurally impossible." },
  { title: "Read access — Auditor", body: "Cross-context read for audit purposes only. Auditor decisions are logged. Every read is traceable." },
  { title: "Multi-context chunks", body: "Chunks that span contexts carry multiple IN_CONTEXT edges. Retrieval checks the full access profile before surfacing." },
  { title: "Forgetting", body: "Tombstone records retire chunks from retrieval. The original node is preserved. Forgetting is auditable." },
];

const EMBEDDING_SPEC = [
  { k: "Model", v: "sentence-transformers/all-MiniLM-L6-v2" },
  { k: "Dimensions", v: "384" },
  { k: "Runtime", v: "Local to write worker — no external API" },
  { k: "Version tracking", v: "embedding_model_version on every Chunk node" },
  { k: "Re-embed policy", v: "Full re-embed on major version change" },
  { k: "Cross-version retrieval", v: "Degraded but non-zero utility" },
];

const CARA_WORKERS = [
  {
    type: "Write Workers",
    color: "#38d4c8",
    trigger: "POST /chunk from orchestrator",
    ops: ["Semantic chunking (Haiku)", "Context tagging", "384-dim embedding", "FalkorDB write"],
    scale: "Horizontal — stateless",
    status: "live",
  },
  {
    type: "Append Workers",
    color: "#9d7ee8",
    trigger: "Schedule + write worker activity",
    ops: ["Taxonomy re-tagging", "Correction appends (superseding)", "Insight generation (traversal)", "Tombstone writes"],
    scale: "Lower-priority queue",
    status: "live",
  },
];

function ServiceTable() {
  return (
    <div style={{ background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 8, overflow: "hidden" }}>
      <div style={{ display: "grid", gridTemplateColumns: "1.6fr 1.2fr 2.6fr 90px", borderBottom: "1px solid var(--border)", padding: "10px 18px" }}>
        {["Service", "Type", "Role", "Status"].map(h => (
          <div key={h} style={{ fontSize: 9, fontFamily: "Space Grotesk, sans-serif", fontWeight: 600, letterSpacing: "0.12em", color: "var(--dim)", textTransform: "uppercase" }}>{h}</div>
        ))}
      </div>
      {SERVICES.map((s, i) => {
        const st = STATUS_META[s.status];
        return (
          <div key={i} style={{
            display: "grid", gridTemplateColumns: "1.6fr 1.2fr 2.6fr 90px",
            padding: "12px 18px", borderBottom: i < SERVICES.length - 1 ? "1px solid var(--border)" : "none",
            background: i % 2 === 0 ? "transparent" : "rgba(255,255,255,0.01)",
            alignItems: "center",
          }}>
            <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11.5, color: "var(--text)", fontWeight: 500 }}>{s.name}</div>
            <div style={{ fontSize: 11, color: "var(--muted)" }}>{s.type}</div>
            <div style={{ fontSize: 11, color: "var(--muted)", lineHeight: 1.5 }}>{s.role}</div>
            <div>
              <span style={{ fontSize: 9, fontFamily: "JetBrains Mono, monospace", letterSpacing: "0.08em", color: st.color, background: st.bg, padding: "3px 8px", borderRadius: 3 }}>
                {st.label}
              </span>
            </div>
          </div>
        );
      })}
    </div>
  );
}

function GraphSchemaViz() {
  const nodeById = Object.fromEntries(GRAPH_NODES.map(n => [n.id, n]));
  const W = 680, H = 200;

  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: "block" }}>
      <defs>
        <marker id="arrow-teal" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto">
          <path d="M0,0 L0,6 L6,3 Z" fill="#38d4c8" opacity="0.6"/>
        </marker>
        <marker id="arrow-amber" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto">
          <path d="M0,0 L0,6 L6,3 Z" fill="#e8a84c" opacity="0.6"/>
        </marker>
        <marker id="arrow-green" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto">
          <path d="M0,0 L0,6 L6,3 Z" fill="#3dd68c" opacity="0.6"/>
        </marker>
      </defs>

      {/* Edges */}
      {GRAPH_EDGES.map((e, i) => {
        const from = nodeById[e.from];
        const to = nodeById[e.to];
        if (!from || !to) return null;
        const fx = from.x + 38, fy = from.y + 14;
        const tx = to.x + 38, ty = to.y + 14;
        const markerColor = e.color === "#38d4c8" ? "teal" : e.color === "#e8a84c" ? "amber" : "green";
        return (
          <g key={i}>
            <line x1={fx} y1={fy} x2={tx} y2={ty}
              stroke={e.color} strokeWidth={e.planned ? 1 : 1.2}
              strokeDasharray={e.planned ? "4 4" : "none"}
              opacity={e.planned ? 0.45 : 0.6}
              markerEnd={`url(#arrow-${markerColor})`}
            />
            <text
              x={(fx + tx) / 2} y={(fy + ty) / 2 - 5}
              textAnchor="middle" fontSize="7.5"
              fill={e.color} opacity={e.planned ? 0.45 : 0.55}
              fontFamily="JetBrains Mono, monospace"
            >{e.label}</text>
          </g>
        );
      })}

      {/* Nodes */}
      {GRAPH_NODES.map(n => (
        <g key={n.id}>
          <rect x={n.x} y={n.y} width={76} height={28} rx={4}
            fill={`rgba(${n.color === "#38d4c8" ? "56,212,200" : n.color === "#e8a84c" ? "232,168,76" : n.color === "#9d7ee8" ? "157,126,232" : "61,214,140"},0.1)`}
            stroke={n.color} strokeWidth={1}
            strokeDasharray={n.id === "insight" ? "3 3" : "none"}
            opacity={n.id === "insight" ? 0.7 : 1}
          />
          <text x={n.x + 38} y={n.y + 18} textAnchor="middle"
            fill={n.color} fontSize={10} fontWeight={600}
            fontFamily="Space Grotesk, sans-serif"
            opacity={n.id === "insight" ? 0.7 : 1}
          >{n.label}</text>
        </g>
      ))}

      {/* Legend */}
      <g transform="translate(0, 175)">
        <circle cx="8" cy="8" r="4" fill="rgba(61,214,140,0.2)" stroke="#3dd68c" strokeWidth="1" strokeDasharray="2 2"/>
        <text x="18" y="12" fontSize="9" fill="#3dd68c" opacity="0.7" fontFamily="Inter, sans-serif">★ planned node / relationship</text>
      </g>
    </svg>
  );
}

function CaraWorkerDiagram() {
  return (
    <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
      {CARA_WORKERS.map(w => {
        const st = STATUS_META[w.status];
        return (
          <div key={w.type} style={{
            background: "var(--surface)", border: `1px solid ${w.color}30`,
            borderRadius: 8, padding: "16px 16px",
          }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
              <div style={{ fontFamily: "Space Grotesk, sans-serif", fontWeight: 600, fontSize: 12, color: w.color }}>{w.type}</div>
              <span style={{ fontSize: 9, fontFamily: "JetBrains Mono, monospace", color: st.color, background: st.bg, padding: "2px 7px", borderRadius: 3 }}>{st.label}</span>
            </div>
            <div style={{ fontSize: 10, color: "var(--muted)", marginBottom: 10 }}>
              <span style={{ color: "var(--dim)", marginRight: 6 }}>trigger</span>{w.trigger}
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
              {w.ops.map((op, i) => (
                <div key={i} style={{ display: "flex", alignItems: "center", gap: 8 }}>
                  <div style={{ width: 4, height: 4, borderRadius: "50%", background: w.color, opacity: 0.6, flexShrink: 0 }}/>
                  <span style={{ fontSize: 11, color: "var(--muted)" }}>{op}</span>
                </div>
              ))}
            </div>
            <div style={{ marginTop: 10, paddingTop: 10, borderTop: `1px solid ${w.color}15`, fontSize: 10, color: "var(--dim)" }}>
              <span style={{ color: w.color, marginRight: 6 }}>scale</span>{w.scale}
            </div>
          </div>
        );
      })}

      {/* Queue between them */}
      <div style={{ gridColumn: "1 / -1", background: "var(--surface2)", border: "1px solid var(--border)", borderRadius: 6, padding: "10px 16px", display: "flex", alignItems: "center", gap: 14 }}>
        <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: "#e8a84c" }}>task queue</div>
        <div style={{ fontSize: 11, color: "var(--muted)" }}>Primary workers enqueue background jobs · Append workers drain at lower priority · FalkorDB is the only write target</div>
        <div style={{ marginLeft: "auto", fontSize: 9, fontFamily: "JetBrains Mono, monospace", color: "var(--dim)", whiteSpace: "nowrap" }}>asyncio / Redis Queue</div>
      </div>
    </div>
  );
}

function EngineerView() {
  const [abacOpen, setAbacOpen] = useState(null);

  return (
    <div style={{ height: "100%", overflowY: "auto", padding: "40px 48px 60px" }}>
      <div style={{ maxWidth: 1000, margin: "0 auto" }}>

        {/* Header */}
        <div style={{ marginBottom: 36 }}>
          <p style={{ fontFamily: "Space Grotesk, sans-serif", fontSize: 11, letterSpacing: "0.16em", color: "var(--muted)", marginBottom: 12, textTransform: "uppercase" }}>Systems Topology</p>
          <h1 style={{ fontFamily: "Space Grotesk, sans-serif", fontWeight: 300, fontSize: "clamp(24px, 3vw, 40px)", color: "var(--text)", lineHeight: 1.25, marginBottom: 10 }}>
            Target stack on<br/>
            <span style={{ color: "#38d4c8", fontWeight: 500 }}>Railway.</span>
          </h1>
          <p style={{ fontSize: 14, color: "var(--muted)", lineHeight: 1.7, maxWidth: 580 }}>
            Seven services. All independently deployable on Railway. The write worker cluster is stateless and horizontally scalable. The graph is the source of truth.
          </p>
        </div>

        {/* Service Table */}
        <div style={{ marginBottom: 36 }}>
          <div style={{ fontSize: 10, fontFamily: "Space Grotesk, sans-serif", letterSpacing: "0.14em", color: "var(--muted)", marginBottom: 12, textTransform: "uppercase" }}>Service Registry</div>
          <ServiceTable/>
        </div>

        {/* Graph Schema + Cara Workers */}
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 28, marginBottom: 36 }}>

          {/* Graph Schema */}
          <div>
            <div style={{ fontSize: 10, fontFamily: "Space Grotesk, sans-serif", letterSpacing: "0.14em", color: "var(--dim)", marginBottom: 12, textTransform: "uppercase" }}>Graph Schema</div>
            <div style={{ background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 8, padding: "20px 16px 10px" }}>
              <GraphSchemaViz/>
              {/* Node property reference */}
              <div style={{ marginTop: 12, paddingTop: 12, borderTop: "1px solid var(--border)", display: "grid", gridTemplateColumns: "1fr 1fr", gap: 6 }}>
                {[
                  { label: "Chunk", props: "content · embedding[384] · embedding_model_version · created_at" },
                  { label: "Context", props: "name — business_deal | personal | operational | research" },
                  { label: "Topic", props: "name — negotiation | analysis | planning | ops | support …" },
                  { label: "Insight ★", props: "content · confidence · insight_type · source_context" },
                ].map(n => (
                  <div key={n.label} style={{ fontSize: 10 }}>
                    <span style={{ fontFamily: "JetBrains Mono, monospace", color: n.label.includes("★") ? "#3dd68c" : "#9d7ee8" }}>{n.label}</span>
                    <div style={{ color: "var(--muted)", marginTop: 2, lineHeight: 1.5 }}>{n.props}</div>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* Cara Workers */}
          <div>
            <div style={{ fontSize: 10, fontFamily: "Space Grotesk, sans-serif", letterSpacing: "0.14em", color: "var(--dim)", marginBottom: 12, textTransform: "uppercase" }}>Graph Worker Cluster</div>
            <CaraWorkerDiagram/>

            {/* Embedding spec */}
            <div style={{ marginTop: 16, background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 8, padding: "14px 16px" }}>
              <div style={{ fontSize: 10, fontFamily: "Space Grotesk, sans-serif", fontWeight: 600, letterSpacing: "0.1em", color: "var(--muted)", marginBottom: 10, textTransform: "uppercase" }}>Embedding Model</div>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "4px 16px" }}>
                {EMBEDDING_SPEC.map(s => (
                  <div key={s.k} style={{ display: "flex", gap: 8, alignItems: "baseline" }}>
                    <span style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 9, color: "var(--dim)", whiteSpace: "nowrap" }}>{s.k}</span>
                    <span style={{ fontSize: 10.5, color: "var(--muted)" }}>{s.v}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>

        {/* ABAC Model */}
        <div style={{ marginBottom: 36 }}>
          <div style={{ fontSize: 10, fontFamily: "Space Grotesk, sans-serif", letterSpacing: "0.14em", color: "var(--dim)", marginBottom: 12, textTransform: "uppercase" }}>ABAC Model — Access by Graph Topology</div>
          <div style={{ background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 8, padding: "18px 20px", marginBottom: 14 }}>
            <p style={{ fontSize: 13, color: "var(--muted)", lineHeight: 1.7 }}>
              <span style={{ color: "#e8a84c", fontWeight: 500 }}>Access boundaries are structural, not procedural.</span>{" "}
              Context membership is attached to chunks at write time by the write worker. The graph topology contains no traversal paths from a restricted query origin to out-of-scope chunks. A principal with access to <span style={{ fontFamily: "JetBrains Mono, monospace", color: "#38d4c8", fontSize: 12 }}>context:business_deal</span> cannot retrieve chunks tagged exclusively <span style={{ fontFamily: "JetBrains Mono, monospace", color: "#38d4c8", fontSize: 12 }}>context:personal</span> — not because a policy engine checked the request, but because no traversal path exists.
            </p>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 8 }}>
            {ABAC_RULES.map((r, i) => (
              <div key={i}
                onClick={() => setAbacOpen(abacOpen === i ? null : i)}
                style={{
                  background: abacOpen === i ? "var(--surface2)" : "var(--surface)",
                  border: `1px solid ${abacOpen === i ? "#e8a84c40" : "var(--border)"}`,
                  borderRadius: 6, padding: "12px 14px", cursor: "pointer", transition: "all 0.2s",
                }}
                onMouseEnter={e => { if (abacOpen !== i) e.currentTarget.style.borderColor = "#e8a84c20"; }}
                onMouseLeave={e => { if (abacOpen !== i) e.currentTarget.style.borderColor = "var(--border)"; }}
              >
                <div style={{ fontFamily: "Space Grotesk, sans-serif", fontWeight: 600, fontSize: 11.5, color: "#e8a84c", marginBottom: abacOpen === i ? 8 : 0 }}>{r.title}</div>
                {abacOpen === i && <div style={{ fontSize: 11, color: "var(--muted)", lineHeight: 1.65 }}>{r.body}</div>}
              </div>
            ))}
          </div>
        </div>

        {/* Engineer Tenets */}
        <div>
          <div style={{ fontSize: 10, fontFamily: "Space Grotesk, sans-serif", letterSpacing: "0.14em", color: "var(--dim)", marginBottom: 12, textTransform: "uppercase" }}>Systems Tenets</div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8 }}>
            {[
              "All writes additive — tombstones, not deletions",
              "Context membership attached at write time by write workers only",
              "No agent writes to the graph directly",
              "Cataloger always one exchange behind — never in response path",
              "Auditor samples async — never blocks write path",
              "Human review queue is the accountability mechanism, not automated override",
            ].map((t, i) => (
              <div key={i} style={{ display: "flex", gap: 10, alignItems: "flex-start", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 6, padding: "11px 13px" }}>
                <div style={{ width: 3, height: 3, borderRadius: "50%", background: "#9d7ee8", marginTop: 6, flexShrink: 0 }}/>
                <span style={{ fontSize: 11.5, color: "var(--muted)", lineHeight: 1.6 }}>{t}</span>
              </div>
            ))}
          </div>
        </div>

      </div>
    </div>
  );
}

window.EngineerView = EngineerView;
