import { useEffect, useState } from 'react'
import { useSearchParams } from 'react-router-dom'

import { FiltersType, URLDecoreFilters, URLEncodeFilters, defaultFilters, excludeFilters } from '../utils/filters'
import { SetState } from '../utils/types'

function useFilters(initialFilters: FiltersType = defaultFilters): [FiltersType, SetState<FiltersType>] {
    const [searchParams, setSearchParams] = useSearchParams()

    const [filters, setFilters] = useState(initialFilters)

    const appendFiltersSearchParams = (filters: FiltersType, replace = false) => (
        setSearchParams(params => ({
            ...excludeFilters(Object.fromEntries(params)),
            ...URLEncodeFilters(filters),
        }), { replace })
    )

    useEffect(() => {
        const urlFilters = URLDecoreFilters(searchParams)

        setFilters(prev => ({
            ...prev,
            ...urlFilters,
        }))

        appendFiltersSearchParams({
            ...URLEncodeFilters(initialFilters),
            ...URLEncodeFilters(urlFilters),
        }, true)
        // searchParams have actual query string at first render
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [])

    const withQuery = (f: SetState<FiltersType>) => (
        (nextInit: (FiltersType | ((prev: FiltersType) => FiltersType))) => {
            const newFilters = (typeof nextInit === 'function') ? nextInit(filters) : nextInit

            appendFiltersSearchParams(newFilters)

            f(nextInit)
        }
    )

    return [filters, withQuery(setFilters)]
}

export default useFilters
