import { FC, useEffect, useState } from "react";
import styles from "./LeadsPage.module.css";
import Board from "../../../components/Dnd/Board/Board.tsx";
import { DragDropContext, Droppable, DropResult } from "@hello-pangea/dnd";
import { useDealSummaries } from "../hooks/useDealSummaries.tsx";
import { DealStatus, getDealStatusByName } from "../../../shared/enums/DealStatus.ts";
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
import DealEditDrawer from "../drawers/DealEditDrawer/DealEditDrawer.tsx";
import { DealPageContextProvider } from "../contexts/DealPageContext.tsx";
import { modals } from "@mantine/modals";
import { DealService, DealSummaryReorderRequest } from "../../../client";
import { ActionIcon, Flex, NumberInput, rem, Text } from "@mantine/core";
import classNames from "classnames";
import { notifications } from "../../../shared/lib/notifications.ts";
import { IconMenu2, IconMenuDeep } from "@tabler/icons-react";
import useDealsPageState from "../../DealsPage/hooks/useDealsPageState.tsx";
import DealStatusSelect from "../../DealsPage/components/DealStatusSelect/DealStatusSelect.tsx";
import BaseMarketplaceSelect from "../../../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
import ClientSelectNew from "../../../components/Selects/ClientSelectNew/ClientSelectNew.tsx";
import DealsTable from "../../DealsPage/components/DealsTable/DealsTable.tsx";
import { motion } from "framer-motion";
import { dateWithoutTimezone } from "../../../shared/lib/date.ts";
import DealPrefillDrawer from "../drawers/DealPrefillDrawer/DealPrefillDrawer.tsx";
import { PrefillDealContextProvider } from "../contexts/PrefillDealContext.tsx";
import { useParams } from "@tanstack/react-router";
import { PrefillDealsWithExcelContextProvider } from "../contexts/PrefillDealsWithExcelContext.tsx";
import PrefillDealsWithExcelDrawer from "../drawers/PrefillDealWithExcelDrawer/PrefillDealsWithExcelDrawer.tsx";

enum DisplayMode {
    BOARD,
    TABLE,
}

