import React, { useRef, useState, useCallback, useEffect } from 'react';
import { useMapTransform } from '../../contexts/MapTransformContext';
import { pxToWorld, formatCoord } from '../../utils/coordinates';
import { PlayerDots } from './PlayerDots';
import type { TelemetrySnapshot } from '../../types';

interface Props {
  players: TelemetrySnapshot[];
  getColor: (name: string) => string;
  onSelectPlayer: (name: string) => void;
}

export const MapView: React.FC<Props> = ({ players, getColor, onSelectPlayer }) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const { transform, dispatch } = useMapTransform();
  const [imgSize, setImgSize] = useState({ w: 0, h: 0 });
  const [tooltip, setTooltip] = useState<{ x: number; y: number; player: TelemetrySnapshot } | null>(null);
  const [worldCoord, setWorldCoord] = useState<{ ns: number; ew: number } | null>(null);
  const dragRef = useRef<{ dragging: boolean; sx: number; sy: number; startOffX: number; startOffY: number }>({
    dragging: false, sx: 0, sy: 0, startOffX: 0, startOffY: 0,
  });

  const onImgLoad = useCallback((e: React.SyntheticEvent<HTMLImageElement>) => {
    const img = e.currentTarget;
    setImgSize({ w: img.naturalWidth, h: img.naturalHeight });
    // Fit map to container on first load
    if (containerRef.current) {
      const cw = containerRef.current.clientWidth;
      const ch = containerRef.current.clientHeight;
      const scale = Math.min(cw / img.naturalWidth, ch / img.naturalHeight);
      dispatch({ type: 'SET', scale, offX: (cw - img.naturalWidth * scale) / 2, offY: (ch - img.naturalHeight * scale) / 2 });
    }
  }, [dispatch]);

  // Wheel zoom
  const onWheel = useCallback((e: React.WheelEvent) => {
    e.preventDefault();
    const rect = containerRef.current?.getBoundingClientRect();
    if (!rect) return;
    const factor = e.deltaY < 0 ? 1.1 : 0.9;
    dispatch({ type: 'ZOOM', factor, cx: e.clientX - rect.left, cy: e.clientY - rect.top });
  }, [dispatch]);

  // Pan drag
  const onMouseDown = useCallback((e: React.MouseEvent) => {
    if (e.button !== 0) return;
    dragRef.current = { dragging: true, sx: e.clientX, sy: e.clientY, startOffX: transform.offX, startOffY: transform.offY };
  }, [transform.offX, transform.offY]);

  useEffect(() => {
    const onMouseMove = (e: MouseEvent) => {
      const d = dragRef.current;
      if (d.dragging) {
        dispatch({ type: 'SET', scale: transform.scale, offX: d.startOffX + (e.clientX - d.sx), offY: d.startOffY + (e.clientY - d.sy) });
      }
      // World coordinate display
      if (containerRef.current && imgSize.w > 0) {
        const rect = containerRef.current.getBoundingClientRect();
        const coord = pxToWorld(e.clientX - rect.left, e.clientY - rect.top, transform.scale, transform.offX, transform.offY, imgSize.w, imgSize.h);
        setWorldCoord(coord);
      }
    };
    const onMouseUp = () => { dragRef.current.dragging = false; };
    window.addEventListener('mousemove', onMouseMove);
    window.addEventListener('mouseup', onMouseUp);
    return () => { window.removeEventListener('mousemove', onMouseMove); window.removeEventListener('mouseup', onMouseUp); };
  }, [dispatch, transform.scale, transform.offX, transform.offY, imgSize.w, imgSize.h]);

  const handleDotHover = useCallback((player: TelemetrySnapshot | null, x: number, y: number) => {
    setTooltip(player ? { x, y, player } : null);
  }, []);

  return (
    <div className="ml-map-container" ref={containerRef} onWheel={onWheel} onMouseDown={onMouseDown}>
      <div
        className="ml-map-group"
        style={{ transform: `translate(${transform.offX}px, ${transform.offY}px) scale(${transform.scale})` }}
      >
        <img src="/dereth.png" alt="Dereth" className="ml-map-img" onLoad={onImgLoad} draggable={false} />
        {imgSize.w > 0 && (
          <PlayerDots
            players={players}
            imgW={imgSize.w}
            imgH={imgSize.h}
            getColor={getColor}
            onHover={handleDotHover}
            onSelect={onSelectPlayer}
          />
        )}
      </div>

      {/* Tooltip */}
      {tooltip && (
        <div className="ml-tooltip" style={{ left: tooltip.x + 12, top: tooltip.y - 10 }}>
          <strong>{tooltip.player.character_name}</strong>
          <br />
          {formatCoord(tooltip.player.ns, tooltip.player.ew)}
          <br />
          {tooltip.player.kills_per_hour} kph &middot; {tooltip.player.kills?.toLocaleString()} kills
        </div>
      )}

      {/* Coordinate display */}
      {worldCoord && (
        <div className="ml-coords">
          {formatCoord(worldCoord.ns, worldCoord.ew)}
        </div>
      )}
    </div>
  );
};
