import { useState, useCallback, useMemo } from 'react';
import { FilterState, RowData } from './validationTypes';
import type { Fields } from '../../../types';
import { ValidationError } from '../../../types';

export const useFilterManagement = <T extends string>(
  data: RowData<T>[],
  fields: Fields<T>,
  validationErrors: Map<number, Record<string, ValidationError[]>>
) => {
  // Filter state
  const [filters, setFilters] = useState<FilterState>({
    searchText: "",
    showErrorsOnly: false,
    filterField: null,
    filterValue: null,
  });

  // Filter data based on current filter state
  const filteredData = useMemo(() => {
    // Fast path: no filters active, return original data reference to avoid re-renders
    const noSearch = !filters.searchText || filters.searchText.trim() === '';
    const noErrorsOnly = !filters.showErrorsOnly;
    const noFieldFilter = !filters.filterField || !filters.filterValue || filters.filterValue.trim() === '';

    if (noSearch && noErrorsOnly && noFieldFilter) {
      return data; // preserve reference; prevents full table rerender on error map changes
    }

    return data.filter((row, index) => {
      // Filter by search text
      if (filters.searchText) {
        const searchLower = filters.searchText.toLowerCase();
        const matchesSearch = fields.some((field) => {
          const value = row[field.key as keyof typeof row];
          if (value === undefined || value === null) return false;
          return String(value).toLowerCase().includes(searchLower);
        });
        if (!matchesSearch) return false;
      }

      // Filter by errors
      if (filters.showErrorsOnly) {
        const hasErrors =
          validationErrors.has(index) &&
          Object.keys(validationErrors.get(index) || {}).length > 0;
        if (!hasErrors) return false;
      }

      // Filter by field value
      if (filters.filterField && filters.filterValue) {
        const fieldValue = row[filters.filterField as keyof typeof row];
        if (fieldValue === undefined) return false;

        const valueStr = String(fieldValue).toLowerCase();
        const filterStr = filters.filterValue.toLowerCase();

        if (!valueStr.includes(filterStr)) return false;
      }

      return true;
    });
  }, [data, fields, filters, validationErrors]);

  // Get filter fields
  const filterFields = useMemo(() => {
    return fields.map((field) => ({
      key: String(field.key),
      label: field.label,
    }));
  }, [fields]);

  // Get filter values for the selected field
  const filterValues = useMemo(() => {
    if (!filters.filterField) return [];

    // Get unique values for the selected field
    const uniqueValues = new Set<string>();

    data.forEach((row) => {
      const value = row[filters.filterField as keyof typeof row];
      if (value !== undefined && value !== null) {
        uniqueValues.add(String(value));
      }
    });

    return Array.from(uniqueValues).map((value) => ({
      value,
      label: value,
    }));
  }, [data, filters.filterField]);

  // Update filters
  const updateFilters = useCallback((newFilters: Partial<FilterState>) => {
    setFilters((prev) => ({
      ...prev,
      ...newFilters,
    }));
  }, []);

  // Reset filters
  const resetFilters = useCallback(() => {
    setFilters({
      searchText: "",
      showErrorsOnly: false,
      filterField: null,
      filterValue: null,
    });
  }, []);

  return {
    filters,
    filteredData,
    filterFields,
    filterValues,
    updateFilters,
    resetFilters
  };
}; 
