// GraphCanvas — SVG renderer for the attack graph (nodes + normal edges).
// Findings + chain are overlaid on top by AttackGraphReveal.

function GraphCanvas({ graph, showFindings, findingVisible, chainActive, children }) {
  const { React, Icon } = window;
  const { w, h } = graph.viewBox;
  const byId = Object.fromEntries(graph.nodes.map(n => [n.id, n]));

  const nodeW = 144, nodeH = 52;

  return (
    <svg className="ag-svg" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="xMidYMid meet">
      <defs>
        <pattern id="ag-grid" width="28" height="28" patternUnits="userSpaceOnUse">
          <path d="M 28 0 L 0 0 0 28" fill="none" stroke="rgba(12,20,16,0.08)" strokeWidth="0.5" />
        </pattern>
      </defs>
      <rect width={w} height={h} fill="url(#ag-grid)" />

      {/* normal edges */}
      {graph.edges.map((e, i) => {
        const a = byId[e.from], b = byId[e.to];
        if (!a || !b) return null;
        return (
          <line key={i} x1={a.x} y1={a.y} x2={b.x} y2={b.y}
                stroke={chainActive ? '#4A5550' : '#8A948F'} strokeWidth="1.2"
                opacity={chainActive ? 0.45 : 0.85}
                style={{ transition: 'stroke 400ms ease, opacity 400ms ease' }} />
        );
      })}

      {/* nodes */}
      {graph.nodes.map((n) => (
        <g key={n.id} className={`ag-node kind-${n.kind}`}>
          <rect x={n.x - nodeW/2} y={n.y - nodeH/2} width={nodeW} height={nodeH} rx="4"
                fill="#F5F2EB" stroke="#15251E" strokeWidth="1.2" />
          <foreignObject x={n.x - nodeW/2 + 10} y={n.y - 10} width="20" height="20">
            <div xmlns="http://www.w3.org/1999/xhtml" style={{color:'#2D4A3E'}}>
              <Icon name={n.icon} size={18} />
            </div>
          </foreignObject>
          <text x={n.x - nodeW/2 + 36} y={n.y - 2}
                fontFamily="'JetBrains Mono', ui-monospace, monospace"
                fontSize="12" fill="#15251E" fontWeight="500">
            {n.label}
          </text>
          <text x={n.x - nodeW/2 + 36} y={n.y + 13}
                fontFamily="'JetBrains Mono', ui-monospace, monospace"
                fontSize="9.5" fill="#6B7A72" letterSpacing="0.04em">
            {n.kind}
          </text>
        </g>
      ))}

      {/* findings overlay */}
      {showFindings && graph.findings.map((f, i) => {
        const n = byId[f.nodeId]; if (!n) return null;
        // offset duplicates on same node
        const sameNodeIdx = graph.findings.filter((g, j) => j < i && g.nodeId === f.nodeId).length;
        const dx = nodeW/2 - 8 + sameNodeIdx * 14;
        const dy = -nodeH/2 + 6;
        return (
          <window.FindingDot key={i}
            x={n.x + dx} y={n.y + dy}
            severity={f.severity} label={f.label}
            visible={findingVisible(i)} i={i} />
        );
      })}

      {/* chain overlay is passed in as children for layering control */}
      {children}
    </svg>
  );
}
window.GraphCanvas = GraphCanvas;
