import { Dispatch, SetStateAction, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { UseFormReturnType } from "@mantine/form";
import { useDebouncedValue } from "@mantine/hooks";
import useDealsFilters, {
    DealsFiltersForm,
} from "@/app/deals/hooks/useDealsFilters";
import useSorting, { SortingForm } from "@/hooks/utils/useSorting";
import { DealSchema, GetDealsData, PaginationInfoSchema } from "@/lib/client";
import {
    getDealsOptions,
    getDealsQueryKey,
} from "@/lib/client/@tanstack/react-query.gen";

type Props = {
    boardId?: number | null;
    projectId?: number | null;
    withPagination: boolean;
};

type ReturnType = {
    deals: DealSchema[];
    setDeals: (deals: DealSchema[]) => void;
    dealsFiltersForm: UseFormReturnType<DealsFiltersForm>;
    isChangedFilters: boolean;
    sortingForm: UseFormReturnType<SortingForm>;
    refetchDeals: () => void;
    page: number;
    setPage: Dispatch<SetStateAction<number>>;
    paginationInfo?: PaginationInfoSchema;
    queryKey: any[];
};

const useDealsList = ({
    withPagination,
    projectId = null,
    boardId = null,
}: Props): ReturnType => {
    const queryClient = useQueryClient();
    const [page, setPage] = useState(1);
    const itemsPerPage = 10;
    const { form: dealsFiltersForm, isChangedFilters } = useDealsFilters();
    const { form: sortingForm } = useSorting();

    const [debouncedId] = useDebouncedValue(dealsFiltersForm.values.id, 300);
    const [debouncedName] = useDebouncedValue(
        dealsFiltersForm.values.name,
        300
    );

    const options: Omit<GetDealsData, "url"> = {
        query: {
            page: withPagination ? page : null,
            itemsPerPage: withPagination ? itemsPerPage : null,
            sortingField: withPagination
                ? sortingForm.values.sortingField
                : null,
            sortingDirection: withPagination
                ? sortingForm.values.sortingDirection
                : null,
            projectId: withPagination ? projectId : null,
            boardId: withPagination
                ? dealsFiltersForm.values.board?.id
                : boardId,
            statusId: withPagination
                ? dealsFiltersForm.values.status?.id
                : null,
            name: debouncedName,
            id: debouncedId,
        },
    };

    const { data, refetch } = useQuery(getDealsOptions(options));

    const queryKey = getDealsQueryKey(options);

    const setDeals = (deals: DealSchema[]) => {
        queryClient.setQueryData(queryKey, (old: { items: DealSchema[] }) => ({
            ...old,
            items: deals,
        }));
    };

    return {
        deals: data?.items ?? [],
        setDeals,
        dealsFiltersForm,
        sortingForm,
        isChangedFilters,
        refetchDeals: refetch,
        page,
        setPage,
        paginationInfo: data?.paginationInfo,
        queryKey,
    };
};

export default useDealsList;
