import { useState, useEffect } from 'react';
import { useMap } from 'react-leaflet';
import L from 'leaflet';

interface ElevationState {
  elevation: number | null;
  position: { lat: number; lon: number } | null;
  loading: boolean;
}

export function useElevation() {
  const map = useMap();
  const [state, setState] = useState<ElevationState>({
    elevation: null,
    position: null,
    loading: false,
  });

  useEffect(() => {
    let timeoutId: number;
    let abortController: AbortController | null = null;

    const handleMouseMove = (e: L.LeafletMouseEvent) => {
      setState((prev) => ({
        ...prev,
        position: { lat: e.latlng.lat, lon: e.latlng.lng },
      }));

      // Debounce API calls (300ms)
      clearTimeout(timeoutId);
      if (abortController) abortController.abort();

      timeoutId = window.setTimeout(async () => {
        setState((prev) => ({ ...prev, loading: true }));
        abortController = new AbortController();

        try {
          const response = await fetch(
            `https://api.open-elevation.com/api/v1/lookup?locations=${e.latlng.lat},${e.latlng.lng}`,
            { signal: abortController.signal }
          );
          const data = await response.json();
          const elev = data?.results?.[0]?.elevation ?? null;
          setState((prev) => ({ ...prev, elevation: elev, loading: false }));
        } catch (error: unknown) {
          if (error instanceof DOMException && error.name === 'AbortError') {
            // Intentional abort, ignore
            return;
          }
          console.error('Elevation fetch failed:', error);
          setState((prev) => ({ ...prev, elevation: null, loading: false }));
        }
      }, 300);
    };

    const handleMouseOut = () => {
      clearTimeout(timeoutId);
      if (abortController) abortController.abort();
      setState({ elevation: null, position: null, loading: false });
    };

    map.on('mousemove', handleMouseMove);
    map.on('mouseout', handleMouseOut);

    return () => {
      map.off('mousemove', handleMouseMove);
      map.off('mouseout', handleMouseOut);
      clearTimeout(timeoutId);
      if (abortController) abortController.abort();
    };
  }, [map]);

  return state;
}
