/**
 * useFiltering Hook
 *
 * A composable hook for managing filter state with support for
 * multiple filters with various operators.
 *
 * @example
 * ```tsx
 * const filtering = useFiltering<'status' | 'category' | 'price'>();
 *
 * return (
 *   <div>
 *     <select
 *       value={filtering.getFilterValue('status') ?? ''}
 *       onChange={(e) => {
 *         if (e.target.value) {
 *           filtering.setFilter('status', 'eq', e.target.value);
 *         } else {
 *           filtering.removeFilter('status');
 *         }
 *       }}
 *     >
 *       <option value="">All Statuses</option>
 *       <option value="active">Active</option>
 *       <option value="inactive">Inactive</option>
 *     </select>
 *
 *     <button onClick={filtering.clearFilters}>Clear All Filters</button>
 *
 *     <div>Active filters: {filtering.count}</div>
 *   </div>
 * );
 * ```
 *
 * ⚠️ AUTO-GENERATED BY PRISM - DO NOT EDIT
 */

import { useState, useCallback, useMemo } from 'react';
import type {
  FilterOperator,
  FilterEntry,
  FilteringOptions,
  FilteringState,
  FilteringActions,
  UseFilteringResult,
} from '../types';

/**
 * Hook for managing filter state.
 *
 * @param options - Filtering options
 * @returns Filtering state and actions
 */
export function useFiltering<TField = string>(
  options: FilteringOptions<TField> = {}
): UseFilteringResult<TField> {
  const { initialFilters = [] } = options;

  const [filters, setFilters] = useState<FilterEntry<TField>[]>(initialFilters);

  // Computed values
  const count = filters.length;
  const hasFilters = count > 0;

  // Create a map for fast lookup by field
  const filterMap = useMemo(() => {
    const map = new Map<TField, FilterEntry<TField>>();
    for (const filter of filters) {
      map.set(filter.field, filter);
    }
    return map;
  }, [filters]);

  // Actions
  const setFilter = useCallback(
    <TValue>(field: TField, operator: FilterOperator, value: TValue) => {
      setFilters((prev) => {
        const existingIndex = prev.findIndex((f) => f.field === field);
        const newEntry: FilterEntry<TField> = { field, operator, value };

        if (existingIndex !== -1) {
          // Update existing filter
          const newFilters = [...prev];
          newFilters[existingIndex] = newEntry;
          return newFilters;
        }
        // Add new filter
        return [...prev, newEntry];
      });
    },
    []
  );

  const removeFilter = useCallback((field: TField) => {
    setFilters((prev) => prev.filter((f) => f.field !== field));
  }, []);

  const clearFilters = useCallback(() => {
    setFilters([]);
  }, []);

  const getFilterValue = useCallback(
    <TValue = unknown>(field: TField): TValue | undefined => {
      const filter = filterMap.get(field);
      return filter?.value as TValue | undefined;
    },
    [filterMap]
  );

  const hasFilter = useCallback(
    (field: TField): boolean => filterMap.has(field),
    [filterMap]
  );

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

  // Build state object
  const state: FilteringState<TField> = {
    filters,
    count,
    hasFilters,
  };

  // Build actions object
  const actions: FilteringActions<TField> = {
    setFilter,
    removeFilter,
    clearFilters,
    getFilterValue,
    hasFilter,
    reset,
  };

  return {
    ...state,
    ...actions,
  };
}

export default useFiltering;
