import { useCallback, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import type { DateFilterField, SortOption } from '../utils/listFilterUtils';
import { normalizeSortBy } from '../utils/listFilterUtils';

export interface ListSortFilterState {
  sortBy: SortOption;
  dateFilterBy: DateFilterField;
  dateStart: string;
  dateEnd: string;
  page: number;
  setSortBy: (value: string) => void;
  setDateFilterBy: (value: DateFilterField) => void;
  setDateStart: (value: string) => void;
  setDateEnd: (value: string) => void;
  setPage: (value: number) => void;
  resetPage: () => void;
}

export function useListSortFilters(defaultSort: SortOption = 'creation desc'): ListSortFilterState {
  const [searchParams, setSearchParams] = useSearchParams();

  const sortBy = normalizeSortBy(searchParams.get('sort_by') || defaultSort, defaultSort);
  const dateFilterBy = (searchParams.get('date_filter_by') || '') as DateFilterField;
  const dateStart = searchParams.get('date_start') || '';
  const dateEnd = searchParams.get('date_end') || '';
  const page = Math.max(0, parseInt(searchParams.get('page') || '1', 10) - 1);

  const updateParams = useCallback(
    (updates: Record<string, string | null>, resetPageOnChange = false) => {
      const next = new URLSearchParams(searchParams);

      for (const [key, value] of Object.entries(updates)) {
        if (value === null || value === '') next.delete(key);
        else next.set(key, value);
      }

      if (resetPageOnChange) {
        next.delete('page');
      }

      setSearchParams(next, { replace: true });
    },
    [searchParams, setSearchParams]
  );

  const setSortBy = useCallback(
    (value: string) => updateParams({ sort_by: value }, true),
    [updateParams]
  );

  const setDateFilterBy = useCallback(
    (value: DateFilterField) => updateParams({ date_filter_by: value || null }, true),
    [updateParams]
  );

  const setDateStart = useCallback(
    (value: string) => updateParams({ date_start: value || null }, true),
    [updateParams]
  );

  const setDateEnd = useCallback(
    (value: string) => updateParams({ date_end: value || null }, true),
    [updateParams]
  );

  const setPage = useCallback(
    (value: number) => updateParams({ page: value <= 0 ? null : String(value + 1) }),
    [updateParams]
  );

  const resetPage = useCallback(() => updateParams({ page: null }), [updateParams]);

  return useMemo(
    () => ({
      sortBy,
      dateFilterBy,
      dateStart,
      dateEnd,
      page,
      setSortBy,
      setDateFilterBy,
      setDateStart,
      setDateEnd,
      setPage,
      resetPage,
    }),
    [
      sortBy,
      dateFilterBy,
      dateStart,
      dateEnd,
      page,
      setSortBy,
      setDateFilterBy,
      setDateStart,
      setDateEnd,
      setPage,
      resetPage,
    ]
  );
}
