/**
 * useFilterItems Hook - Manages filter state for data tables
 */

import { useState, useMemo, useCallback } from 'react';
import { v4 as uuidv4 } from 'uuid';
import type {
  Filter,
  FilterItem,
  FilterFields,
  FilterRequest,
} from '../types/filters';

interface UseFilterItemsReturn {
  filterItems: FilterItem[];
  setFilterItems: (items: FilterItem[]) => void;
  addFilter: () => void;
  removeFilter: (id: string) => void;
  updateFilter: (id: string, fields: Partial<FilterFields>) => void;
  resetFilters: () => void;
  generateFilterRequest: () => string;
  filterRequest: FilterRequest;
}

/**
 * Hook for managing filter items in data tables
 *
 * @param filters - Available filter definitions
 * @returns Filter state and management functions
 *
 * @example
 * ```typescript
 * const filters: Filter[] = [
 *   { title: 'name', label: 'Name' },
 *   { title: 'status', label: 'Status', type: 'enum', options: ['active', 'inactive'] }
 * ]
 * const { filterItems, addFilter, removeFilter, generateFilterRequest } = useFilterItems(filters)
 * ```
 */
export function useFilterItems(filters: Filter[]): UseFilterItemsReturn {
  const [filterItems, setFilterItems] = useState<FilterItem[]>([]);

  const addFilter = useCallback(() => {
    const newFilter: FilterItem = {
      id: uuidv4(),
      fields: {
        selectedField: filters[0]?.title || '',
        filterValue: '',
        filterValueFrom: '',
        filterValueTo: '',
      },
    };
    setFilterItems((prev) => [...prev, newFilter]);
  }, [filters]);

  const removeFilter = useCallback((id: string) => {
    setFilterItems((prev) => prev.filter((item) => item.id !== id));
  }, []);

  const updateFilter = useCallback(
    (id: string, fields: Partial<FilterFields>) => {
      setFilterItems((prev) =>
        prev.map((item) => {
          if (item.id !== id) return item;
          // If changing the selected field, reset values
          if (
            fields.selectedField &&
            fields.selectedField !== item.fields.selectedField
          ) {
            return {
              id,
              fields: {
                selectedField: fields.selectedField,
                filterValue: '',
                filterValueFrom: '',
                filterValueTo: '',
              },
            };
          }
          return {
            id,
            fields: { ...item.fields, ...fields },
          };
        }),
      );
    },
    [],
  );

  const resetFilters = useCallback(() => {
    setFilterItems([]);
  }, []);

  // Generate filter request object
  const filterRequest = useMemo<FilterRequest>(() => {
    const request: FilterRequest = {};

    filterItems.forEach((item) => {
      const filter = filters.find((f) => f.title === item.fields.selectedField);
      if (!filter) return;

      const isRangeFilter = filter.number || filter.date;

      if (isRangeFilter) {
        const rangeKey = `${item.fields.selectedField}Range`;
        const values: string[] = [];
        if (item.fields.filterValueFrom) {
          values.push(item.fields.filterValueFrom);
        }
        if (item.fields.filterValueTo) {
          values.push(item.fields.filterValueTo);
        }
        if (values.length > 0) {
          request[rangeKey] = values;
        }
      } else if (item.fields.filterValue) {
        request[item.fields.selectedField] = item.fields.filterValue;
      }
    });

    return request;
  }, [filterItems, filters]);

  // Generate filter request as query string
  const generateFilterRequest = useCallback((): string => {
    let request = '&';

    filterItems.forEach((item) => {
      const filter = filters.find((f) => f.title === item.fields.selectedField);
      if (!filter) return;

      const isRangeFilter = filter.number || filter.date;

      if (isRangeFilter) {
        const from = item.fields.filterValueFrom;
        const to = item.fields.filterValueTo;
        if (from) {
          request += `${item.fields.selectedField}Range=${encodeURIComponent(from)}&`;
        }
        if (to) {
          request += `${item.fields.selectedField}Range=${encodeURIComponent(to)}&`;
        }
      } else {
        const value = item.fields.filterValue;
        if (value) {
          request += `${item.fields.selectedField}=${encodeURIComponent(value)}&`;
        }
      }
    });

    return request;
  }, [filterItems, filters]);

  return {
    filterItems,
    setFilterItems,
    addFilter,
    removeFilter,
    updateFilter,
    resetFilters,
    generateFilterRequest,
    filterRequest,
  };
}

export default useFilterItems;
