import { useState, useCallback, useRef } from 'react';

import { router } from '@inertiajs/react';

export interface UseFilterStateReturn<T extends Record<string, unknown>> {
  filters: T;
  setFilter: (key: keyof T, value: T[keyof T]) => void;
  resetFilters: () => void;
  isFiltering: boolean;
}

/**
 * DEBT-006: URL-synced filter state for list pages.
 *
 * Replaces the repeated pattern of managing separate filter useState hooks
 * and calling router.reload with replace:true + preserveState.
 *
 * Filters are applied immediately to local state and debounced to Inertia reload
 * so the UI responds instantly while reducing server requests.
 *
 * Usage:
 *   const { filters, setFilter, resetFilters, isFiltering } = useFilterState({
 *     search: '', status: 'all', sort: 'desc'
 *   });
 *   <input value={filters.search} onChange={e => setFilter('search', e.target.value)} />
 */
export function useFilterState<T extends Record<string, unknown>>(
  initialFilters: T,
  debounceMs = 300,
): UseFilterStateReturn<T> {
  const [filters, setFilters] = useState<T>(initialFilters);
  const [isFiltering, setIsFiltering] = useState(false);
  const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const applyFilters = useCallback(
    (newFilters: T) => {
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
      }

      setIsFiltering(true);
      debounceTimerRef.current = setTimeout(() => {
        router.reload({
          data: newFilters as Record<string, string | number | boolean | null | undefined>,
          replace: true,
          onFinish: () => setIsFiltering(false),
        });
      }, debounceMs);
    },
    [debounceMs],
  );

  const setFilter = useCallback(
    (key: keyof T, value: T[keyof T]) => {
      setFilters((prev) => {
        const next = { ...prev, [key]: value };
        applyFilters(next);
        return next;
      });
    },
    [applyFilters],
  );

  const resetFilters = useCallback(() => {
    setFilters(initialFilters);
    applyFilters(initialFilters);
  }, [initialFilters, applyFilters]);

  return { filters, setFilter, resetFilters, isFiltering };
}
