import { closestCenter, DndContext, DragOverlay, MouseSensor, useSensor, useSensors } from '@dnd-kit/core';
import React, { useCallback, useMemo, useState } from 'react';
import { createPortal } from 'react-dom';
import { DndItemTypes } from '../../types';
import { DndMeasurer } from '../DndMeasurer';
import { TableColumnDragPreview } from '../TableColumnDragPreview';
import { TableRowDragPreview } from '../TableRowDragPreview';
import { columnMoveModifier, rowMoveModifier } from './helpers';
import { useStyles } from './styles';
export var DndComponent = function (_a) {
    var _b, _c;
    var children = _a.children, containerRef = _a.containerRef, onMoveColumn = _a.onMoveColumn, onDropColumn = _a.onDropColumn, onMoveRow = _a.onMoveRow, onDropRow = _a.onDropRow, columnsId = _a.columnsId, rowsId = _a.rowsId, tableClassName = _a.tableClassName;
    var styles = useStyles();
    var containerHeight = (_b = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) === null || _b === void 0 ? void 0 : _b.clientHeight;
    var containerWidth = (_c = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current) === null || _c === void 0 ? void 0 : _c.clientWidth;
    var _d = useState(null), draggingType = _d[0], setDraggingType = _d[1];
    var _e = useState(null), draggingColumn = _e[0], setDraggingColumn = _e[1];
    var _f = useState(null), draggingRow = _f[0], setDraggingRow = _f[1];
    var onDragStart = useCallback(function (event) {
        var _a, _b;
        var dndData = (_b = (_a = event.active) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.current;
        if (dndData) {
            setDraggingType(dndData === null || dndData === void 0 ? void 0 : dndData.type);
        }
        if ((dndData === null || dndData === void 0 ? void 0 : dndData.type) === DndItemTypes.Column) {
            setDraggingColumn(dndData);
        }
        if ((dndData === null || dndData === void 0 ? void 0 : dndData.type) === DndItemTypes.Row) {
            setDraggingRow(dndData);
        }
    }, []);
    var onDragEnd = useCallback(function (event) {
        var _a, _b, _c;
        var draggingType = (_c = (_b = (_a = event.active) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.current) === null || _c === void 0 ? void 0 : _c.type;
        setDraggingType(null);
        setDraggingColumn(null);
        setDraggingRow(null);
        if (draggingType === DndItemTypes.Column) {
            onDropColumn();
        }
        if (draggingType === DndItemTypes.Row) {
            onDropRow();
        }
    }, [onDropColumn, onDropRow]);
    var modifiers = useMemo(function () {
        switch (draggingType) {
            case DndItemTypes.Column:
                return [columnMoveModifier];
            case DndItemTypes.Row:
                return [rowMoveModifier];
            default:
                return [];
        }
    }, [draggingType]);
    var onDragOver = useCallback(function (_a) {
        var _b, _c;
        var active = _a.active, over = _a.over;
        if (active.id === (over === null || over === void 0 ? void 0 : over.id))
            return;
        switch ((_c = (_b = active === null || active === void 0 ? void 0 : active.data) === null || _b === void 0 ? void 0 : _b.current) === null || _c === void 0 ? void 0 : _c.type) {
            case DndItemTypes.Column:
                return onMoveColumn(active.id, over === null || over === void 0 ? void 0 : over.id);
            case DndItemTypes.Row:
                return onMoveRow(active.id, over === null || over === void 0 ? void 0 : over.id);
        }
    }, [onMoveColumn, onMoveRow]);
    var dragOverlayStyle = useMemo(function () {
        var _a;
        var containerRect = (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
        switch (draggingType) {
            case DndItemTypes.Column:
                return {
                    top: containerRect.top,
                    width: 'auto',
                    height: 'auto'
                };
            case DndItemTypes.Row:
                return {
                    left: containerRect.left,
                    width: 'auto',
                    height: 'auto'
                };
            default:
                return {};
        }
    }, [containerRef, draggingType]);
    var mouseSensor = useSensor(MouseSensor);
    var sensors = useSensors(mouseSensor);
    return (React.createElement(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragStart: onDragStart, onDragEnd: onDragEnd, onDragOver: onDragOver },
        children,
        draggingType && createPortal(React.createElement("div", { className: styles.backDrop }), document.body),
        React.createElement(DndMeasurer, { columnsId: columnsId, rowsId: rowsId }),
        createPortal(React.createElement(DragOverlay, { dropAnimation: null, style: dragOverlayStyle, modifiers: modifiers },
            React.createElement(TableColumnDragPreview, { columnHeight: containerHeight, draggingColumn: draggingColumn }),
            React.createElement(TableRowDragPreview, { tableWidth: containerWidth, draggingRow: draggingRow, tableClassName: tableClassName })), document.body)));
};
