import { modals } from "@mantine/modals";
import { Flex } from "@mantine/core";
import { DropResult } from "@hello-pangea/dnd";
import { useEffect, useState } from "react";
import { CardGroupService, CardService, CardSummary, CardSummaryReorderRequest } from "../../../../../client";
import { notifications } from "../../../../../shared/lib/notifications.ts";
import { dateWithoutTimezone } from "../../../../../shared/lib/date.ts";


type Props = {
    summariesRaw: CardSummary[];
    refetchSummaries: () => void;
}

const useCardsDnd = ({
                         summariesRaw,
                         refetchSummaries,
                     }: Props) => {
    const [summaries, setSummaries] = useState(summariesRaw);

    useEffect(() => {
        setSummaries(summariesRaw);
    }, [summariesRaw]);

    const recalculate = async (cardId: number) => {
        return CardService.recalculateCardPrice({
            requestBody: {
                cardId,
            },
        }).then(({ ok, message }) => {
            if (!ok) {
                notifications.guess(ok, { message });
            }
        });
    };

    const onDelete = (cardId: number) => {
        const summary = summaries.find(summary => summary.id == cardId);
        if (!summary) return;
        modals.openConfirmModal({
            title: "Удаление сделки",
            children: (
                <Flex>
                    Вы действительно хотите удалить сделку {summary.name}?
                </Flex>
            ),
            onConfirm: () => {
                CardService.deleteCard({
                    requestBody: { cardId },
                }).then(async ({ ok, message }) => {
                    notifications.guess(ok, { message });
                    if (!ok) return;
                    await refetchSummaries();
                });
            },
            labels: {
                confirm: "Удалить",
                cancel: "Отмена",
            },
        });
    };

    const onSuccess = (cardId: number) => {
        const summary = summaries.find(summary => summary.id == cardId);
        if (!summary) return;
        modals.openConfirmModal({
            title: "Завершение сделки",
            children: (
                <Flex>
                    Вы действительно хотите завершить сделку {summary.name}?
                </Flex>
            ),
            onConfirm: () => {
                CardService.completeCard({
                    requestBody: { cardId },
                }).then(async ({ ok, message }) => {
                    notifications.guess(ok, { message });
                    if (!ok) return;
                    await refetchSummaries();
                });
            },
            labels: {
                confirm: "Завершить",
                cancel: "Отмена",
            },
        });
    };
    const onCombine = async (result: DropResult) => {
        if (!result.combine) return;
        const destination = result.combine.draggableId;
        const source = result.draggableId;
        if (!destination || !source) return;
        const sourceId = parseInt(source);
        if (destination.includes("group")) {
            const groupId = parseInt(destination.split("-")[1]);
            CardGroupService.addCard({
                requestBody: {
                    cardId: sourceId,
                    groupId: groupId,
                },
            }).then(async response => {
                if (!response.ok) {
                    notifications.error({ message: response.message });
                    return;
                }
                await refetchSummaries();
                await recalculate(sourceId);
                await refetchSummaries();
            });
        } else {
            const destinationId = parseInt(destination);
            // creating new group
            CardGroupService.createCardGroup({
                requestBody: {
                    draggingCardId: sourceId,
                    hoveredCardId: destinationId,
                },
            }).then(async response => {
                if (!response.ok) {
                    notifications.error({ message: response.message });
                    return;
                }
                await refetchSummaries();
                await recalculate(sourceId);
                await refetchSummaries();
            });
            return;
        }
    };
    const moveGroup = async (result: DropResult) => {
        const groupId = parseInt(result.draggableId.split("-")[1]);
        const destination = result.destination?.droppableId;
        if (!destination) return;
        const statusId = parseInt(destination);
        CardGroupService.changeStatus({
            requestBody: {
                groupId: groupId,
                newStatus: statusId,
            },
        }).then(async response => {
            if (!response.ok) {
                notifications.error({ message: response.message });
                return;
            }
            await refetchSummaries();
        });
    };

    const onCardDragEnd = async (result: DropResult) => {
        if (result.combine) {
            return onCombine(result);
        }

        // If there is no changes
        if (!result.destination || result.destination == result.source) return;

        // Checking for valid cardId
        if (result.draggableId.includes("group")) {
            return moveGroup(result);
        }
        const cardId = parseInt(result.draggableId);
        if (isNaN(cardId)) return;

        // Checking for valid card
        const summary = summaries.find(summary => summary.id == cardId);
        if (!summary) return;

        // Checking if it is custom actions
        const droppableId = result.destination.droppableId;
        if (droppableId === "DELETE") {
            onDelete(cardId);
            return;
        }
        if (droppableId === "SUCCESS") {
            onSuccess(cardId);
            return;
        }

        const statusId = Number.parseInt(droppableId);
        const request: Partial<CardSummaryReorderRequest> = {
            cardId,
            index: result.destination.index,
            statusId,
        };
        if (statusId == summary.status.id) {
            CardService.reorderCardSummaries({
                requestBody: request as CardSummaryReorderRequest,
            }).then(async response => {
                setSummaries(response.summaries);
                await refetchSummaries();
            });
            return;
        }

        CardService.reorderCardSummaries({
            requestBody: {
                cardId,
                statusId,
                index: result.destination.index,
                comment: "",
                deadline: dateWithoutTimezone(new Date()),
            },
        }).then(async response => {
            setSummaries(response.summaries);
            await refetchSummaries();
        });
    };

    return {
        summaries,
        onCardDragEnd,
    };
};

export default useCardsDnd;
