// Hero — scroll-driven crystallization animation.
// Particles drift chaotically; as the user scrolls, they magnetize into a
// breathing outer ring, then a counter-rotating inner ring materializes.
const { useEffect: useEffectHero, useRef: useRefHero, useState: useStateHero } = React;

function Crystallizer() {
  const canvasRef = useRefHero(null);

  useEffectHero(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    const W = 560, H = 620;
    canvas.width = W * dpr;
    canvas.height = H * dpr;
    canvas.style.width = W + "px";
    canvas.style.height = H + "px";

    const cx = W / 2, cy = H / 2;
    const outerR = 180;
    const innerR = 118;

    const N_OUTER = 340;
    const N_INNER = 220;
    const N_FREE = 180;

    const easeInOut = (t) => t * t * (3 - 2 * t);
    const smooth = (t, a, b) => {
      if (t <= a) return 0;
      if (t >= b) return 1;
      return easeInOut((t - a) / (b - a));
    };

    // Build particles
    const particles = [];
    const rand = (min, max) => min + Math.random() * (max - min);

    function spawn(role, idx, total) {
      // Chaos home: random point in canvas with slight bias toward center.
      const ang = rand(0, Math.PI * 2);
      const radChaos = rand(40, 280);
      const hx = cx + Math.cos(ang) * radChaos;
      const hy = cy + Math.sin(ang) * radChaos;

      const p = {
        role, // 'outer' | 'inner' | 'free'
        // chaos state
        x: hx, y: hy,
        vx: rand(-0.3, 0.3), vy: rand(-0.3, 0.3),
        // per-particle drift noise
        dpx: rand(0, Math.PI * 2),
        dpy: rand(0, Math.PI * 2),
        dsx: rand(0.00015, 0.0005),
        dsy: rand(0.00015, 0.0005),
        // ring slot
        slot: idx / total,
        // ring radius jitter for imperfection
        rJitter: rand(-4, 4),
        // ring phase offset for breathing
        phase: rand(0, Math.PI * 2),
        // size + alpha
        size: rand(0.6, 1.6) + (Math.random() < 0.08 ? 1.2 : 0),
        baseA: rand(0.35, 0.95),
        // trail
        tx: hx, ty: hy,
        // twinkle
        tw: rand(0, Math.PI * 2),
        twSp: rand(0.015, 0.045),
      };
      return p;
    }

    for (let i = 0; i < N_OUTER; i++) particles.push(spawn("outer", i, N_OUTER));
    for (let i = 0; i < N_INNER; i++) particles.push(spawn("inner", i, N_INNER));
    for (let i = 0; i < N_FREE;  i++) particles.push(spawn("free",  i, N_FREE));

    let raf;
    let t0 = performance.now();

    function tick(now) {
      const t = (now - t0) / 1000;
      // Time-driven progress: reaches full state (~1.0) by 5s, with a
      // gentle tail past 1 for breathing/rotation to keep evolving.
      const progress = Math.min(1, t / 5);

      // Phase windows — timed so both rings are formed by ~5s total.
      const outerLock = smooth(progress, 0.05, 0.55);  // ~0.25s → 2.75s
      const innerLock = smooth(progress, 0.45, 0.98);  // ~2.25s → 4.9s
      const shedFree  = smooth(progress, 0.10, 0.50);

      // Breathing scalars — only visible once locked
      const breathOuter = 1 + Math.sin(t * Math.PI) * 0.035 * outerLock;   // ~2s cycle
      const breathInner = 1 + Math.sin(t * Math.PI * 1.1 + Math.PI) * 0.045 * innerLock;

      // Rotations
      const rotOuter =  t * 0.08;
      const rotInner = -t * 0.14;

      // Full-clear every frame (transparent canvas — no black fill).
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      ctx.clearRect(0, 0, W, H);

      // Ambient warm glow behind rings
      if (outerLock > 0.05) {
        const g = ctx.createRadialGradient(cx, cy, 20, cx, cy, 240);
        g.addColorStop(0, `rgba(215,196,151,${0.10 * outerLock})`);
        g.addColorStop(1, "rgba(215,196,151,0)");
        ctx.fillStyle = g;
        ctx.fillRect(0, 0, W, H);
      }

      // Faint guide ring strokes (gets stronger with lock)
      if (outerLock > 0.1) {
        ctx.strokeStyle = `rgba(215,196,151,${0.08 * outerLock})`;
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.arc(cx, cy, outerR * breathOuter, 0, Math.PI * 2);
        ctx.stroke();
      }
      if (innerLock > 0.1) {
        ctx.strokeStyle = `rgba(215,196,151,${0.06 * innerLock})`;
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.arc(cx, cy, innerR * breathInner, 0, Math.PI * 2);
        ctx.stroke();
      }

      for (const p of particles) {
        p.tw += p.twSp;

        // --- Compute chaotic home position (drift) ---
        const driftX = Math.sin(now * p.dsx + p.dpx) * 22;
        const driftY = Math.cos(now * p.dsy + p.dpy) * 22;
        // slow random walk nudge
        p.vx += (Math.random() - 0.5) * 0.012;
        p.vy += (Math.random() - 0.5) * 0.012;
        p.vx *= 0.965;
        p.vy *= 0.965;

        // Chaos target = current position + velocity + drift accent
        const chaosTX = p.x + p.vx + driftX * 0.008;
        const chaosTY = p.y + p.vy + driftY * 0.008;

        // --- Compute ring target ---
        let ringX = 0, ringY = 0, lock = 0, accentAmt = 0, roleAlpha = 1;

        if (p.role === "outer") {
          const ang = p.slot * Math.PI * 2 + rotOuter;
          const r = (outerR + p.rJitter) * breathOuter;
          ringX = cx + Math.cos(ang) * r;
          ringY = cy + Math.sin(ang) * r;
          lock = outerLock;
          accentAmt = lock;
        } else if (p.role === "inner") {
          const ang = p.slot * Math.PI * 2 + rotInner;
          const r = (innerR + p.rJitter * 0.7) * breathInner;
          ringX = cx + Math.cos(ang) * r;
          ringY = cy + Math.sin(ang) * r;
          lock = innerLock;
          accentAmt = lock * 0.7;
          roleAlpha = 0.65 + innerLock * 0.15;
        } else {
          // free particles: never fully lock. They fade out as we scroll.
          ringX = chaosTX;
          ringY = chaosTY;
          lock = 0;
          roleAlpha = 1 - shedFree * 0.85;
        }

        // Blend toward ring target with spring
        const targetX = chaosTX * (1 - lock) + ringX * lock;
        const targetY = chaosTY * (1 - lock) + ringY * lock;

        // Spring: stiffer as we lock
        const k = 0.015 + lock * 0.22;
        p.x += (targetX - p.x) * k;
        p.y += (targetY - p.y) * k;

        // Trail follows with lag (shorter when ordered, longer when chaotic)
        const trailK = 0.18 + lock * 0.25;
        p.tx += (p.x - p.tx) * trailK;
        p.ty += (p.y - p.ty) * trailK;

        // --- Render ---
        const twinkle = 0.75 + 0.25 * Math.sin(p.tw);
        const alpha = Math.max(0, p.baseA * twinkle * roleAlpha);

        // Trail segment
        if (p.role !== "free" || lock < 0.05) {
          ctx.strokeStyle = `rgba(255,255,255,${alpha * 0.25})`;
          ctx.lineWidth = Math.max(0.5, p.size * 0.7);
          ctx.beginPath();
          ctx.moveTo(p.tx, p.ty);
          ctx.lineTo(p.x, p.y);
          ctx.stroke();
        }

        // Core dot
        const size = Math.max(0.6, p.size) * (1 + lock * 0.15);
        ctx.fillStyle = `rgba(255,255,255,${alpha})`;
        ctx.beginPath();
        ctx.arc(p.x, p.y, size, 0, Math.PI * 2);
        ctx.fill();

        // Warm accent halo on locked particles
        if (accentAmt > 0.15) {
          ctx.fillStyle = `rgba(215,196,151,${0.18 * accentAmt})`;
          ctx.beginPath();
          ctx.arc(p.x, p.y, size * 2.6, 0, Math.PI * 2);
          ctx.fill();
        }

        // Occasional bright sparks on outer ring
        if (p.role === "outer" && lock > 0.7 && Math.random() < 0.001) {
          ctx.fillStyle = `rgba(255,245,220,${0.9})`;
          ctx.beginPath();
          ctx.arc(p.x, p.y, size * 3, 0, Math.PI * 2);
          ctx.fill();
        }
      }

      // Center mote — crystallizes last. A tiny bright core + thin ring.
      if (innerLock > 0.3) {
        const a = innerLock;
        const pulse = 1 + Math.sin(t * 2) * 0.15;
        ctx.fillStyle = `rgba(215,196,151,${0.18 * a})`;
        ctx.beginPath();
        ctx.arc(cx, cy, 12 * pulse, 0, Math.PI * 2);
        ctx.fill();
        ctx.fillStyle = `rgba(255,245,220,${0.9 * a})`;
        ctx.beginPath();
        ctx.arc(cx, cy, 1.8, 0, Math.PI * 2);
        ctx.fill();
      }

      raf = requestAnimationFrame(tick);
    }

    // start transparent
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    ctx.clearRect(0, 0, W, H);

    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  return (
    <canvas
      ref={canvasRef}
      style={{
        display: "block",
        borderRadius: 12,
        // soft vignette edge so the canvas blends into the section
        maskImage: "radial-gradient(ellipse 80% 80% at 50% 50%, black 55%, transparent 100%)",
        WebkitMaskImage: "radial-gradient(ellipse 80% 80% at 50% 50%, black 55%, transparent 100%)",
      }}
    />
  );
}

function AtlasFigure() {
  return (
    <div style={{ position: "relative", width: 560, height: 620 }}>
      <Crystallizer />
    </div>
  );
}

function TagStrip() {
  return (
    <div
      className="mono"
      style={{
        border: "1px solid var(--line-strong)",
        padding: "10px 18px",
        fontSize: 11,
        letterSpacing: "0.14em",
        color: "var(--text-dim)",
        textTransform: "uppercase",
        display: "inline-flex",
        flexDirection: "column",
        alignItems: "center",
        gap: 6,
        background: "rgba(0,0,0,0.35)",
        backdropFilter: "blur(4px)",
      }}
    >
      <div style={{ display: "flex", gap: 18 }}>
        <span>Framework-agnostic</span>
        <span style={{ color: "var(--text-faint)" }}>·</span>
        <span>Language-agnostic</span>
        <span style={{ color: "var(--text-faint)" }}>·</span>
        <span>Platform-agnostic</span>
      </div>
      <div style={{ display: "flex", gap: 18 }}>
        <span>Full OWASP agentic coverage</span>
        <span style={{ color: "var(--text-faint)" }}>·</span>
        <span>Verified by 10,500+ tests</span>
      </div>
    </div>
  );
}

function Hero() {
  return (
    <section
      style={{
        position: "relative",
        minHeight: "88vh",
        display: "flex",
        alignItems: "center",
        borderBottom: "1px solid var(--line)",
        overflow: "hidden",
      }}
    >
      <Starfield opacity={0.6} />
      <div
        aria-hidden
        style={{
          position: "absolute",
          inset: 0,
          background:
            "radial-gradient(ellipse 60% 50% at 50% 100%, oklch(0.82 0.14 75 / 0.10), transparent 70%)",
          pointerEvents: "none",
        }}
      />
      <div
        style={{
          maxWidth: 1200,
          margin: "0 auto",
          padding: "72px 28px 60px",
          width: "100%",
          position: "relative",
          zIndex: 2,
        }}
      >
        <div
          style={{
            display: "flex",
            justifyContent: "center",
            marginBottom: 48,
          }}
        >
          <TagStrip />
        </div>
        <div
          style={{
            display: "grid",
            gridTemplateColumns: "1fr 1fr",
            gap: 60,
            alignItems: "center",
          }}
        >
          <div style={{ display: "flex", justifyContent: "center" }}>
            <AtlasFigure />
          </div>
          <div>
            <h1
              className="mono"
              style={{
                fontSize: 48,
                lineHeight: 1.08,
                letterSpacing: "-0.01em",
                margin: 0,
                textTransform: "uppercase",
                fontWeight: 500,
                color: "var(--text)",
              }}
            >
              Enforce policy.
              <br />
              Stay compliant.
              <br />
              Govern every
              <br />
              agent action.
              <br />
              <span style={{ color: "var(--amber)" }}>Prove it</span> to
              <br />
              anyone who asks.
            </h1>
            <div
              aria-hidden
              style={{
                height: 1,
                background:
                  "repeating-linear-gradient(90deg, var(--line-strong) 0 4px, transparent 4px 8px)",
                margin: "28px 0 20px",
              }}
            />
            <p
              className="mono"
              style={{
                fontSize: 13,
                lineHeight: 1.7,
                color: "var(--text-dim)",
                maxWidth: 460,
                margin: 0,
              }}
            >
              Aurek sits between your agent framework and every action your
              agents take. Every tool call, resource access, and inter-agent
              message is evaluated against policy before it executes. Developers
              ship it in an afternoon. Compliance teams get the audit trail they
              need before anyone asks for it.
            </p>
            <div
              className="mono"
              style={{
                marginTop: 28,
                display: "flex",
                gap: 14,
                alignItems: "center",
              }}
            >
              <a
                href="mailto:manasgarg02@gmail.com?subject=Aurek%20Early%20Access"
                style={{
                  padding: "12px 20px",
                  background: "var(--amber)",
                  color: "#111",
                  fontSize: 12,
                  letterSpacing: "0.14em",
                  textTransform: "uppercase",
                  fontWeight: 600,
                  borderRadius: 2,
                  boxShadow: "0 0 40px var(--amber-glow)",
                  transition: "transform .15s",
                }}
                onMouseEnter={(e) => (e.currentTarget.style.transform = "translateY(-1px)")}
                onMouseLeave={(e) => (e.currentTarget.style.transform = "translateY(0)")}
              >
                Request access →
              </a>

            </div>
            <div
              className="mono"
              style={{
                textAlign: "right",
                marginTop: 40,
                fontSize: 10,
                letterSpacing: "0.3em",
                color: "var(--text-faint)",
                textTransform: "uppercase",
              }}
            >
              aurek·protocol
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Hero, AtlasFigure, Crystallizer });
