import { useEffect, useRef } from "react";
import { useTheme } from "@/contexts/ThemeContext";

/*
  FloatingStudyHero — Canvas-powered animated study-themed visual
  Features: glowing orbs, floating knowledge nodes (code, math, AI topics),
  animated connecting lines like a neural/knowledge graph.
*/

const TOPICS = [
  { label: "Python", color: "#3b82f6" },
  { label: "ML", color: "#8b5cf6" },
  { label: "NLP", color: "#ec4899" },
  { label: "∑ Math", color: "#f59e0b" },
  { label: "AI", color: "#10b981" },
  { label: "</>Code", color: "#06b6d4" },
  { label: "Neural", color: "#f43f5e" },
  { label: "Data", color: "#a855f7" },
  { label: "GPT", color: "#22c55e" },
];

interface Node {
  x: number;
  y: number;
  vx: number;
  vy: number;
  label: string;
  color: string;
  radius: number;
  phase: number;
}

export const FloatingStudyHero = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const { isDark } = useTheme();

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    let raf: number;
    let t = 0;

    // Build nodes
    const nodes: Node[] = TOPICS.map((topic, i) => ({
      x: (canvas.width / (TOPICS.length + 1)) * (i + 1) + (Math.random() - 0.5) * 80,
      y: canvas.height / 2 + (Math.random() - 0.5) * canvas.height * 0.6,
      vx: (Math.random() - 0.5) * 0.4,
      vy: (Math.random() - 0.5) * 0.4,
      label: topic.label,
      color: topic.color,
      radius: 32 + Math.random() * 12,
      phase: Math.random() * Math.PI * 2,
    }));

    const resize = () => {
      canvas.width = canvas.offsetWidth;
      canvas.height = canvas.offsetHeight;
      // Reposition nodes on resize
      nodes.forEach((n, i) => {
        n.x = (canvas.width / (nodes.length + 1)) * (i + 1);
        n.y = canvas.height / 2 + (Math.random() - 0.5) * canvas.height * 0.5;
      });
    };
    resize();
    window.addEventListener("resize", resize);

    const drawGlowCircle = (x: number, y: number, r: number, color: string, alpha: number) => {
      const grad = ctx.createRadialGradient(x, y, 0, x, y, r * 2.5);
      grad.addColorStop(0, color + "cc");
      grad.addColorStop(0.4, color + "55");
      grad.addColorStop(1, color + "00");
      ctx.beginPath();
      ctx.arc(x, y, r * 2.5, 0, Math.PI * 2);
      ctx.fillStyle = grad;
      ctx.globalAlpha = alpha;
      ctx.fill();
      ctx.globalAlpha = 1;
    };

    const drawNode = (node: Node, t: number) => {
      const bob = Math.sin(t * 0.8 + node.phase) * 6;
      const x = node.x;
      const y = node.y + bob;
      const r = node.radius;

      // Outer glow
      drawGlowCircle(x, y, r, node.color, 0.7);

      // Inner circle with gradient
      const grad = ctx.createRadialGradient(x - r * 0.3, y - r * 0.3, r * 0.1, x, y, r);
      grad.addColorStop(0, node.color + "ff");
      grad.addColorStop(0.6, node.color + "cc");
      grad.addColorStop(1, node.color + "88");

      ctx.beginPath();
      ctx.arc(x, y, r, 0, Math.PI * 2);
      ctx.fillStyle = grad;
      ctx.shadowColor = node.color;
      ctx.shadowBlur = 20;
      ctx.fill();
      ctx.shadowBlur = 0;

      // Border ring
      ctx.beginPath();
      ctx.arc(x, y, r, 0, Math.PI * 2);
      ctx.strokeStyle = node.color + "ff";
      ctx.lineWidth = 2;
      ctx.stroke();

      // Label
      ctx.font = `bold ${Math.floor(r * 0.38)}px 'Inter', sans-serif`;
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.fillStyle = "#ffffff";
      ctx.shadowColor = "#00000099";
      ctx.shadowBlur = 6;
      ctx.fillText(node.label, x, y);
      ctx.shadowBlur = 0;
    };

    const drawEdge = (a: Node, b: Node, t: number) => {
      const dx = b.x - a.x;
      const dy = b.y - a.y;
      const dist = Math.sqrt(dx * dx + dy * dy);
      if (dist > 240) return;

      const alpha = (1 - dist / 240) * 0.4;
      const grad = ctx.createLinearGradient(a.x, a.y, b.x, b.y);
      grad.addColorStop(0, a.color + Math.round(alpha * 255).toString(16).padStart(2, "0"));
      grad.addColorStop(1, b.color + Math.round(alpha * 255).toString(16).padStart(2, "0"));

      ctx.beginPath();
      ctx.moveTo(a.x, a.y);
      ctx.lineTo(b.x, b.y);
      ctx.strokeStyle = grad;
      ctx.lineWidth = 1.5;
      ctx.setLineDash([6, 8]);
      ctx.lineDashOffset = -t * 15;
      ctx.stroke();
      ctx.setLineDash([]);
    };

    // Interaction state
    const mouse = { x: -1000, y: -1000, active: false };
    let draggedNode: Node | null = null;

    const handleMouseMove = (e: MouseEvent) => {
      const rect = canvas.getBoundingClientRect();
      mouse.x = e.clientX - rect.left;
      mouse.y = e.clientY - rect.top;
      mouse.active = true;
    };

    const handleMouseDown = () => {
      // Find node under mouse
      for (const node of nodes) {
        const dx = node.x - mouse.x;
        const dy = node.y - mouse.y;
        if (Math.sqrt(dx * dx + dy * dy) < node.radius * 1.5) {
          draggedNode = node;
          break;
        }
      }
    };

    const handleMouseUp = () => {
      draggedNode = null;
    };

    const handleMouseLeave = () => {
      mouse.active = false;
    };

    canvas.addEventListener("mousemove", handleMouseMove);
    canvas.addEventListener("mousedown", handleMouseDown);
    window.addEventListener("mouseup", handleMouseUp);
    canvas.addEventListener("mouseleave", handleMouseLeave);

    const tick = () => {
      t += 0.016;
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Background ambient blobs
      [[canvas.width * 0.2, canvas.height * 0.3, "#6366f1"], [canvas.width * 0.8, canvas.height * 0.7, "#10b981"], [canvas.width * 0.5, canvas.height * 0.5, "#ec4899"]].forEach(([bx, by, bc]) => {
        drawGlowCircle(bx as number, by as number, 80, bc as string, 0.15);
      });

      // Physics: move nodes
      nodes.forEach((n) => {
        if (n === draggedNode) {
          n.x = mouse.x;
          n.y = mouse.y;
          n.vx = 0;
          n.vy = 0;
        } else {
          // Magnetic attraction to mouse
          if (mouse.active) {
            const dx = mouse.x - n.x;
            const dy = mouse.y - n.y;
            const dist = Math.sqrt(dx * dx + dy * dy);
            if (dist < 400) {
              const force = (1 - dist / 400) * 0.02;
              n.vx += dx * force;
              n.vy += dy * force;
            }
          }

          n.x += n.vx;
          n.y += n.vy;
          
          // Damping to keep things stable
          n.vx *= 0.98;
          n.vy *= 0.98;

          if (n.x < n.radius) { n.x = n.radius; n.vx *= -1; }
          if (n.x > canvas.width - n.radius) { n.x = canvas.width - n.radius; n.vx *= -1; }
          if (n.y < n.radius) { n.y = n.radius; n.vy *= -1; }
          if (n.y > canvas.height - n.radius) { n.y = canvas.height - n.radius; n.vy *= -1; }
        }
      });

      // Draw edges
      for (let i = 0; i < nodes.length; i++) {
        for (let j = i + 1; j < nodes.length; j++) {
          drawEdge(nodes[i], nodes[j], t);
        }
      }

      // Draw nodes on top
      nodes.forEach((n) => drawNode(n, t));

      raf = requestAnimationFrame(tick);
    };

    tick();

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("resize", resize);
      canvas.removeEventListener("mousemove", handleMouseMove);
      canvas.removeEventListener("mousedown", handleMouseDown);
      window.removeEventListener("mouseup", handleMouseUp);
      canvas.removeEventListener("mouseleave", handleMouseLeave);
    };
  }, [isDark]);

  return (
    <div className="w-full h-full relative">
      <canvas
        ref={canvasRef}
        className="w-full h-full"
        style={{ display: "block" }}
      />
    </div>
  );
};
