
const { useRef, useEffect } = React;

const KENTUCKY = { lat: 37.8, lon: -85.7 };

const CITIES = [
  { lat: 40.7,  lon: -74.0,  delay: 2   },
  { lat: 19.4,  lon: -99.1,  delay: 3.5 },
  { lat: -23.5, lon: -46.6,  delay: 5   },
  { lat: -34.6, lon: -58.4,  delay: 5.8 },
  { lat: 4.7,   lon: -74.1,  delay: 6.5 },
  { lat: 51.5,  lon: -0.1,   delay: 8   },
  { lat: 48.9,  lon: 2.3,    delay: 8.5 },
  { lat: 52.5,  lon: 13.4,   delay: 9   },
  { lat: 41.0,  lon: 28.9,   delay: 9.5 },
  { lat: 55.7,  lon: 37.6,   delay: 10  },
  { lat: 30.1,  lon: 31.2,   delay: 11  },
  { lat: 6.5,   lon: 3.4,    delay: 12  },
  { lat: 28.6,  lon: 77.2,   delay: 13  },
  { lat: 39.9,  lon: 116.4,  delay: 14  },
  { lat: 35.7,  lon: 139.7,  delay: 14.5},
  { lat: -33.9, lon: 151.2,  delay: 16  },
];

// [lon, lat] pairs — simplified continent outlines
const CONTINENTS = [
  // North America
  [[-168,71],[-155,71],[-140,60],[-132,56],[-127,50],[-124,47],[-124,38],[-117,32],[-110,23],[-99,19],[-87,16],[-85,10],[-77,8],[-72,11],[-68,12],[-62,10],[-60,15],[-68,12],[-73,20],[-82,24],[-81,28],[-80,32],[-75,35],[-74,40],[-70,42],[-66,44],[-60,47],[-64,50],[-60,47],[-55,47],[-53,46],[-56,52],[-60,56],[-64,63],[-78,63],[-84,65],[-92,68],[-100,72],[-120,74],[-155,72],[-168,71]],
  // South America
  [[-78,11],[-75,11],[-68,12],[-62,11],[-50,2],[-36,-3],[-34,-8],[-35,-11],[-38,-14],[-38,-18],[-40,-21],[-44,-24],[-47,-27],[-50,-30],[-52,-33],[-53,-33],[-58,-34],[-62,-37],[-65,-42],[-65,-54],[-68,-55],[-70,-55],[-72,-50],[-72,-44],[-68,-25],[-70,-18],[-74,-10],[-76,-3],[-78,2],[-78,6],[-78,11]],
  // Europe
  [[-9,38],[-8,44],[-2,44],[2,44],[8,44],[12,44],[14,40],[20,38],[26,38],[28,41],[30,38],[36,36],[37,37],[36,37],[42,42],[45,43],[38,47],[30,46],[24,60],[22,65],[27,70],[30,70],[28,72],[14,70],[4,62],[-2,58],[-6,54],[-8,52],[-10,44],[-9,38]],
  // Africa
  [[-17,15],[-17,14],[-15,11],[-15,5],[-10,4],[-2,5],[4,5],[10,4],[14,4],[18,2],[24,0],[30,-3],[36,-2],[38,4],[42,12],[44,12],[44,8],[42,14],[40,20],[36,22],[36,30],[33,31],[25,31],[14,22],[2,20],[-8,16],[-17,15]],
  // Asia (West + Middle East + Russia)
  [[36,36],[42,42],[38,47],[30,46],[24,60],[28,70],[45,72],[60,73],[80,75],[100,74],[120,73],[140,72],[165,66],[170,62],[162,60],[155,60],[145,55],[140,50],[135,44],[132,42],[130,38],[128,36],[122,36],[120,28],[115,22],[110,18],[105,12],[103,1],[104,-2],[110,0],[115,4],[120,5],[128,4],[132,2],[134,8],[138,10],[140,34],[142,38],[144,44],[147,48],[150,50],[152,50],[145,55],[130,60],[120,60],[110,55],[100,52],[90,50],[80,44],[72,38],[62,36],[52,38],[45,43],[42,42],[36,36]],
  // South / SE Asia islands (Sumatra + Java shape)
  [[96,5],[104,-2],[108,-7],[112,-8],[116,-8],[120,-10],[124,-10],[125,-8],[120,-5],[115,-2],[110,1],[106,3],[102,4],[98,5],[96,5]],
  // Japan
  [[130,31],[130,34],[132,34],[136,36],[138,38],[140,40],[142,44],[144,44],[142,40],[140,38],[138,36],[136,34],[132,32],[130,31]],
  // Australia
  [[114,-22],[114,-26],[114,-32],[118,-35],[122,-34],[128,-34],[132,-35],[137,-35],[140,-38],[145,-38],[148,-38],[152,-28],[154,-25],[152,-24],[150,-22],[147,-20],[140,-18],[136,-14],[130,-14],[122,-18],[114,-22]],
  // New Zealand (simplified)
  [[168,-46],[170,-44],[172,-42],[174,-40],[176,-38],[176,-36],[174,-36],[172,-38],[170,-42],[168,-46]],
  // Greenland
  [[-45,76],[-28,70],[-25,65],[-28,60],[-40,60],[-50,65],[-55,68],[-58,74],[-55,77],[-48,78],[-45,76]],
  // Iceland
  [[-24,64],[-14,64],[-13,65],[-16,66],[-22,66],[-24,65],[-24,64]],
  // UK + Ireland simplified
  [[-6,53],[-2,50],[1,51],[1,53],[-2,56],[-4,58],[-5,58],[-6,55],[-6,53]],
  // Madagascar
  [[44,-12],[48,-14],[50,-17],[50,-23],[46,-25],[44,-22],[42,-18],[44,-12]],
];

