import { useEffect, useRef, useState } from 'react';
import { Airport, AirportCategory } from '@lib/airport.types.ts';
import { useMapEvents } from 'react-leaflet';
import debounce from 'lodash.debounce';
import { getAirports } from '@lib/airport.ts';
import AirportMarker from '@components/AirportMarker.tsx';
import { LayerInfo } from '@/App.tsx';

const EXPANSION_FACTOR = 0.5;

export default function AirportLayer({
  setAirport,
  showNoMetar,
  selectedLayer
}: {
  setAirport: (airport: Airport) => void;
  showNoMetar: boolean;
  selectedLayer: LayerInfo;
}) {
  const [airports, setAirports] = useState<Airport[]>([]);
  const lastBoundsRef = useRef<{ ne: any; sw: any } | null>(null);

  const debouncedLoad = useRef(
    debounce(async (map: any) => {
      const b = map.getBounds();
      const north = b.getNorth(),
        south = b.getSouth();
      const east = b.getEast(),
        west = b.getWest();
      const latDelta = (north - south) * EXPANSION_FACTOR;
      const lonDelta = (east - west) * EXPANSION_FACTOR;

      // expanded bbox
      const ne = { lat: north + latDelta, lon: east + lonDelta };
      const sw = { lat: south - latDelta, lon: west - lonDelta };
      lastBoundsRef.current = { ne, sw };

      try {
        const resp = await getAirports({
          bounds: { northEast: ne, southWest: sw },
          metars: true,
          categories: [AirportCategory.HELIPORT, AirportCategory.SMALL, AirportCategory.MEDIUM, AirportCategory.LARGE]
        });
        setAirports(resp.data);
      } catch (err) {
        console.error('fetch error', err);
        setAirports([]);
      }
    }, 300)
  ).current;

  const map = useMapEvents({
    move: () => debouncedLoad(map)
  });

  useEffect(() => {
    if (map) debouncedLoad(map);
    return () => {
      debouncedLoad.cancel();
    };
  }, [map]);

  return (
    <>
      {airports.map((airport, index) => (
        <div key={index}>
          {(showNoMetar || airport.latest_metar != undefined) && (
            <AirportMarker airport={airport} index={index} setAirport={setAirport} selectedLayer={selectedLayer} />
          )}
        </div>
      ))}
    </>
  );
}
