// nature-sound.jsx — ambient music player for nature mode.
// Vertical line with 3D multi-layer wave, fades at top/bottom.

const { useEffect: _ns_ue, useRef: _ns_ur, useState: _ns_us } = React;

function NatureSound({ active }) {
  const canvasRef = _ns_ur(null);
  const audioRef = _ns_ur(null);
  const rafRef = _ns_ur(null);
  const volRef = _ns_ur(0);
  const [vol, setVol] = _ns_us(0);
  const isDragging = _ns_ur(false);
  const dragStartY = _ns_ur(0);
  const dragStartVol = _ns_ur(0);

  _ns_ue(() => {
    if (!active) return;
    const audio = new Audio('music/meditation.m4a');
    audio.loop = true;
    audio.volume = 0;
    audioRef.current = audio;
    return () => { audio.pause(); audio.src = ''; audioRef.current = null; };
  }, [active]);

  _ns_ue(() => {
    const audio = audioRef.current;
    if (!audio) return;
    const v = Math.max(0, Math.min(1, vol));
    audio.volume = v;
    if (v > 0.01 && audio.paused) audio.play().catch(() => { });
    else if (v <= 0.01 && !audio.paused) audio.pause();
  }, [vol]);

  _ns_ue(() => {
    if (!active) return;
    const canvas = canvasRef.current;
    if (!canvas) return;
    const resize = () => {
      canvas.width = canvas.offsetWidth || 64;
      canvas.height = canvas.offsetHeight || 160;
    };
    resize();
    window.addEventListener('resize', resize);
    return () => window.removeEventListener('resize', resize);
  }, [active]);

  _ns_ue(() => {
    if (!active) return;
    const canvas = canvasRef.current;
    if (!canvas) return;

    function draw(ts) {
      const t = ts * 0.001;
      const ctx = canvas.getContext('2d');
      const W = canvas.width, H = canvas.height;
      ctx.clearRect(0, 0, W, H);
      const v = volRef.current;
      const cx = W / 2;

      // Base vertical line — always visible
      ctx.save();
      ctx.shadowBlur = v > 0.01 ? 14 : 6;
      ctx.shadowColor = 'rgba(255,255,255,0.65)';
      ctx.strokeStyle = `rgba(255,255,255,${0.25 + v * 0.55})`;
      ctx.lineWidth = 1 + v * 1.4;
      ctx.beginPath();
      ctx.moveTo(cx, 0);
      ctx.lineTo(cx, H);
      ctx.stroke();
      ctx.restore();

      if (v > 0.012) {
        const maxAmp = v * (W / 2 - 2);

        // 6 depth layers — back (blurry/blue) → front (sharp/white)
        // freq tuned for H≈160px: 0.042≈1 cycle, 0.26≈6 cycles
        const layers = [
          // Far back — dense ripples, bluish, blurry — slowest
          { amp: maxAmp * 0.14, freq: 0.260, spd: 0.16, phase: 0, lw: 0.5, r: 110, g: 155, b: 255, a: 0.18, blur: 5 },
          { amp: maxAmp * 0.22, freq: 0.190, spd: -0.13, phase: Math.PI * 0.55, lw: 0.7, r: 138, g: 180, b: 255, a: 0.24, blur: 3.5 },
          // Mid depth
          { amp: maxAmp * 0.44, freq: 0.115, spd: 0.34, phase: Math.PI * 1.4, lw: 1.1, r: 180, g: 208, b: 255, a: 0.44, blur: 1.5 },
          { amp: maxAmp * 0.62, freq: 0.078, spd: -0.27, phase: Math.PI * 0.85, lw: 1.5, r: 212, g: 228, b: 255, a: 0.56, blur: 0 },
          // Foreground — slow sweep, bright white
          { amp: maxAmp * 0.92, freq: 0.042, spd: 0.52, phase: 0, lw: 2.1, r: 255, g: 255, b: 255, a: 0.88, blur: 0 },
          // Highlight shimmer
          { amp: maxAmp * 0.38, freq: 0.158, spd: -0.72, phase: Math.PI * 0.32, lw: 0.8, r: 255, g: 255, b: 255, a: 0.36, blur: 0 },
        ];

        for (const l of layers) {
          const pts = [];
          for (let y = 0; y <= H; y += 1) {
            pts.push({ x: cx + Math.sin(y * l.freq + t * l.spd + l.phase) * l.amp, y });
          }

          ctx.save();
          if (l.blur > 0) ctx.filter = `blur(${l.blur}px)`;
          ctx.shadowBlur = l.blur > 0 ? 0 : (14 + 10 * v);
          ctx.shadowColor = `rgba(${l.r},${l.g},${l.b},0.55)`;
          ctx.strokeStyle = `rgba(${l.r},${l.g},${l.b},${l.a})`;
          ctx.lineWidth = l.lw;
          ctx.lineJoin = 'round';
          ctx.lineCap = 'round';
          ctx.beginPath();
          ctx.moveTo(pts[0].x, pts[0].y);
          for (let i = 1; i < pts.length; i++) ctx.lineTo(pts[i].x, pts[i].y);
          ctx.stroke();
          ctx.restore();
        }
      }

      // Fade at top and bottom via destination-out
      const fadeH = H * 0.30;
      ctx.save();
      ctx.globalCompositeOperation = 'destination-out';

      const tGrad = ctx.createLinearGradient(0, 0, 0, fadeH);
      tGrad.addColorStop(0, 'rgba(0,0,0,1)');
      tGrad.addColorStop(0.55, 'rgba(0,0,0,0.35)');
      tGrad.addColorStop(1, 'rgba(0,0,0,0)');
      ctx.fillStyle = tGrad;
      ctx.fillRect(0, 0, W, fadeH);

      const bGrad = ctx.createLinearGradient(0, H - fadeH, 0, H);
      bGrad.addColorStop(0, 'rgba(0,0,0,0)');
      bGrad.addColorStop(0.45, 'rgba(0,0,0,0.35)');
      bGrad.addColorStop(1, 'rgba(0,0,0,1)');
      ctx.fillStyle = bGrad;
      ctx.fillRect(0, H - fadeH, W, fadeH);

      ctx.restore();

      rafRef.current = requestAnimationFrame(draw);
    }

    rafRef.current = requestAnimationFrame(draw);
    return () => cancelAnimationFrame(rafRef.current);
  }, [active]);

  const onPointerDown = (e) => {
    isDragging.current = true;
    dragStartY.current = e.clientY;
    dragStartVol.current = volRef.current;
    e.currentTarget.setPointerCapture(e.pointerId);
  };

  const onPointerMove = (e) => {
    if (!isDragging.current) return;
    const dy = dragStartY.current - e.clientY;
    const delta = dy / (window.innerHeight * 0.42);
    const nv = Math.max(0, Math.min(1, dragStartVol.current + delta));
    volRef.current = nv;
    setVol(nv);
  };

  const onPointerUp = () => { isDragging.current = false; };

  if (!active) return null;

  return (
    <div style={{ position: 'absolute', bottom: 'calc(25vh - 100px)', left: 0, right: 0, height: 160, pointerEvents: 'none' }}>
      <canvas ref={canvasRef} style={{ width: '100%', height: '100%', display: 'block' }} />
      <div
        style={{ position: 'absolute', inset: 0, cursor: 'ns-resize', pointerEvents: 'auto' }}
        onPointerDown={onPointerDown}
        onPointerMove={onPointerMove}
        onPointerUp={onPointerUp}
      />
    </div>
  );
}

window.NatureSound = NatureSound;
