import { useState, useEffect, useRef } from 'react';
import type { Bounds, POI, POIResponse } from '../types';
import { apiUrl, logNonAbortError, authHeaders } from '../lib/api';

const DEBOUNCE_MS = 150;

export function usePOIData(bounds: Bounds | null, selectedCategories: Set<string>) {
  const [pois, setPois] = useState<POI[]>([]);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const abortControllerRef = useRef<AbortController | null>(null);
  const requestIdRef = useRef(0);

  useEffect(() => {
    requestIdRef.current += 1;
    const requestId = requestIdRef.current;

    if (!bounds || selectedCategories.size === 0) {
      abortControllerRef.current?.abort();
      setPois([]);
      return;
    }

    if (debounceRef.current) {
      clearTimeout(debounceRef.current);
    }

    debounceRef.current = setTimeout(async () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
      abortControllerRef.current = new AbortController();

      try {
        const boundsStr = `${bounds.south},${bounds.west},${bounds.north},${bounds.east}`;
        const categoriesStr = Array.from(selectedCategories).join(',');
        const params = new URLSearchParams({
          categories: categoriesStr,
          bounds: boundsStr,
        });
        const res = await fetch(
          apiUrl('pois', params),
          authHeaders({
            signal: abortControllerRef.current.signal,
          })
        );
        if (!res.ok) throw new Error(`POIs fetch failed: HTTP ${res.status}`);
        const json: POIResponse = await res.json();
        if (requestIdRef.current !== requestId) return;
        setPois(json.pois || []);
      } catch (err) {
        logNonAbortError('Failed to fetch POIs', err);
      }
    }, DEBOUNCE_MS);

    return () => {
      if (debounceRef.current) {
        clearTimeout(debounceRef.current);
      }
      abortControllerRef.current?.abort();
    };
  }, [bounds, selectedCategories]);

  return pois;
}
