// Diagrama técnico de red neuronal.
// ON: dibujo de líneas L→R por capa, luego números forward (gris) y backward (rojo tenue).
// OFF: solo loop cíclico de dibujo, sin números.
const NeuralNetwork = () => {
  const W = 480;
  const H = 360;
  const padX = 60;
  const padY = 36;

  const layers = [4, 5, 3];

  // Pequeñas muestras de "pesos" — decimales positivos y negativos.
  const SAMPLE_WEIGHTS = [
    '0.42', '−0.18', '0.71', '0.09', '−0.33', '0.56',
    '0.81', '−0.05', '0.27', '0.13', '−0.62', '0.91',
    '0.34', '−0.27', '0.50', '0.08', '0.66', '−0.41',
  ];

  const nodes = React.useMemo(() => {
    const out = [];
    layers.forEach((count, layerIdx) => {
      const x = layers.length === 1
        ? W / 2
        : padX + layerIdx * ((W - 2 * padX) / (layers.length - 1));
      const usable = H - 2 * padY;
      const spacing = count > 1 ? usable / (count - 1) : 0;
      for (let i = 0; i < count; i++) {
        const y = count === 1 ? H / 2 : padY + i * spacing;
        out.push({ x, y, layer: layerIdx, idxInLayer: i, id: `n-${layerIdx}-${i}` });
      }
    });
    return out;
  }, []);

  const connections = React.useMemo(() => {
    const out = [];
    for (let l = 0; l < layers.length - 1; l++) {
      const left = nodes.filter(n => n.layer === l);
      const right = nodes.filter(n => n.layer === l + 1);
      left.forEach(a => right.forEach(b => {
        const dx = b.x - a.x;
        const dy = b.y - a.y;
        const len = Math.sqrt(dx * dx + dy * dy);
        out.push({ from: a, to: b, len, fromLayer: l, id: `${a.id}->${b.id}` });
      }));
    }
    return out;
  }, [nodes]);

  // Tiempos:
  //   - Cada capa de líneas se dibuja con un offset (capa 0 a 0s, capa 1 a 0.35s).
  //   - Línea individual tarda ~0.95s.
  //   - Allá de los ~1.3s todas las líneas están dibujadas → comienzan los flujos.
  const FLOW_START = 1.4;        // s — después del dibujo
  const FLOW_CYCLE = 3.6;        // s — duración del cycle FF+BP
  const STAGGER_PER_CONN = 0.05; // s entre flujos

  return (
    <div className="nn-canvas" role="img" aria-label="Diagrama técnico de red neuronal: tres capas de nodos conectados, con flujos de pesos forward y backpropagation.">
      <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMid meet" aria-hidden="true">
        <g>
          {connections.map((c, i) => {
            const drawDelay = c.fromLayer * 0.32; // stagger por capa
            return (
              <line
                key={c.id}
                className="nn-link"
                x1={c.from.x} y1={c.from.y}
                x2={c.to.x} y2={c.to.y}
                style={{
                  '--len': c.len,
                  '--draw-delay': `${drawDelay}s`,
                }}
              />
            );
          })}
        </g>
        <g>
          {nodes.map((n, i) => (
            <circle
              key={n.id}
              className="nn-node"
              cx={n.x} cy={n.y} r={4.5}
            />
          ))}
        </g>
      </svg>

      <div className="nn-overlay" aria-hidden="true">
        {connections.map((c, i) => {
          const x1 = (c.from.x / W) * 100;
          const y1 = (c.from.y / H) * 100;
          const x2 = (c.to.x   / W) * 100;
          const y2 = (c.to.y   / H) * 100;
          // Stagger en cascada por conexión + ligera variación por capa
          const flowDelay = FLOW_START + (c.fromLayer * 0.18) + (i * STAGGER_PER_CONN) % FLOW_CYCLE;
          const weight = SAMPLE_WEIGHTS[i % SAMPLE_WEIGHTS.length];
          return (
            <span
              key={c.id}
              className="flow-num"
              style={{
                '--x1': `${x1}%`,
                '--y1': `${y1}%`,
                '--x2': `${x2}%`,
                '--y2': `${y2}%`,
                '--flow-delay': `${flowDelay}s`,
              }}
            >
              {weight}
            </span>
          );
        })}
      </div>

      <span className="nn-label">
        <span className="nn-blink" />
        nn.live · {layers.join('-')} · ff/bp
      </span>
    </div>
  );
};

window.NeuralNetwork = NeuralNetwork;
