import { createContext, FC, useContext, useState } from "react";
import {
    ClientDetailedSchema,
    ClientSchema,
    ClientService,
    ResidualBoxSchema,
    ResidualPalletSchema,
    ResiduesService,
} from "../../../client";
import { modals } from "@mantine/modals";
import { Text } from "@mantine/core";
import { notifications } from "../../../shared/lib/notifications.ts";
import { useSet } from "@mantine/hooks";

type ResiduesContextState = {
    selectedClient?: ClientDetailedSchema;
    selectClient: (client?: ClientSchema) => void;
    refetchClient: () => void;
    onDeletePalletClick: (pallet: ResidualPalletSchema) => void;
    onCreatePalletClick: () => void;
    onDeleteBoxClick: (box: ResidualBoxSchema) => void;
    onCreateBoxClick: (pallet?: number) => void;
    boxIdsToPrint: Set<number>;
    palletIdsToPrint: Set<number>;
};

const ResiduesContext = createContext<ResiduesContextState | undefined>(
    undefined,
);

const useResiduesContextState = () => {
    const [selectedClient, setSelectedClient] = useState<ClientDetailedSchema>();
    const boxIdsToPrint = useSet<number>();
    const palletIdsToPrint = useSet<number>();

    const fetchClient = (clientId?: number) => {
        if (!clientId) {
            setSelectedClient(undefined);
            return;
        }

        ClientService.getClient({
            clientId,
        }).then(res => {
            setSelectedClient(res.client);
        }).catch(err => console.log(err));
    };

    const selectClient = (client?: ClientSchema) => {
        fetchClient(client?.id);
    };

    const refetchClient = () => {
        fetchClient(selectedClient?.id);
    };

    const onDeletePallet = (palletId: number) => {
        ResiduesService.deleteResidualPallet({ palletId })
            .then(({ ok, message }) => {
                if (!ok) {
                    notifications.error({ message });
                    return;
                }
                palletIdsToPrint.delete(palletId);
                refetchClient();
            })
            .catch(err => console.log(err));
    };

    const onDeletePalletClick = (pallet: ResidualPalletSchema) => {
        if (!selectedClient) return;
        if (pallet.boxes.length === 0 && pallet.residualProducts.length === 0) {
            onDeletePallet(pallet.id);
            return;
        }

        modals.openConfirmModal({
            title: "Удаление паллета",
            children: <Text size="sm">Вы уверены что хотите удалить паллет?</Text>,
            labels: { confirm: "Да", cancel: "Нет" },
            confirmProps: { color: "red" },
            onConfirm: () => onDeletePallet(pallet.id),
        });
    };

    const onDeleteBox = (boxId: number) => {
        ResiduesService.deleteResidualBox({ boxId })
            .then(({ ok, message }) => {
                if (!ok) {
                    notifications.error({ message });
                    return;
                }
                boxIdsToPrint.delete(boxId);
                refetchClient();
            })
            .catch(err => console.log(err));
    };

    const onDeleteBoxClick = (box: ResidualBoxSchema) => {
        if (!selectedClient) return;
        if (box.residualProducts.length === 0) {
            onDeleteBox(box.id);
            return;
        }

        modals.openConfirmModal({
            title: "Удаление короба",
            children: <Text size="sm">Вы уверены что хотите удалить короб?</Text>,
            labels: { confirm: "Да", cancel: "Нет" },
            confirmProps: { color: "red" },
            onConfirm: () => onDeleteBox(box.id),
        });
    };

    const onCreatePalletClick = () => {
        if (!selectedClient) return;
        ResiduesService.createResidualPallet({
            requestBody: { clientId: selectedClient.id },
        })
            .then(({ ok, message }) => {
                if (!ok) notifications.error({ message });
                refetchClient();
            })
            .catch(err => console.log(err));
    };

    const onCreateBoxClick = (palletId?: number) => {
        if (!selectedClient) return;
        ResiduesService.createResidualBox({
            requestBody: {
                palletId: palletId ?? null,
                clientId: palletId ? null : selectedClient.id,
            },
        })
            .then(({ ok, message }) => {
                if (!ok) notifications.error({ message });
                refetchClient();
            })
            .catch(err => console.log(err));
    };

    return {
        selectedClient,
        selectClient,
        refetchClient,
        onDeletePalletClick,
        onCreatePalletClick,
        onDeleteBoxClick,
        onCreateBoxClick,
        boxIdsToPrint,
        palletIdsToPrint,
    };
};

type ResiduesContextProviderProps = {
    children: React.ReactNode;
};

export const ResiduesContextProvider: FC<ResiduesContextProviderProps> = ({ children }) => {
    const state = useResiduesContextState();
    return (
        <ResiduesContext.Provider value={state}>
            {children}
        </ResiduesContext.Provider>
    );
};

export const useResiduesContext = () => {
    const context = useContext(ResiduesContext);
    if (!context) {
        throw new Error(
            "useResiduesContext must be used within a ResiduesContextProvider",
        );
    }
    return context;
};
