// Intro — cinematic loading reveal. Multi-layer wave system rises from the
// bottom, engulfs the viewport, crests, then drains fully off the bottom to
// reveal the main hero. Rich bubble/foam/caustic detail for depth.

const Intro = ({ onDone }) => {
  const canvasRef = React.useRef(null);
  const [done, setDone] = React.useState(false);

  // Persistent bubble pool — spawned over time, each with its own lifecycle
  const bubblesRef = React.useRef([]);
  const splashesRef = React.useRef([]); // crown-splash points when wave hits top

  React.useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');

    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    let w = window.innerWidth;
    let h = window.innerHeight;
    const resize = () => {
      w = window.innerWidth; h = window.innerHeight;
      canvas.width = w * dpr; canvas.height = h * dpr;
      canvas.style.width = w + 'px'; canvas.style.height = h + 'px';
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    };
    resize();
    window.addEventListener('resize', resize);

    const start = performance.now();
    const T_RISE  = 1.3;
    const T_HOLD  = 0.45;
    const T_DRAIN = 1.7;
    const T_TOTAL = T_RISE + T_HOLD + T_DRAIN;

    let lastT = 0;
    let crestedAt = -1; // when the wave first fully covers the screen

    // Pre-seed a few bubbles starting below-screen
    for (let i = 0; i < 22; i++) {
      bubblesRef.current.push(makeBubble(w, h, Math.random() * 2));
    }

    function makeBubble(w, h, age = 0) {
      return {
        x: Math.random() * w,
        y: h + Math.random() * 60,         // start below screen
        r: 1 + Math.random() * 4,
        vy: 40 + Math.random() * 90,       // upward speed
        wobbleAmp: 4 + Math.random() * 14,
        wobbleHz: 0.8 + Math.random() * 1.6,
        phase: Math.random() * Math.PI * 2,
        alpha: 0.35 + Math.random() * 0.45,
        age,
        life: 6 + Math.random() * 4,
      };
    }

    // Helper: compute water surface at (x, t) with composed layers
    const surfaceAt = (x, t, baseY, isDraining) => {
      // Main carrier wave (tall, slow)
      const a1 = Math.sin(x * 0.009  + t * 2.2) * 14;
      // Mid wave
      const a2 = Math.sin(x * 0.018  + t * 3.6) * 8;
      // Small chop
      const a3 = Math.sin(x * 0.045  + t * 6.2) * 3;
      // Occasional big swell (from random offset)
      const a4 = Math.sin(x * 0.004  + t * 1.4) * 10;
      return baseY + a1 + a2 + a3 + a4 * 0.6;
    };

    let raf;
    const loop = (now) => {
      const t = (now - start) / 1000;
      const dt = Math.min(0.05, t - lastT);
      lastT = t;

      let baseSurfaceY;
      let phase;
      if (t < T_RISE) {
        const p = t / T_RISE;
        const eased = p < 0.5 ? 2*p*p : 1 - Math.pow(-2*p+2, 2) / 2;
        baseSurfaceY = h - eased * h;
        phase = 'rising';
      } else if (t < T_RISE + T_HOLD) {
        baseSurfaceY = -20;
        phase = 'cresting';
        if (crestedAt < 0) {
          crestedAt = t;
          // Spawn a burst of crown splash points across the top
          for (let i = 0; i < 18; i++) {
            splashesRef.current.push({
              x: (i + Math.random() * 0.6) * (w / 18),
              y: 40 + Math.random() * 20,
              vy: -(120 + Math.random() * 180),
              vx: (Math.random() - 0.5) * 80,
              t0: t,
              r: 3 + Math.random() * 3,
              life: 1.2 + Math.random() * 0.6,
            });
          }
        }
      } else if (t < T_TOTAL) {
        const dp = (t - T_RISE - T_HOLD) / T_DRAIN;
        const eased = dp < 0.5 ? 2*dp*dp : 1 - Math.pow(-2*dp+2, 2) / 2;
        baseSurfaceY = eased * (h + 80);
        phase = 'draining';
      } else {
        setDone(true);
        if (onDone) onDone();
        return;
      }

      const isDraining = phase === 'draining';

      ctx.clearRect(0, 0, w, h);

      // ─── Deep atmospheric backdrop while submerged ──────────────────────
      if (baseSurfaceY < h * 0.6) {
        const alpha = Math.max(0, Math.min(1, (h * 0.6 - baseSurfaceY) / (h * 0.6)));
        const skyG = ctx.createLinearGradient(0, 0, 0, h);
        skyG.addColorStop(0, `rgba(127,179,201,${0.25 * alpha})`);
        skyG.addColorStop(1, `rgba(61,122,149,${0.15 * alpha})`);
        ctx.fillStyle = skyG;
        ctx.fillRect(0, 0, w, h);
      }

      // ─── 1) Back wave layer (deeper, darker, slower, offset) ────────────
      // (removed — was reading as horizontal bands)

      // ─── 2) Front/primary water body ────────────────────────────────────
      ctx.beginPath();
      ctx.moveTo(0, h + 10);
      const step = 5;
      for (let x = 0; x <= w; x += step) {
        const y = surfaceAt(x, t, baseSurfaceY, isDraining);
        ctx.lineTo(x, y);
      }
      ctx.lineTo(w, h + 10);
      ctx.closePath();
      const g = ctx.createLinearGradient(0, baseSurfaceY, 0, h);
      g.addColorStop(0, '#B8DDEA');
      g.addColorStop(0.25, '#7FB3C9');
      g.addColorStop(1, '#3D7A95');
      ctx.fillStyle = g;
      ctx.fill();

      // ─── 4) Thick foam crest line ───────────────────────────────────────
      ctx.beginPath();
      for (let x = 0; x <= w; x += 4) {
        const y = surfaceAt(x, t, baseSurfaceY, isDraining);
        if (x === 0) ctx.moveTo(x, y);
        else ctx.lineTo(x, y);
      }
      ctx.strokeStyle = 'rgba(255,255,255,0.85)';
      ctx.lineWidth = 2.4;
      ctx.stroke();

      // Foam bubbles along the crest
      for (let x = 0; x < w; x += 22) {
        const jitter = Math.sin(x * 0.1 + t * 2) * 10;
        const y = surfaceAt(x + jitter, t, baseSurfaceY, isDraining);
        const r = 1.2 + ((x * 13 + Math.floor(t * 2)) % 3);
        ctx.beginPath();
        ctx.arc(x + jitter, y - 2, r, 0, Math.PI * 2);
        ctx.fillStyle = 'rgba(255,255,255,0.5)';
        ctx.fill();
      }

      // ─── 5) Rising bubbles (continuously respawn) ──────────────────────
      const bubbles = bubblesRef.current;
      // Spawn new bubbles over time while wave is active (not draining)
      if (phase !== 'draining' && Math.random() < 0.75) {
        for (let k = 0; k < 2; k++) {
          bubbles.push(makeBubble(w, h));
        }
      } else if (phase === 'draining' && Math.random() < 0.2) {
        bubbles.push(makeBubble(w, h));
      }
      // Update and draw
      for (let i = bubbles.length - 1; i >= 0; i--) {
        const b = bubbles[i];
        b.age += dt;
        b.y -= b.vy * dt;
        const surfaceY = surfaceAt(b.x, t, baseSurfaceY, isDraining);
        // Pop at surface
        if (b.y < surfaceY - 4 || b.age > b.life) {
          // Pop: small ring
          if (b.y > 0 && b.y < h) {
            ctx.beginPath();
            ctx.arc(b.x, surfaceY, b.r + 2, 0, Math.PI * 2);
            ctx.strokeStyle = 'rgba(255,255,255,0.5)';
            ctx.lineWidth = 0.8;
            ctx.stroke();
          }
          bubbles.splice(i, 1);
          continue;
        }
        if (b.y < 0) { bubbles.splice(i, 1); continue; }
        const wx = b.x + Math.sin(b.age * b.wobbleHz + b.phase) * b.wobbleAmp;
        // Bubble body
        ctx.beginPath();
        ctx.arc(wx, b.y, b.r, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(255,255,255,${b.alpha * 0.55})`;
        ctx.fill();
        ctx.strokeStyle = `rgba(255,255,255,${b.alpha})`;
        ctx.lineWidth = 0.6;
        ctx.stroke();
        // Highlight dot
        ctx.beginPath();
        ctx.arc(wx - b.r * 0.35, b.y - b.r * 0.35, b.r * 0.35, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(255,255,255,${b.alpha})`;
        ctx.fill();
      }

      // ─── 6) Crown splash droplets (when wave hits top) ─────────────────
      const splashes = splashesRef.current;
      for (let i = splashes.length - 1; i >= 0; i--) {
        const s = splashes[i];
        const age = t - s.t0;
        if (age > s.life) { splashes.splice(i, 1); continue; }
        // Gravity
        s.vy += 420 * dt;
        s.x += s.vx * dt;
        s.y += s.vy * dt;
        const alpha = Math.max(0, 1 - age / s.life);
        ctx.beginPath();
        ctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(255,255,255,${alpha * 0.85})`;
        ctx.fill();
      }

      // ─── 8) Overall edge vignette for depth ─────────────────────────────
      const vg = ctx.createRadialGradient(w/2, h/2, Math.min(w,h) * 0.3, w/2, h/2, Math.max(w,h) * 0.7);
      vg.addColorStop(0, 'rgba(0,0,0,0)');
      vg.addColorStop(1, 'rgba(20,50,65,0.25)');
      ctx.fillStyle = vg;
      ctx.fillRect(0, 0, w, h);

      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('resize', resize);
    };
  }, []);

  if (done) return null;

  return (
    <canvas
      ref={canvasRef}
      style={{
        position: 'fixed',
        inset: 0,
        zIndex: 200,
        pointerEvents: 'none',
      }}
    />
  );
};

window.Intro = Intro;