function Globe({ size = 520, rotSpeed = 7 }) {
  const canvasRef = useRef(null);
  const animRef  = useRef(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    const W = canvas.width, H = canvas.height;
    const cx = W / 2, cy = H / 2;
    const R = Math.min(W, H) * 0.41;
    let startTime = null;

    function v3(lat, lon, rotDeg) {
      const phi   = (90 - lat) * Math.PI / 180;
      const theta = (lon + rotDeg) * Math.PI / 180;
      return {
        x: Math.sin(phi) * Math.cos(theta),
        y: -Math.cos(phi),
        z: Math.sin(phi) * Math.sin(theta),
      };
    }

    function proj(v) {
      return { px: cx + v.x * R, py: cy + v.y * R, vis: v.z > 0 };
    }

    function drawContinent(polygon, rot, stroke, lineW) {
      for (let i = 0; i < polygon.length - 1; i++) {
        const [lon1, lat1] = polygon[i];
        const [lon2, lat2] = polygon[i + 1];
        if (Math.abs(lon2 - lon1) > 90) continue;
        const v1 = v3(lat1, lon1, rot);
        const v2 = v3(lat2, lon2, rot);
        if (v1.z > 0 && v2.z > 0) {
          const p1 = proj(v1);
          const p2 = proj(v2);
          ctx.beginPath();
          ctx.moveTo(p1.px, p1.py);
          ctx.lineTo(p2.px, p2.py);
          ctx.strokeStyle = stroke;
          ctx.lineWidth   = lineW;
          ctx.stroke();
        }
      }
    }

    function fillContinent(polygon, rot) {
      let run = [];
      const flush = () => {
        if (run.length > 2) {
          ctx.beginPath();
          ctx.moveTo(run[0].px, run[0].py);
          for (let i = 1; i < run.length; i++) ctx.lineTo(run[i].px, run[i].py);
          ctx.closePath();
          ctx.fillStyle = 'rgba(30, 60, 10, 0.55)';
          ctx.fill();
        }
        run = [];
      };
      for (let i = 0; i < polygon.length; i++) {
        const [lon, lat] = polygon[i];
        const v = v3(lat, lon, rot);
        if (v.z > 0.02) {
          run.push(proj(v));
        } else {
          flush();
        }
      }
      flush();
    }

    function drawFrame(ts) {
      if (!startTime) startTime = ts;
      const t   = (ts - startTime) / 1000;
      const rot = t * rotSpeed;

      ctx.clearRect(0, 0, W, H);

      // Atmosphere glow
      const atm = ctx.createRadialGradient(cx, cy, R * 0.75, cx, cy, R * 1.45);
      atm.addColorStop(0, 'rgba(168,255,0,0)');
      atm.addColorStop(0.55, 'rgba(168,255,0,0.07)');
      atm.addColorStop(1, 'rgba(168,255,0,0)');
      ctx.fillStyle = atm;
      ctx.fillRect(0, 0, W, H);

      ctx.save();
      ctx.beginPath();
      ctx.arc(cx, cy, R - 0.5, 0, Math.PI * 2);
      ctx.clip();

      const bg = ctx.createRadialGradient(cx - R*0.2, cy - R*0.3, R*0.05, cx, cy, R);
      bg.addColorStop(0, '#1a2612');
      bg.addColorStop(0.6, '#0d0f0a');
      bg.addColorStop(1, '#040604');
      ctx.fillStyle = bg;
      ctx.fillRect(0, 0, W, H);

      const ocean = ctx.createRadialGradient(cx, cy, 0, cx, cy, R);
      ocean.addColorStop(0, 'rgba(0,20,40,0.18)');
      ocean.addColorStop(1, 'rgba(0,10,20,0.0)');
      ctx.fillStyle = ocean;
      ctx.fillRect(0, 0, W, H);

      CONTINENTS.forEach(c => fillContinent(c, rot));

      // Grid lines — lat
      for (let lat = -75; lat <= 75; lat += 15) {
        ctx.beginPath();
        let pen = false;
        for (let lon = -180; lon <= 182; lon += 2) {
          const p = proj(v3(lat, lon, rot));
          if (p.vis) { pen ? ctx.lineTo(p.px, p.py) : ctx.moveTo(p.px, p.py); pen = true; }
          else pen = false;
        }
        ctx.strokeStyle = `rgba(168,255,0,${lat === 0 ? 0.18 : 0.07})`;
        ctx.lineWidth   = lat === 0 ? 0.8 : 0.35;
        ctx.stroke();
      }

      // Grid lines — lon
      for (let lon = 0; lon < 360; lon += 15) {
        ctx.beginPath();
        let pen = false;
        for (let lat2 = -90; lat2 <= 92; lat2 += 2) {
          const p = proj(v3(lat2, lon, rot));
          if (p.vis) { pen ? ctx.lineTo(p.px, p.py) : ctx.moveTo(p.px, p.py); pen = true; }
          else pen = false;
        }
        ctx.strokeStyle = 'rgba(168,255,0,0.07)';
        ctx.lineWidth   = 0.35;
        ctx.stroke();
      }

      CONTINENTS.forEach(c => drawContinent(c, rot, 'rgba(168,255,0,0.7)', 1.1));

      const scanY = cy - R + ((t * 0.22) % 1) * R * 2;
      const sg = ctx.createLinearGradient(0, scanY - 35, 0, scanY + 35);
      sg.addColorStop(0, 'rgba(168,255,0,0)');
      sg.addColorStop(0.5, 'rgba(168,255,0,0.09)');
      sg.addColorStop(1, 'rgba(168,255,0,0)');
      ctx.fillStyle = sg;
      ctx.fillRect(cx - R, scanY - 35, R * 2, 70);

      ctx.restore();

      // Sphere rim
      ctx.beginPath();
      ctx.arc(cx, cy, R, 0, Math.PI * 2);
      const rim = ctx.createLinearGradient(cx - R, cy - R, cx + R, cy + R);
      rim.addColorStop(0, 'rgba(168,255,0,0.1)');
      rim.addColorStop(0.5, 'rgba(168,255,0,0.55)');
      rim.addColorStop(1, 'rgba(168,255,0,0.1)');
      ctx.strokeStyle = rim;
      ctx.lineWidth   = 1.8;
      ctx.stroke();

      // Kentucky origin pulse
      const kv = v3(KENTUCKY.lat, KENTUCKY.lon, rot);
      if (kv.z > 0) {
        const kp = proj(kv);
        const pt = (t * 1.6) % 1;
        for (let i = 0; i < 3; i++) {
          const pf = (pt + i / 3) % 1;
          ctx.beginPath();
          ctx.arc(kp.px, kp.py, pf * R * 0.17 + 2, 0, Math.PI * 2);
          ctx.strokeStyle = `rgba(255,80,20,${(1 - pf) * 0.75})`;
          ctx.lineWidth   = 1.5;
          ctx.stroke();
        }
        ctx.save();
        ctx.shadowColor = '#ff5010';
        ctx.shadowBlur  = 22;
        ctx.beginPath();
        ctx.arc(kp.px, kp.py, 4.5, 0, Math.PI * 2);
        ctx.fillStyle = '#ff6020';
        ctx.fill();
        ctx.restore();
      }

      // Infected cities
      CITIES.forEach((city, i) => {
        if (t < city.delay) return;
        const cv = v3(city.lat, city.lon, rot);
        if (cv.z < 0) return;
        const cp   = proj(cv);
        const fade = Math.min(1, (t - city.delay) * 2);
        const pulse = Math.sin(t * 2.5 + i * 1.3) * 0.3 + 0.7;

        ctx.save();
        ctx.shadowColor = '#a8ff00';
        ctx.shadowBlur  = 14;
        ctx.beginPath();
        ctx.arc(cp.px, cp.py, 3 * pulse, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(168,255,0,${fade * 0.9})`;
        ctx.fill();
        ctx.restore();
      });

      // HUD label
      ctx.fillStyle = 'rgba(168,255,0,0.22)';
      ctx.font = "9px 'Share Tech Mono', monospace";
      const label = 'ANÁLISE DE PROPAGAÇÃO // AO VIVO';
      ctx.fillText(label, cx - ctx.measureText(label).width / 2, cy - R - 10);

      animRef.current = requestAnimationFrame(drawFrame);
    }

    animRef.current = requestAnimationFrame(drawFrame);
    return () => cancelAnimationFrame(animRef.current);
  }, [rotSpeed]);

  return (
    <canvas
      ref={canvasRef}
      width={size}
      height={size}
      style={{ display: 'block', maxWidth: '100%', height: 'auto' }}
    />
  );
}

Object.assign(window, { Globe });
