import React from "react";
import { useMutation } from "@tanstack/react-query";
import { Text } from "@mantine/core";
import { modals } from "@mantine/modals";
import getCommonQueryClient from "@/hooks/cruds/baseCrud/getCommonQueryClient";
import {
    CreateDealServiceSchema,
    DealServiceSchema,
    UpdateDealServiceSchema,
} from "@/lib/client";
import {
    createDealServiceMutation,
    deleteDealServiceMutation,
    getDealServicesQueryKey,
    updateDealServiceMutation,
} from "@/lib/client/@tanstack/react-query.gen";

type Props = {
    dealId: number;
};

export type DealServicesCrud = {
    onCreate: (data: CreateDealServiceSchema) => void;
    onUpdate: (
        dealId: number,
        serviceId: number,
        data: UpdateDealServiceSchema
    ) => void;
    onDelete: (data: DealServiceSchema, onSuccess?: () => void) => void;
};

const useDealServicesCrud = ({ dealId }: Props): DealServicesCrud => {
    const queryKey = getDealServicesQueryKey({ path: { dealId } });
    const key = "getDealServices";
    const { queryClient, onError, onSettled } = getCommonQueryClient({
        queryKey,
        key,
    });

    const createMutation = useMutation({
        ...createDealServiceMutation(),
        onError,
        onSettled,
    });

    const updateMutation = useMutation({
        ...updateDealServiceMutation(),
        onError,
        onSettled,
        onMutate: async ({
            body: { entity: update },
            path: { dealId, serviceId },
        }) => {
            await queryClient.cancelQueries({ queryKey: [key] });

            const previous = queryClient.getQueryData(queryKey);

            queryClient.setQueryData(
                queryKey,
                (old: { items: DealServiceSchema[] }) => {
                    const updated: DealServiceSchema[] = old.items.map(
                        (entity: DealServiceSchema) =>
                            entity.dealId === dealId &&
                            entity.serviceId === serviceId
                                ? { ...entity, ...update }
                                : entity
                    );

                    return {
                        ...old,
                        items: updated,
                    };
                }
            );

            return { previous };
        },
    });

    const deleteMutation = useMutation({
        ...deleteDealServiceMutation(),
        onError,
        onSettled,
        onMutate: async ({ path: { dealId, serviceId } }) => {
            await queryClient.cancelQueries({ queryKey: [key] });

            const previous = queryClient.getQueryData(queryKey);

            queryClient.setQueryData(
                queryKey,
                (old: { items: DealServiceSchema[] }) => {
                    const filtered = old.items.filter(
                        e => e.dealId !== dealId && e.serviceId !== serviceId
                    );
                    return {
                        ...old,
                        items: filtered,
                    };
                }
            );

            return { previous };
        },
    });

    const onCreate = (entity: CreateDealServiceSchema) => {
        createMutation.mutate({
            body: {
                entity,
            },
        });
    };

    const onUpdate = (
        dealId: number,
        serviceId: number,
        entity: UpdateDealServiceSchema
    ) => {
        updateMutation.mutate({
            body: {
                entity,
            },
            path: {
                dealId,
                serviceId,
            },
        });
    };

    const onDelete = (entity: DealServiceSchema, onSuccess?: () => void) => {
        modals.openConfirmModal({
            title: "Удаление услуги из сделки",
            children: (
                <Text>
                    Вы уверены, что хотите удалить "{entity.service.name}" из
                    сделки?
                </Text>
            ),
            confirmProps: { color: "red" },
            onConfirm: () => {
                deleteMutation.mutate({ path: entity }, { onSuccess });
            },
        });
    };

    return {
        onCreate,
        onUpdate,
        onDelete,
    };
};

export default useDealServicesCrud;
