"use client";

import { useEffect, useRef, useState, useCallback, useMemo } from "react";
import dynamic from "next/dynamic";
import { useHeatmapData, type HeatmapPoint } from "@/hooks/use-heatmap-data";
import { GlobeControls } from "./globe-controls";

const Globe = dynamic(() => import("react-globe.gl"), {
  ssr: false,
  loading: () => (
    <div className="flex h-full items-center justify-center">
      <div className="flex flex-col items-center gap-3">
        <div className="h-8 w-8 animate-spin rounded-full border-2 border-[var(--accent-cyan)] border-t-transparent" />
        <span className="font-mono text-xs text-[var(--text-muted)]">Loading globe...</span>
      </div>
    </div>
  ),
});

interface ArcData {
  startLat: number;
  startLng: number;
  endLat: number;
  endLng: number;
  color: string;
}

export function GlobeView() {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const globeRef = useRef<any>(undefined);
  const containerRef = useRef<HTMLDivElement>(null);
  const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
  const [hoveredPoint, setHoveredPoint] = useState<HeatmapPoint | null>(null);
  const { points } = useHeatmapData(30000);

  // Generate arcs from recent activity (connecting pairs of active points)
  const arcs = useMemo((): ArcData[] => {
    if (points.length < 2) return [];
    const result: ArcData[] = [];
    const maxArcs = Math.min(points.length - 1, 8);
    for (let i = 0; i < maxArcs; i++) {
      const from = points[i];
      const to = points[(i + 1) % points.length];
      result.push({
        startLat: from.lat,
        startLng: from.lng,
        endLat: to.lat,
        endLng: to.lng,
        color: "rgba(0, 240, 255, 0.4)",
      });
    }
    return result;
  }, [points]);

  useEffect(() => {
    const updateDimensions = () => {
      if (containerRef.current) {
        setDimensions({
          width: containerRef.current.clientWidth,
          height: containerRef.current.clientHeight,
        });
      }
    };

    updateDimensions();
    const observer = new ResizeObserver(updateDimensions);
    if (containerRef.current) observer.observe(containerRef.current);
    return () => observer.disconnect();
  }, []);

  useEffect(() => {
    if (globeRef.current) {
      globeRef.current.pointOfView({ lat: 20, lng: 100, altitude: 2.5 });
    }
  }, [dimensions]);

  const handleResetView = useCallback(() => {
    if (globeRef.current) {
      globeRef.current.pointOfView({ lat: 20, lng: 100, altitude: 2.5 });
    }
  }, []);

  const handleZoomIn = useCallback(() => {
    if (globeRef.current) {
      globeRef.current.pointOfView({ lat: 20, lng: 100, altitude: 1.5 });
    }
  }, []);

  const handleZoomOut = useCallback(() => {
    if (globeRef.current) {
      globeRef.current.pointOfView({ lat: 20, lng: 100, altitude: 3.5 });
    }
  }, []);

  return (
    <div ref={containerRef} className="relative h-full w-full overflow-hidden rounded-xl border border-white/5">
      {dimensions.width > 0 && (
        <Globe
          ref={globeRef}
          width={dimensions.width}
          height={dimensions.height}
          backgroundColor="rgba(0,0,0,0)"
          globeImageUrl="//unpkg.com/three-globe/example/img/earth-dark.jpg"
          atmosphereColor="#00f0ff"
          atmosphereAltitude={0.15}
          // Points
          pointsData={points}
          pointLat={(d: object) => (d as HeatmapPoint).lat}
          pointLng={(d: object) => (d as HeatmapPoint).lng}
          pointAltitude={(d: object) => Math.min((d as HeatmapPoint).weight * 0.02, 0.15)}
          pointRadius={(d: object) => Math.max((d as HeatmapPoint).weight * 0.3, 0.4)}
          pointColor={() => "#00f0ff"}
          pointsMerge={false}
          onPointHover={(point: object | null) => setHoveredPoint(point as HeatmapPoint | null)}
          // Arcs
          arcsData={arcs}
          arcStartLat={(d: object) => (d as ArcData).startLat}
          arcStartLng={(d: object) => (d as ArcData).startLng}
          arcEndLat={(d: object) => (d as ArcData).endLat}
          arcEndLng={(d: object) => (d as ArcData).endLng}
          arcColor={(d: object) => (d as ArcData).color}
          arcDashLength={0.5}
          arcDashGap={0.2}
          arcDashAnimateTime={2000}
          arcStroke={0.3}
          // Auto-rotate
          animateIn={true}
          enablePointerInteraction={true}
        />
      )}

      {/* Tooltip */}
      {hoveredPoint && (
        <div className="pointer-events-none absolute left-1/2 top-4 z-20 -translate-x-1/2">
          <div className="rounded-xl border border-white/10 bg-[var(--bg-card)]/95 p-3 shadow-xl backdrop-blur-sm">
            <div className="flex items-center gap-2">
              <span className="text-lg">🦞</span>
              <div>
                <p className="font-mono text-sm font-medium text-[var(--accent-cyan)]">
                  {hoveredPoint.city}
                </p>
                <p className="text-xs text-[var(--text-muted)]">{hoveredPoint.country}</p>
              </div>
            </div>
            <p className="mt-1 text-xs text-[var(--text-secondary)]">
              {hoveredPoint.lobsterCount} active lobster{hoveredPoint.lobsterCount !== 1 ? "s" : ""}
            </p>
          </div>
        </div>
      )}

      <GlobeControls
        onResetView={handleResetView}
        onZoomIn={handleZoomIn}
        onZoomOut={handleZoomOut}
      />
    </div>
  );
}
