import { router } from '@inertiajs/react';
import { useCallback, useEffect, useState } from 'react';
import type { PaginationState } from '@/components/data-display';

type UseServerTableOptions = {
    route: () => string;
    pagination: PaginationState;
    filters?: Record<string, string | undefined>;
    filterWithParams?: boolean;
};

export function useServerTable({
    route,
    pagination,
    filters,
    filterWithParams = true,
}: UseServerTableOptions) {
    const [search, setSearch] = useState('');
    const [filterOpen, setFilterOpen] = useState(false);

    useEffect(() => {
        const params = new URLSearchParams(window.location.search);

        if (params.has('search')) {
            params.delete('search');
            const cleanUrl =
                window.location.pathname +
                (params.toString() ? `?${params.toString()}` : '');
            history.replaceState(null, '', cleanUrl);
            router.get(route(), {}, { preserveState: true, replace: true });
        }
    }, []);

    const handlePageChange = useCallback(
        (page: number) => {
            router.get(
                route(),
                {
                    ...filters,
                    page,
                    per_page: pagination.per_page,
                    search,
                },
                { preserveState: true, replace: true },
            );
        },
        [route, filters, pagination.per_page, search],
    );

    const handlePerPageChange = useCallback(
        (perPage: number) => {
            router.get(
                route(),
                {
                    ...filters,
                    page: 1,
                    per_page: perPage,
                    search,
                },
                { preserveState: true, replace: true },
            );
        },
        [route, filters, search],
    );

    const handleSearchChange = useCallback(
        (value: string) => {
            setSearch(value);
            router.get(
                route(),
                {
                    ...filters,
                    page: 1,
                    per_page: pagination.per_page,
                    search: value,
                },
                { preserveState: true, replace: true },
            );
        },
        [route, filters, pagination.per_page],
    );

    function applyFilter(key: string, value: string) {
        const newFilters = { ...filters };

        if (value === '' || value === 'all') {
            delete newFilters[key];
        } else {
            newFilters[key] = value;
        }

        router.get(
            route(),
            filterWithParams
                ? {
                      ...newFilters,
                      page: 1,
                      per_page: pagination.per_page,
                      search,
                  }
                : newFilters,
            { preserveState: true, replace: true },
        );
    }

    function clearFilters() {
        router.get(
            route(),
            filterWithParams
                ? {
                      page: 1,
                      per_page: pagination.per_page,
                      search,
                  }
                : {},
            { preserveState: true, replace: true },
        );
        setFilterOpen(false);
    }

    return {
        search,
        filterOpen,
        setFilterOpen,
        handlePageChange,
        handlePerPageChange,
        handleSearchChange,
        applyFilter,
        clearFilters,
    };
}