export const LeadsPage: FC = () => {
    const { data, form } = useDealsPageState();
    const { dealId } = useParams({ strict: false });
    const { summariesRaw, refetch } = useDealSummaries();
    const [summaries, setSummaries] = useState(summariesRaw);
    const [displayMode, setDisplayMode] = useState<DisplayMode>(
        DisplayMode.BOARD,
    );
    const [isDragEnded, setIsDragEnded] = useState(true);

    // const [selectedDeals, setSelectedDeals] = useState<DealSummary[]>([]);

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

    const recalculate = async (dealId: number) => {
        return DealService.recalculateDealPrice({
            requestBody: {
                dealId: dealId,
            },
        }).then(({ ok, message }) => {
            notifications.guess(ok, { message });
        });
    };

    const onDelete = (dealId: number) => {
        const summary = summaries.find(summary => summary.id == dealId);
        if (!summary) return;
        modals.openConfirmModal({
            title: "Удаление сделки",
            children: (
                <Flex>
                    Вы действительно хотите удалить сделку {summary.name}?
                </Flex>
            ),
            onConfirm: () => {
                DealService.deleteDeal({
                    requestBody: { dealId: dealId },
                }).then(async ({ ok, message }) => {
                    notifications.guess(ok, { message });
                    if (!ok) return;
                    await refetch();
                });
            },
            labels: {
                confirm: "Удалить",
                cancel: "Отмена",
            },
        });
    };
    const onSuccess = (dealId: number) => {
        const summary = summaries.find(summary => summary.id == dealId);
        if (!summary) return;
        modals.openConfirmModal({
            title: "Завершение сделки",
            children: (
                <Flex>
                    Вы действительно хотите завершить сделку {summary.name}?
                </Flex>
            ),
            onConfirm: () => {
                DealService.completeDeal({
                    requestBody: { dealId: dealId },
                }).then(async ({ ok, message }) => {
                    notifications.guess(ok, { message });
                    if (!ok) return;
                    await refetch();
                });
            },
            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]);
            DealService.addDealToGroup({
                requestBody: {
                    dealId: sourceId,
                    groupId: groupId,
                },
            }).then(async response => {
                if (!response.ok) {
                    notifications.error({ message: response.message });
                    return;
                }
                await refetch();
                await recalculate(sourceId);
                await refetch();
            });
        } else {
            const destinationId = parseInt(destination);
            // creating new group
            DealService.createDealGroup({
                requestBody: {
                    draggingDealId: sourceId,
                    hoveredDealId: destinationId,
                },
            }).then(async response => {
                if (!response.ok) {
                    notifications.error({ message: response.message });
                    return;
                }
                await refetch();
                await recalculate(sourceId);
                await refetch();
            });
            return;
        }
    };
    const moveGroup = async (result: DropResult) => {
        const groupId = parseInt(result.draggableId.split("-")[1]);
        const destination = result.destination?.droppableId;
        if (!destination) return;
        const status = getDealStatusByName(destination);
        DealService.changeDealGroupStatus({
            requestBody: {
                groupId: groupId,
                newStatus: status,
            },
        }).then(async response => {
            if (!response.ok) {
                notifications.error({ message: response.message });
                return;
            }
            await refetch();
        });
    };
    const onDragEnd = async (result: DropResult) => {

        if (result.combine) {
            return onCombine(result);
        }
        setIsDragEnded(true);
        // If there is no changes
        if (!result.destination || result.destination == result.source) return;

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

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

        // Checking if it is custom actions
        const droppableId = result.destination.droppableId;
        if (droppableId === "DELETE") {
            onDelete(dealId);
            return;
        }
        if (droppableId === "SUCCESS") {
            onSuccess(dealId);
            return;
        }
        const status = getDealStatusByName(droppableId);
        const request: Partial<DealSummaryReorderRequest> = {
            dealId: dealId,
            index: result.destination.index,
            status: status,
        };
        if (status == summary.status) {
            DealService.reorderDealSummaries({
                requestBody: request as DealSummaryReorderRequest,
            }).then(async response => {
                setSummaries(response.summaries);
                await refetch();
            });
            return;
        }

        DealService.reorderDealSummaries({
            requestBody: {
                dealId: dealId,
                status: status,
                index: result.destination.index,
                comment: "",
                deadline: dateWithoutTimezone(new Date()),
            },
        }).then(async response => {
            setSummaries(response.summaries);
            await refetch();
        });
    };
    const getTableBody = () => {
        return (
            <motion.div
                key={displayMode}
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                transition={{ duration: 0.2 }}>
                <DealsTable items={data}
                    // onSelectionChange={setSelectedDeals}
                />
            </motion.div>
        );
    };
    const getBoardBody = () => {
        return (
            <motion.div
                style={{
                    display: "flex",
                    height: "100%",
                    flex: 1,
                }}
                key={displayMode}
                initial={{ opacity: 0 }}
                animate={{ opacity: 1 }}
                transition={{ duration: 0.2 }}>
                <DragDropContext
                    onDragStart={() => {
                        setIsDragEnded(false);
                    }}
                    onDragEnd={onDragEnd}>
                    <Flex
                        justify={"space-between"}
                        direction={"column"}
                        style={{ flex: 1 }}>
                        <div className={styles["boards"]}>
                            <Board
                                withCreateButton
                                summaries={summaries.filter(
                                    summary =>
                                        summary.status ==
                                        DealStatus.AWAITING_ACCEPTANCE,
                                )}
                                title={"Ожидает приемки"}
                                droppableId={"AWAITING_ACCEPTANCE"}
                                color={"#4A90E2"}
                            />
                            <Board
                                summaries={summaries.filter(
                                    summary =>
                                        summary.status == DealStatus.READY_FOR_WORK,
                                )}
                                title={"Готов к работе"}
                                droppableId={"READY_FOR_WORK"}
                                color={"#D3D3D3"}
                            />
                            <Board
                                summaries={summaries.filter(
                                    summary =>
                                        summary.status == DealStatus.PACKAGING,
                                )}
                                title={"Упаковка"}
                                droppableId={"PACKAGING"}
                                color={"#F5A623"}
                            />
                            <Board
                                summaries={summaries.filter(
                                    summary =>
                                        summary.status ==
                                        DealStatus.AWAITING_SHIPMENT,
                                )}
                                title={"Ожидает отгрузки"}
                                droppableId={"AWAITING_SHIPMENT"}
                                color={"#7ED321"}
                            />
                            <Board
                                summaries={summaries.filter(
                                    summary =>
                                        summary.status == DealStatus.IN_DELIVERY,
                                )}
                                title={"В доставке"}
                                droppableId={"IN_DELIVERY"}
                                color={"#6A0DAD"}
                            />
                            <Board
                                summaries={summaries.filter(
                                    summary =>
                                        summary.status ==
                                        DealStatus.AWAITING_PAYMENT,
                                )}
                                title={"Ожидает оплаты"}
                                droppableId={"AWAITING_PAYMENT"}
                                color={"#D0021B"}
                            />
                            <Board
                                summaries={summaries.filter(
                                    summary =>
                                        summary.status == DealStatus.COMPLETED,
                                )}
                                title={"Завершена"}
                                droppableId={"COMPLETED"}
                                color={"#417505"}
                            />
                        </div>
                        <Flex
                            justify={"space-between"}
                            gap={rem(10)}>
                            <div
                                className={classNames(
                                    styles["delete"],
                                    isDragEnded && styles["delete-hidden"],
                                )}>
                                <Droppable droppableId={"DELETE"}>
                                    {(provided, snapshot) => (
                                        <>
                                            <div
                                                {...provided.droppableProps}
                                                ref={provided.innerRef}>
                                                {!isDragEnded &&
                                                    !snapshot.isDraggingOver && (
                                                        <span>Удалить</span>
                                                    )}
                                            </div>
                                            {provided.placeholder}
                                        </>
                                    )}
                                </Droppable>
                            </div>
                            <div
                                className={classNames(
                                    styles["delete"],
                                    isDragEnded && styles["delete-hidden"],
                                )}>
                                <Droppable droppableId={"SUCCESS"}>
                                    {(provided, snapshot) => (
                                        <>
                                            <div
                                                {...provided.droppableProps}
                                                ref={provided.innerRef}>
                                                {!isDragEnded &&
                                                    !snapshot.isDraggingOver && (
                                                        <span>
                                                            Успешно завершена
                                                        </span>
                                                    )}
                                            </div>
                                            {provided.placeholder}
                                        </>
                                    )}
                                </Droppable>
                            </div>
                        </Flex>
                    </Flex>
                </DragDropContext>
            </motion.div>
        );
    };
    const getBody = () => {
        return displayMode === DisplayMode.TABLE
            ? getTableBody()
            : getBoardBody();
    };
    return (
        <PageBlock
            fullHeight
            style={{
                gap: rem(10),
                display: "flex",
                flexDirection: "column",
                backgroundColor: "transparent",
                boxShadow: "none",
            }}>
            <DealPageContextProvider
                defaultDealId={(dealId && parseInt(dealId)) || undefined}
                refetchDeals={async () => {
                    await refetch();
                }}>
                <PrefillDealContextProvider>
                    <PrefillDealsWithExcelContextProvider>
                        <PageBlock style={{ flex: 0 }}>
                            <Flex
                                align={"center"}
                                justify={"space-between"}>
                                <Flex
                                    gap={rem(10)}
                                    direction={"column"}
                                    align={"center"}>
                                    <Text size={"xs"}>Вид</Text>
                                    <Flex gap={rem(10)}>
                                        <ActionIcon
                                            onClick={() =>
                                                setDisplayMode(DisplayMode.BOARD)
                                            }
                                            variant={
                                                displayMode === DisplayMode.BOARD
                                                    ? "filled"
                                                    : "default"
                                            }>
                                            <IconMenuDeep
                                                style={{ rotate: "-90deg" }}
                                            />
                                        </ActionIcon>
                                        <ActionIcon
                                            onClick={() =>
                                                setDisplayMode(DisplayMode.TABLE)
                                            }
                                            variant={
                                                displayMode === DisplayMode.TABLE
                                                    ? "filled"
                                                    : "default"
                                            }>
                                            <IconMenu2 />
                                        </ActionIcon>
                                    </Flex>
                                </Flex>
                                <motion.div
                                    key={displayMode}
                                    initial={{ opacity: 0 }}
                                    animate={{ opacity: 1 }}
                                    transition={{ duration: 0.2 }}>
                                    <div
                                        className={styles["top-panel"]}
                                        style={{
                                            display:
                                                displayMode === DisplayMode.TABLE
                                                    ? "flex"
                                                    : "none",
                                        }}>
                                        <NumberInput
                                            min={1}
                                            placeholder={"Введите номер"}
                                            {...form.getInputProps("id")}
                                            hideControls
                                        />
                                        <DealStatusSelect
                                            onClear={() =>
                                                form.setFieldValue("dealStatus", null)
                                            }
                                            clearable
                                            placeholder={"Выберите статус "}
                                            {...form.getInputProps("dealStatus")}
                                        />
                                        <BaseMarketplaceSelect
                                            onClear={() =>
                                                form.setFieldValue("marketplace", null)
                                            }
                                            clearable
                                            placeholder={"Выберите маркетплейс"}
                                            {...form.getInputProps("marketplace")}
                                        />
                                        <ClientSelectNew
                                            onClear={() =>
                                                form.setFieldValue("client", null)
                                            }
                                            clearable
                                            searchable
                                            placeholder={"Выберите клиента"}
                                            {...form.getInputProps("client")}
                                        />
                                    </div>
                                </motion.div>
                            </Flex>
                        </PageBlock>
                        <PageBlock
                            style={{
                                display: "flex",
                                flexDirection: "column",
                                flex: 1,
                                height: "100%",
                            }}>
                            {getBody()}
                        </PageBlock>
                        <DealEditDrawer />
                        <DealPrefillDrawer />
                        <PrefillDealsWithExcelDrawer />
                    </PrefillDealsWithExcelContextProvider>
                </PrefillDealContextProvider>
            </DealPageContextProvider>
        </PageBlock>
    );
};
