import React, { useEffect, useRef } from 'react';

const API_BASE = import.meta.env.VITE_API_URL || (import.meta.env.DEV ? 'http://localhost:3000' : '');
const TWITCH_CHANNEL = 'winx_prinx';

export default function ChatterOrbit({ chatters }) {
  const canvasRef = useRef(null);
  const containerRef = useRef(null);
  const particlesRef = useRef(new Map());
  const avatarRef = useRef(null);

  useEffect(() => {
    // Load Avatar via backend proxy (avoids CORS issues with decapi.me)
    if (!avatarRef.current) {
      const img = new Image();
      img.src = `${API_BASE}/api/avatar/${TWITCH_CHANNEL}`;
      img.onload = () => { avatarRef.current = img; };
      img.onerror = () => console.warn('[ChatterOrbit] Avatar load failed');
    }
  }, []);

  useEffect(() => {
    const safeChatters = Array.isArray(chatters) ? chatters : [];
    
    safeChatters.forEach(c => {
      const username = c.username || c.display_name || 'unknown';
      if (!particlesRef.current.has(username)) {
        const isLurker = !c.has_chatted && !(c.message_count > 0);
        // All particles go on the ring — tight band around ring radius ±8%
        const ringNoise = (Math.random() - 0.5) * 0.16;
        const radiusNorm = 1.0 + ringNoise;
          
        particlesRef.current.set(username, {
          username,
          displayName: c.display_name || username,
          angle: Math.random() * Math.PI * 2,
          radiusNorm,
          speed: (0.0003 + Math.random() * 0.0004) * (Math.random() > 0.5 ? 1 : -1),
          isMod: c.is_mod,
          isSub: c.is_sub,
          isLurker,
          messageCount: c.message_count || 0,
          isStreamer: username.toLowerCase() === 'winx_prinx',
        });
      } else {
        const p = particlesRef.current.get(username);
        const isLurker = !c.has_chatted && !(c.message_count > 0);
        p.isLurker = isLurker;
        p.messageCount = c.message_count || p.messageCount;
        p.isMod = c.is_mod || p.isMod;
        p.isSub = c.is_sub || p.isSub;
      }
    });
  }, [chatters]);

  useEffect(() => {
    const canvas = canvasRef.current;
    const container = containerRef.current;
    if (!canvas || !container) return;
    const ctx = canvas.getContext('2d');
    let animationId;

    const HEIGHT = 320;

    const resize = () => {
      const dpr = window.devicePixelRatio || 1;
      const rect = container.getBoundingClientRect();
      canvas.width = rect.width * dpr;
      canvas.height = HEIGHT * dpr;
      canvas.style.width = `${rect.width}px`;
      canvas.style.height = `${HEIGHT}px`;
      ctx.scale(dpr, dpr);
    };
    resize();
    window.addEventListener('resize', resize);

    let hoverName = null;
    let hoverX = 0;
    let hoverY = 0;
    let mouseX = -9999;
    let mouseY = -9999;

    const handleMouseMove = (e) => {
      const rect = canvas.getBoundingClientRect();
      mouseX = e.clientX - rect.left;
      mouseY = e.clientY - rect.top;
    };
    const handleMouseLeave = () => { mouseX = -9999; mouseY = -9999; };
    canvas.addEventListener('mousemove', handleMouseMove);
    canvas.addEventListener('mouseleave', handleMouseLeave);

    const animate = () => {
      const width = canvas.width / (window.devicePixelRatio || 1);
      const height = HEIGHT;
      const cx = width / 2;
      const cy = height / 2;

      // Ring fills most of the canvas
      const RX = width * 0.44;
      const RY = height * 0.36;
      const TILT = RY / RX;

      // Solid near-black background
      ctx.fillStyle = '#08080f';
      ctx.fillRect(0, 0, width, height);

      const particles = Array.from(particlesRef.current.values());

      hoverName = null;

      // Update positions
      particles.forEach(p => {
        p.angle += p.speed;
        const r = p.radiusNorm * RX;
        p.x = cx + Math.cos(p.angle) * r;
        p.y = cy + Math.sin(p.angle) * r * TILT;
        p.depth = (Math.sin(p.angle) * TILT + TILT) / (2 * TILT); // 0=back, 1=front

        if (p.isStreamer) {
          p.baseSize = 5;
          p.color = '#A370F7';
        } else if (p.isLurker) {
          p.baseSize = 1;
          p.color = null;
        } else {
          p.baseSize = Math.min(4, 1.5 + Math.log10((p.messageCount || 0) + 1) * 1.2);
          p.color = p.isMod ? '#00F5D4' : p.isSub ? '#FF007F' : '#c8c8d8';
        }
        p.drawSize = p.baseSize;
      });

      // Sort back-to-front
      particles.sort((a, b) => a.depth - b.depth);

      // Draw particles
      particles.forEach(p => {
        const alpha = p.isLurker
          ? 0.15 + p.depth * 0.45
          : 0.5 + p.depth * 0.5;

        let color;
        if (p.isLurker) {
          const brightness = Math.round(160 + p.depth * 60);
          color = `rgba(${brightness},${brightness},${brightness + 20},${alpha})`;
        } else {
          color = p.color;
        }

        const dist = Math.hypot(mouseX - p.x, mouseY - p.y);
        if (dist < p.drawSize + 6) {
          hoverName = p.displayName;
          hoverX = p.x;
          hoverY = p.y;
          p.drawSize = Math.max(p.drawSize * 2.5, 5);
        }

        ctx.globalAlpha = p.isLurker ? 1 : alpha;
        ctx.shadowBlur = 0;

        if (!p.isLurker && (p.isMod || p.isSub || p.isStreamer)) {
          ctx.shadowBlur = 6;
          ctx.shadowColor = color;
        }

        ctx.beginPath();
        ctx.arc(p.x, p.y, p.drawSize, 0, Math.PI * 2);
        ctx.fillStyle = color;
        ctx.fill();
      });
      ctx.globalAlpha = 1;
      ctx.shadowBlur = 0;

      // Draw Avatar on top
      ctx.save();
      ctx.beginPath();
      ctx.arc(cx, cy, 26, 0, Math.PI * 2);
      ctx.closePath();
      ctx.shadowColor = '#9147ff';
      ctx.shadowBlur = 24;
      ctx.strokeStyle = 'rgba(145, 71, 255, 0.9)';
      ctx.lineWidth = 2.5;
      ctx.stroke();
      ctx.shadowBlur = 0;
      ctx.clip();
      if (avatarRef.current) {
        ctx.drawImage(avatarRef.current, cx - 26, cy - 26, 52, 52);
      } else {
        ctx.fillStyle = '#6441A5';
        ctx.fill();
      }
      ctx.restore();

      // Hover tooltip
      if (hoverName) {
        ctx.shadowBlur = 0;
        ctx.globalAlpha = 1;
        ctx.font = 'bold 11px Inter, sans-serif';
        const tw = ctx.measureText(hoverName).width;
        const tx = Math.min(hoverX + 12, width - tw - 20);
        const ty = hoverY - 30 < 5 ? hoverY + 20 : hoverY - 30;
        ctx.fillStyle = 'rgba(18,18,24,0.92)';
        ctx.beginPath();
        if (ctx.roundRect) ctx.roundRect(tx - 4, ty, tw + 16, 22, 5);
        else ctx.rect(tx - 4, ty, tw + 16, 22);
        ctx.fill();
        ctx.strokeStyle = 'rgba(145,71,255,0.5)';
        ctx.lineWidth = 1;
        ctx.stroke();
        ctx.fillStyle = '#efeff1';
        ctx.fillText(hoverName, tx + 4, ty + 15);
      }

      animationId = requestAnimationFrame(animate);
    };

    animate();

    return () => {
      cancelAnimationFrame(animationId);
      canvas.removeEventListener('mousemove', handleMouseMove);
      canvas.removeEventListener('mouseleave', handleMouseLeave);
      window.removeEventListener('resize', resize);
    };
  }, []);

  return (
    <div ref={containerRef} style={{ display: 'flex', flexDirection: 'column', width: '100%', position: 'relative' }}>
      <canvas ref={canvasRef} style={{ borderRadius: '8px', display: 'block', width: '100%' }} />
      <div style={{ position: 'absolute', bottom: '10px', right: '12px', fontSize: '11px', color: 'rgba(180,180,200,0.7)', display: 'flex', gap: '14px' }}>
        <span><span style={{ display: 'inline-block', width: '6px', height: '6px', background: 'rgba(200,200,220,0.5)', borderRadius: '50%', marginRight: '4px'}}></span>Зрители</span>
        <span><span style={{ display: 'inline-block', width: '6px', height: '6px', background: '#c8c8d8', borderRadius: '50%', marginRight: '4px'}}></span>Чатеры</span>
        <span><span style={{ display: 'inline-block', width: '6px', height: '6px', background: '#FF007F', borderRadius: '50%', marginRight: '4px'}}></span>Сабы</span>
        <span><span style={{ display: 'inline-block', width: '6px', height: '6px', background: '#00F5D4', borderRadius: '50%', marginRight: '4px'}}></span>Модеры</span>
      </div>
    </div>
  );
}
