import { useState, useCallback, useEffect, useRef } from 'react';
import { router } from '@inertiajs/react';
import { type MapBounds } from '@/types/explore';

interface UseExploreStateProps {
    initialSearch?: string | null;
    initialCategory?: string | null;
    initialBounds?: MapBounds | null;
}

export function useExploreState({
    initialSearch = null,
    initialCategory = null,
    initialBounds = null
}: UseExploreStateProps) {
    const [search, setSearch] = useState(initialSearch);
    const [category, setCategory] = useState(initialCategory);
    const [bounds, setBounds] = useState<MapBounds | null>(initialBounds);
    const [selectedItemId, setSelectedItemId] = useState<number | null>(null);
    const [hoveredItemId, setHoveredItemId] = useState<number | null>(null);
    const [isMapView, setIsMapView] = useState(false); // For mobile toggle

    // Use refs to avoid infinite loops
    const boundsTimerRef = useRef<NodeJS.Timeout | null>(null);
    const lastBoundsRef = useRef<string | null>(null);

    // Debounced search
    useEffect(() => {
        const timer = setTimeout(() => {
            updateFilters({ search });
        }, 500);

        return () => clearTimeout(timer);
    }, [search]);

    const updateFilters = useCallback((filters: {
        search?: string | null;
        category?: string | null;
        bounds?: MapBounds | null;
        page?: number;
    }) => {
        const params: Record<string, any> = {};

        if (filters.search !== undefined) {
            params.search = filters.search || undefined;
        } else if (search) {
            params.search = search;
        }

        if (filters.category !== undefined) {
            params.category = filters.category || undefined;
        } else if (category) {
            params.category = category;
        }

        if (filters.bounds !== undefined) {
            if (filters.bounds) {
                params.bounds = `${filters.bounds.south},${filters.bounds.west},${filters.bounds.north},${filters.bounds.east}`;
            }
        } else if (bounds) {
            params.bounds = `${bounds.south},${bounds.west},${bounds.north},${bounds.east}`;
        }

        if (filters.page) {
            params.page = filters.page;
        }

        router.get('/explore', params, {
            preserveState: true,
            preserveScroll: true,
        });
    }, [search, category, bounds]);

    const handleSearchChange = useCallback((value: string) => {
        setSearch(value);
    }, []);

    const handleCategoryChange = useCallback((value: string | null) => {
        setCategory(value);
        updateFilters({ category: value, page: 1 });
    }, [updateFilters]);

    const handleBoundsChange = useCallback((newBounds: MapBounds) => {
        // Create a string representation of bounds for comparison
        const boundsString = `${newBounds.south.toFixed(3)},${newBounds.west.toFixed(3)},${newBounds.north.toFixed(3)},${newBounds.east.toFixed(3)}`;

        // Skip if bounds haven't actually changed (with precision to 3 decimal places)
        if (lastBoundsRef.current === boundsString) {
            return;
        }

        lastBoundsRef.current = boundsString;
        setBounds(newBounds);

        // Clear existing timer
        if (boundsTimerRef.current) {
            clearTimeout(boundsTimerRef.current);
        }

        // Debounce bounds updates (1 second) to avoid excessive API calls during zooming/panning
        boundsTimerRef.current = setTimeout(() => {
            router.get('/explore', {
                search: search || undefined,
                category: category || undefined,
                bounds: `${newBounds.south},${newBounds.west},${newBounds.north},${newBounds.east}`,
                page: 1,
            }, {
                preserveState: true,
                preserveScroll: true,
            });
        }, 1000);
    }, [search, category]);

    const handleClearFilters = useCallback(() => {
        setSearch(null);
        setCategory(null);
        setBounds(null);
        router.get('/explore', {}, { preserveState: true });
    }, []);

    return {
        // State
        search,
        category,
        bounds,
        selectedItemId,
        hoveredItemId,
        isMapView,
        // Setters
        setSearch: handleSearchChange,
        setCategory: handleCategoryChange,
        setBounds: handleBoundsChange,
        setSelectedItemId,
        setHoveredItemId,
        setIsMapView,
        // Actions
        updateFilters,
        clearFilters: handleClearFilters,
    };
}
