"use client";

import React, { ReactNode } from "react";
import {
    closestCorners,
    DndContext,
    DragEndEvent,
    DragOverEvent,
    DragStartEvent,
} from "@dnd-kit/core";
import {
    horizontalListSortingStrategy,
    SortableContext,
} from "@dnd-kit/sortable";
import { Carousel } from "@mantine/carousel";
import { Group } from "@mantine/core";
import CreateStatusButton from "@/app/deals/components/shared/CreateStatusButton/CreateStatusButton";
import useDndSensors from "@/app/deals/hooks/useSensors";
import FunnelColumn from "@/components/dnd/FunnelDnd/FunnelColumn";
import FunnelOverlay from "@/components/dnd/FunnelDnd/FunnelOverlay";
import { BaseDraggable } from "@/components/dnd/types/types";
import useIsMobile from "@/hooks/useIsMobile";
import SortableItem from "../SortableItem";
import styles from "./FunnelDnd.module.css";

type Props<TContainer, TItem> = {
    containers: TContainer[];
    items: TItem[];
    onDragStart: (event: DragStartEvent) => void;
    onDragOver: (event: DragOverEvent) => void;
    onDragEnd: (event: DragEndEvent) => void;
    renderContainer: (container: TContainer, children: ReactNode) => ReactNode;
    renderContainerOverlay: (
        container: TContainer,
        children: ReactNode
    ) => ReactNode;
    renderItem: (item: TItem) => ReactNode;
    renderItemOverlay: (item: TItem) => ReactNode;
    getContainerId: (container: TContainer) => string;
    getItemsByContainer: (container: TContainer, items: TItem[]) => TItem[];
    activeContainer: TContainer | null;
    activeItem: TItem | null;
    disabledColumns?: boolean;
};

const FunnelDnd = <
    TContainer extends BaseDraggable,
    TItem extends BaseDraggable,
>({
    containers,
    items,
    onDragStart,
    onDragOver,
    onDragEnd,
    renderContainer,
    renderContainerOverlay,
    renderItem,
    renderItemOverlay,
    getContainerId,
    getItemsByContainer,
    activeContainer,
    activeItem,
    disabledColumns = false,
}: Props<TContainer, TItem>) => {
    const sensors = useDndSensors();
    const isMobile = useIsMobile();

    const renderContainers = () =>
        containers.map(container => {
            const containerItems = getItemsByContainer(container, items);
            const containerId = getContainerId(container);
            const item = (
                <SortableItem
                    key={containerId}
                    id={containerId}
                    disabled={disabledColumns}
                    renderItem={() =>
                        renderContainer(
                            container,
                            <FunnelColumn
                                id={containerId}
                                items={containerItems}
                                renderItem={renderItem}
                            />
                        )
                    }
                />
            );
            if (!isMobile) return item;
            return <Carousel.Slide key={containerId}>{item}</Carousel.Slide>;
        });

    const renderBody = () => {
        if (isMobile) {
            return (
                <Carousel
                    slideSize={"80%"}
                    slideGap={"md"}
                    pb={"xl"}
                    withControls={false}
                    withIndicators
                    classNames={styles}>
                    {renderContainers()}
                    <CreateStatusButton />
                </Carousel>
            );
        }
        return (
            <Group
                gap={"xs"}
                wrap="nowrap"
                align="start">
                {renderContainers()}
            </Group>
        );
    };

    return (
        <DndContext
            sensors={sensors}
            collisionDetection={closestCorners}
            onDragStart={onDragStart}
            onDragOver={onDragOver}
            onDragEnd={onDragEnd}>
            <SortableContext
                items={containers.map(getContainerId)}
                strategy={horizontalListSortingStrategy}>
                {renderBody()}
                <FunnelOverlay
                    activeContainer={activeContainer}
                    activeItem={activeItem}
                    renderContainer={container => {
                        const containerItems = getItemsByContainer(
                            container,
                            items
                        );
                        const containerId = getContainerId(container);
                        return renderContainerOverlay(
                            container,
                            <FunnelColumn
                                id={containerId}
                                items={containerItems}
                                renderItem={renderItem}
                            />
                        );
                    }}
                    renderItem={renderItemOverlay}
                />
            </SortableContext>
        </DndContext>
    );
};

export default FunnelDnd;
