/* Connie's energy orb — multi-layered, audio-reactive */
const { useEffect, useRef, useState } = React;

function Orb({ state }) {
  // state: 'ready' | 'listening' | 'thinking' | 'speaking'
  const canvasRef = useRef(null);
  const rafRef = useRef(null);

  // Audio-reactive waveform driven by procedural amplitude
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    const dpr = window.devicePixelRatio || 1;

    function resize() {
      const rect = canvas.getBoundingClientRect();
      canvas.width = rect.width * dpr;
      canvas.height = rect.height * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(canvas);

    let t = 0;
    let particles = Array.from({ length: 30 }, (_, i) => ({
      angle: (i / 30) * Math.PI * 2,
      radius: 90 + Math.random() * 20,
      speed: 0.0006 + Math.random() * 0.0008,
      size: 0.6 + Math.random() * 1.4,
      hue: Math.random() < 0.5 ? "lime" : "teal",
      phase: Math.random() * Math.PI * 2,
    }));

    function draw(now) {
      t = now;
      const w = canvas.width / dpr;
      const h = canvas.height / dpr;
      ctx.clearRect(0, 0, w, h);
      const cx = w / 2;
      const cy = h / 2;
      const baseR = Math.min(w, h) * 0.18;

      // State-driven intensity
      let intensity = 0.4;
      if (state === "listening") intensity = 0.7;
      else if (state === "thinking") intensity = 0.55;
      else if (state === "speaking") intensity = 1.0;

      // ---- Outer ripples (listening) ----
      if (state === "listening") {
        for (let i = 0; i < 3; i++) {
          const phase = ((t / 1400) + i / 3) % 1;
          const r = baseR + phase * baseR * 2.4;
          const alpha = (1 - phase) * 0.5;
          ctx.beginPath();
          ctx.arc(cx, cy, r, 0, Math.PI * 2);
          ctx.strokeStyle = `rgba(225,245,40,${alpha * 0.8})`;
          ctx.lineWidth = 1.5;
          ctx.stroke();
        }
      }

      // ---- Particles ----
      const particleBoost = state === "thinking" ? 1.6 : state === "speaking" ? 1.3 : 1;
      particles.forEach((p) => {
        const a = p.angle + t * p.speed * particleBoost;
        const rWobble = Math.sin(t * 0.001 + p.phase) * 6;
        const r = p.radius + rWobble + baseR * 0.15;
        const x = cx + Math.cos(a) * r;
        const y = cy + Math.sin(a) * r;
        const flicker = 0.6 + Math.sin(t * 0.003 + p.phase) * 0.4;
        ctx.beginPath();
        ctx.arc(x, y, p.size * (1 + intensity * 0.4), 0, Math.PI * 2);
        const c = p.hue === "lime"
          ? `rgba(225,245,40,${0.6 * flicker})`
          : `rgba(5,230,165,${0.6 * flicker})`;
        ctx.fillStyle = c;
        ctx.shadowColor = c;
        ctx.shadowBlur = 6;
        ctx.fill();
      });
      ctx.shadowBlur = 0;

      // ---- Speaking waveform around orb ----
      if (state === "speaking") {
        ctx.save();
        ctx.translate(cx, cy);
        const points = 96;
        ctx.beginPath();
        for (let i = 0; i <= points; i++) {
          const ang = (i / points) * Math.PI * 2;
          const wob =
            Math.sin(t * 0.006 + i * 0.4) * 6 +
            Math.sin(t * 0.011 + i * 0.7) * 4 +
            Math.sin(t * 0.018 + i * 1.3) * 3;
          const r = baseR * 1.55 + wob;
          const x = Math.cos(ang) * r;
          const y = Math.sin(ang) * r;
          if (i === 0) ctx.moveTo(x, y);
          else ctx.lineTo(x, y);
        }
        ctx.closePath();
        const grad = ctx.createLinearGradient(-baseR, -baseR, baseR, baseR);
        grad.addColorStop(0, "rgba(225,245,40,0.85)");
        grad.addColorStop(1, "rgba(5,230,165,0.85)");
        ctx.strokeStyle = grad;
        ctx.lineWidth = 1.4;
        ctx.stroke();
        ctx.restore();
      }

      rafRef.current = requestAnimationFrame(draw);
    }

    const reduced = matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (!reduced) rafRef.current = requestAnimationFrame(draw);
    else draw(0);

    return () => {
      cancelAnimationFrame(rafRef.current);
      ro.disconnect();
    };
  }, [state]);

  return (
    <div className={`orb orb--${state}`} aria-hidden="true">
      {/* Outer aura */}
      <div className="orb__aura" />

      {/* Canvas for particles + ripples + waveform */}
      <canvas ref={canvasRef} className="orb__canvas" />

      {/* Rotating conic rings */}
      <div className="orb__ring orb__ring--1" />
      <div className="orb__ring orb__ring--2" />
      <div className="orb__ring orb__ring--3" />

      {/* Core */}
      <div className="orb__core">
        <div className="orb__core-inner" />
        <div className="orb__core-flare" />
      </div>

      <style>{`
        .orb {
          position: relative;
          width: 100%;
          height: 100%;
          display: grid;
          place-items: center;
        }
        .orb__aura {
          position: absolute;
          inset: -20%;
          background: radial-gradient(50% 50% at 50% 50%,
            rgba(225,245,40,0.30) 0%,
            rgba(5,230,165,0.20) 40%,
            transparent 75%);
          filter: blur(20px);
          opacity: 0.9;
          animation: aura-breathe 5s var(--ease) infinite;
          pointer-events: none;
        }
        .orb--listening .orb__aura { opacity: 1; animation-duration: 1.4s; }
        .orb--thinking .orb__aura  { opacity: 0.95; animation-duration: 3s; }
        .orb--speaking .orb__aura  { opacity: 1; animation-duration: 0.9s; }

        .orb__canvas {
          position: absolute;
          inset: 0;
          width: 100%; height: 100%;
        }

        .orb__ring {
          position: absolute;
          border-radius: 50%;
          mix-blend-mode: screen;
          pointer-events: none;
        }
        .orb__ring--1 {
          width: 78%; height: 78%;
          background: conic-gradient(from 0deg,
            rgba(225,245,40,0) 0%,
            rgba(225,245,40,0.55) 25%,
            rgba(5,230,165,0.55) 50%,
            rgba(5,230,165,0) 75%,
            rgba(225,245,40,0) 100%);
          mask: radial-gradient(circle, transparent 56%, #000 58%, #000 64%, transparent 66%);
          -webkit-mask: radial-gradient(circle, transparent 56%, #000 58%, #000 64%, transparent 66%);
          animation: spin-cw 8s linear infinite;
          opacity: 0.85;
        }
        .orb__ring--2 {
          width: 92%; height: 92%;
          background: conic-gradient(from 180deg,
            rgba(5,230,165,0) 0%,
            rgba(5,230,165,0.4) 30%,
            rgba(225,245,40,0.4) 60%,
            rgba(225,245,40,0) 90%);
          mask: radial-gradient(circle, transparent 64%, #000 66%, #000 70%, transparent 72%);
          -webkit-mask: radial-gradient(circle, transparent 64%, #000 66%, #000 70%, transparent 72%);
          animation: spin-ccw 14s linear infinite;
          opacity: 0.7;
        }
        .orb__ring--3 {
          width: 100%; height: 100%;
          background: conic-gradient(from 45deg,
            rgba(255,255,255,0) 0%,
            rgba(225,245,40,0.18) 20%,
            rgba(5,230,165,0.22) 50%,
            rgba(255,255,255,0) 70%);
          mask: radial-gradient(circle, transparent 76%, #000 78%, #000 80%, transparent 82%);
          -webkit-mask: radial-gradient(circle, transparent 76%, #000 78%, #000 80%, transparent 82%);
          animation: spin-cw 22s linear infinite;
          opacity: 0.6;
        }

        .orb--thinking .orb__ring--1 { animation-duration: 3.2s; }
        .orb--thinking .orb__ring--2 { animation-duration: 5s; }
        .orb--speaking .orb__ring--1 { animation-duration: 5s; }
        .orb--listening .orb__ring--1 { animation-duration: 6s; }

        .orb__core {
          position: relative;
          width: 36%; height: 36%;
          border-radius: 50%;
          background: radial-gradient(circle at 35% 32%,
            rgba(255,255,255,0.95) 0%,
            rgba(225,245,40,0.85) 18%,
            rgba(5,230,165,0.7) 55%,
            rgba(5,230,165,0.2) 85%,
            transparent 100%);
          box-shadow:
            0 0 40px rgba(5,230,165,0.6),
            0 0 80px rgba(225,245,40,0.35),
            inset 0 0 30px rgba(255,255,255,0.4);
          animation: core-breathe 4s var(--ease) infinite;
          filter: blur(0.3px);
        }
        .orb--listening .orb__core { animation-duration: 1.2s; }
        .orb--thinking .orb__core  { animation-duration: 2.6s; }
        .orb--speaking .orb__core  { animation-duration: 0.6s; }

        .orb__core-inner {
          position: absolute; inset: 18%;
          border-radius: 50%;
          background: radial-gradient(circle at 40% 40%,
            #ffffff 0%,
            rgba(225,245,40,0.9) 35%,
            rgba(5,230,165,0.8) 70%,
            transparent 100%);
          filter: blur(2px);
          opacity: 0.9;
          animation: core-breathe 3s var(--ease) infinite reverse;
        }
        .orb__core-flare {
          position: absolute; top: 15%; left: 20%;
          width: 28%; height: 18%;
          border-radius: 50%;
          background: radial-gradient(ellipse, rgba(255,255,255,0.7) 0%, transparent 70%);
          filter: blur(3px);
        }

        @keyframes spin-cw  { to { transform: rotate(360deg); } }
        @keyframes spin-ccw { to { transform: rotate(-360deg); } }
        @keyframes aura-breathe {
          0%, 100% { transform: scale(1); opacity: 0.85; }
          50% { transform: scale(1.08); opacity: 1; }
        }
        @keyframes core-breathe {
          0%, 100% { transform: scale(1); }
          50%      { transform: scale(1.06); }
        }

        @media (prefers-reduced-motion: reduce) {
          .orb__ring, .orb__aura, .orb__core, .orb__core-inner { animation: none !important; }
        }
      `}</style>
    </div>
  );
}

window.Orb = Orb;
