// DNA helix canvas — three named behaviors that retune the whole feel.
// `behavior` accepts: "dormant" | "breathing" | "reactive"
function FasciaCanvas({ behavior = "breathing" }) {
  const ref = React.useRef(null);
  const stateRef = React.useRef({ mouse: { x: -9999, y: -9999, active: false }, t: 0 });
  const behaviorRef = React.useRef(behavior);
  React.useEffect(() => { behaviorRef.current = behavior; }, [behavior]);

  React.useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    let raf;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;

    function resize() {
      const r = canvas.getBoundingClientRect();
      canvas.width = Math.floor(r.width * dpr);
      canvas.height = Math.floor(r.height * dpr);
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    function onMove(e) {
      const r = canvas.getBoundingClientRect();
      const t = e.touches ? e.touches[0] : e;
      stateRef.current.mouse = { x: t.clientX - r.left, y: t.clientY - r.top, active: true };
    }
    function onLeave() { stateRef.current.mouse.active = false; }

    // Behavior presets — each retunes multiple knobs at once
    const PRESETS = {
      dormant:    { speedMul: 0.25, trail: 0.12, cursorPull: 0.05, cursorBoost: 0.20, helixCount: 2, ampMul: 0.85, brightness: 0.65 },
      breathing:  { speedMul: 1.00, trail: 0.22, cursorPull: 0.35, cursorBoost: 0.55, helixCount: 3, ampMul: 1.00, brightness: 1.00 },
      reactive:   { speedMul: 1.55, trail: 0.34, cursorPull: 0.85, cursorBoost: 1.10, helixCount: 4, ampMul: 1.20, brightness: 1.35 },
    };

    let t0 = performance.now();
    function frame(t) {
      const dt = Math.min(50, t - t0); t0 = t;
      const r = canvas.getBoundingClientRect();
      const w = r.width, h = r.height;
      const P = PRESETS[behaviorRef.current] || PRESETS.breathing;
      const time = (stateRef.current.t += (dt / 1000) * P.speedMul);
      const { mouse } = stateRef.current;

      ctx.fillStyle = `rgba(26, 26, 26, ${P.trail.toFixed(3)})`;
      ctx.fillRect(0, 0, w, h);

      const isMobile = w < 760;
      const baseHelices = [
        { yMid: h * 0.22, amp: h * 0.09, freq: 0.0095, speed: 0.55, phase: 0.0, depth: 0.45 },
        { yMid: h * 0.45, amp: h * 0.13, freq: 0.0075, speed: 0.7,  phase: 1.7, depth: 0.85 },
        { yMid: h * 0.68, amp: h * 0.10, freq: 0.0110, speed: 0.42, phase: 3.1, depth: 0.30 },
        { yMid: h * 0.88, amp: h * 0.08, freq: 0.0130, speed: 0.62, phase: 4.4, depth: 0.55 },
      ].slice(0, P.helixCount);

      const cursorR = Math.min(220, Math.min(w, h) * 0.22);
      const cursorR2 = cursorR * cursorR;
      const step = Math.max(6, Math.floor(w / (isMobile ? 80 : 160)));

      function strandY(hel, x, side) {
        const angle = x * hel.freq + time * hel.speed + hel.phase;
        let y = hel.yMid + Math.sin(angle) * hel.amp * P.ampMul * side;
        if (mouse.active) {
          const dx = mouse.x - x, dy = mouse.y - y;
          const d2 = dx * dx + dy * dy;
          if (d2 < cursorR2) {
            const k = 1 - d2 / cursorR2;
            y += (mouse.y - y) * k * P.cursorPull;
          }
        }
        return y;
      }
      function strandWidth(hel, x, side) {
        const angle = x * hel.freq + time * hel.speed + hel.phase;
        return Math.abs(Math.sin(angle));
      }

      ctx.lineCap = "round";
      for (const hel of baseHelices) {
        const rungStep = step * (isMobile ? 5 : 4);
        for (let x = 0; x <= w + rungStep; x += rungStep) {
          const yA = strandY(hel, x, 1);
          const yB = strandY(hel, x, -1);
          const cross = Math.abs(yA - yB) / (hel.amp * P.ampMul * 2);
          let alpha = (0.06 + cross * 0.22) * (0.5 + hel.depth * 0.7) * P.brightness;
          if (mouse.active) {
            const dxA = mouse.x - x;
            const da2 = dxA * dxA + (mouse.y - (yA + yB) / 2) ** 2;
            if (da2 < cursorR2) alpha += (1 - da2 / cursorR2) * 0.45 * P.cursorBoost;
          }
          ctx.strokeStyle = `rgba(184, 151, 63, ${Math.min(0.9, alpha).toFixed(3)})`;
          ctx.lineWidth = 0.5 + hel.depth * 0.6;
          ctx.beginPath();
          ctx.moveTo(x, yA);
          ctx.lineTo(x, yB);
          ctx.stroke();
        }
        for (const side of [1, -1]) {
          ctx.beginPath();
          let started = false;
          for (let x = -step; x <= w + step; x += step) {
            const y = strandY(hel, x, side);
            if (!started) { ctx.moveTo(x, y); started = true; }
            else ctx.lineTo(x, y);
          }
          const baseA = (0.18 + hel.depth * 0.32) * P.brightness;
          ctx.strokeStyle = `rgba(184, 151, 63, ${baseA.toFixed(3)})`;
          ctx.lineWidth = 0.8 + hel.depth * 1.1;
          ctx.stroke();
        }
        const nodeStep = step * 2;
        for (let x = 0; x <= w + nodeStep; x += nodeStep) {
          for (const side of [1, -1]) {
            const y = strandY(hel, x, side);
            const wMul = strandWidth(hel, x, side);
            const size = (1.0 + hel.depth * 1.6) * (0.5 + wMul * 0.8);
            let alpha = (0.18 + hel.depth * 0.42) * P.brightness;
            if (mouse.active) {
              const dx = mouse.x - x, dy = mouse.y - y;
              const d2 = dx * dx + dy * dy;
              if (d2 < cursorR2) {
                const k = 1 - d2 / cursorR2;
                alpha = Math.min(1, alpha + k * 0.7 * P.cursorBoost);
                const glow = ctx.createRadialGradient(x, y, 0, x, y, size * 6);
                glow.addColorStop(0, `rgba(184, 151, 63, ${(k * 0.32 * P.cursorBoost).toFixed(3)})`);
                glow.addColorStop(1, "rgba(184, 151, 63, 0)");
                ctx.fillStyle = glow;
                ctx.beginPath();
                ctx.arc(x, y, size * 6, 0, Math.PI * 2);
                ctx.fill();
              }
            }
            ctx.fillStyle = `rgba(184, 151, 63, ${alpha.toFixed(3)})`;
            ctx.beginPath();
            ctx.arc(x, y, size, 0, Math.PI * 2);
            ctx.fill();
          }
        }
      }

      if (!reduce) raf = requestAnimationFrame(frame);
    }

    resize();
    raf = requestAnimationFrame(frame);
    window.addEventListener("resize", resize);
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseleave", onLeave);
    canvas.addEventListener("touchmove", onMove, { passive: true });
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("resize", resize);
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseleave", onLeave);
      canvas.removeEventListener("touchmove", onMove);
    };
  }, []);

  return <canvas id="fascia-canvas" ref={ref} />;
}

window.FasciaCanvas = FasciaCanvas;
