// ChainPath — animated attack path that ignites edge-by-edge.
// Given the list of hops, a progress 0..1 maps to how many hops have drawn.

function ChainPath({ nodes, hops, localP, active }) {
  const { React } = window;
  const byId = Object.fromEntries(nodes.map(n => [n.id, n]));

  // localP: 0..1 across state C. Split into hops.length segments.
  const segmentSize = 1 / hops.length;

  const segments = hops.map((h, i) => {
    const a = byId[h.from], b = byId[h.to];
    if (!a || !b) return null;
    const t0 = i * segmentSize;
    const t1 = (i + 1) * segmentSize;
    const p  = Math.max(0, Math.min(1, (localP - t0) / (t1 - t0)));
    return { hop: h, a, b, p, index: i };
  }).filter(Boolean);

  // Mid-hop gets the tooltip; pick the latest segment currently drawing (0<p<1)
  // or fall back to the last completed one.
  let tipIdx = -1;
  for (let i = segments.length - 1; i >= 0; i--) {
    if (segments[i].p > 0) { tipIdx = i; break; }
  }
  const allDone = segments.every(s => s.p >= 1);

  return (
    <g className={`chain-path ${active ? 'is-active' : ''} ${allDone ? 'all-done' : ''}`}>
      {segments.map(({ hop, a, b, p, index }) => {
        if (p <= 0) return null;
        if (hop.terminal) {
          // terminal: pulse on the target node
          return (
            <circle key={index} cx={b.x} cy={b.y} r={44 + index * 2}
                    fill="none" stroke="#EF4444" strokeWidth="2"
                    opacity={0.6 * (1 - p)} className="chain-terminal" />
          );
        }
        const dx = b.x - a.x, dy = b.y - a.y;
        const len = Math.hypot(dx, dy);
        const drawn = len * p;
        return (
          <g key={index}>
            <line x1={a.x} y1={a.y} x2={a.x + dx * p} y2={a.y + dy * p}
                  stroke="#EF4444" strokeWidth="2.6"
                  strokeDasharray="7 6"
                  style={{ filter: 'drop-shadow(0 0 6px rgba(239,68,68,0.6))' }} />
          </g>
        );
      })}

      {tipIdx >= 0 && segments[tipIdx] && !segments[tipIdx].hop.terminal && (
        <ChainTip seg={segments[tipIdx]} />
      )}
    </g>
  );
}

function ChainTip({ seg }) {
  const { a, b, hop } = seg;
  const mx = (a.x + b.x) / 2;
  const my = (a.y + b.y) / 2 - 18;
  const w  = Math.max(hop.tooltip.length * 6.5 + 68, 180);
  return (
    <g className="chain-tip">
      <rect x={mx - w/2} y={my - 16} width={w} height="26" rx="3"
            fill="#0B0F0E" stroke="#EF4444" strokeWidth="1" />
      <text x={mx - w/2 + 10} y={my + 2}
            fontFamily="'JetBrains Mono', ui-monospace, monospace"
            fontSize="11" fill="#D7DDD9">
        <tspan fill="#E8847C">▸</tspan> {hop.tooltip}
      </text>
      <text x={mx + w/2 - 10} y={my + 2} textAnchor="end"
            fontFamily="'JetBrains Mono', ui-monospace, monospace"
            fontSize="10.5" fill="#D4915D">
        cvss·e {hop.cvss.toFixed(1)}
      </text>
    </g>
  );
}

window.ChainPath = ChainPath;
