var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import { v4 as uuid } from 'uuid';
import React, { useCallback, useRef, useState, useEffect } from 'react';
import { Responsive as ResponsiveGridLayout } from 'react-grid-layout';
import { makeStyles, useTheme } from '@material-ui/core';
import { useMeasure } from 'react-use';
import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css';
import { useDragLayer } from 'react-dnd';
import getWidgetLayout from './getWidgetLayout.ts';
import { useShellStore } from '../stores/shellStore';
const useStyle = makeStyles((theme) => ({
    root: {
        display: 'flex',
        flexDirection: 'column',
        width: '100%',
        flexGrow: 1,
        marginBottom: (props) => ((props === null || props === void 0 ? void 0 : props.disableMargin) ? '' : theme.spacing(3))
    },
    autoHeightContainer: {
        height: 'auto !important',
        display: 'flex',
        flexWrap: 'wrap',
        gap: `${theme.spacing(3)}px ${theme.spacing(3)}px`,
        '& > .react-grid-item': {
            position: 'relative !important',
            top: 'auto !important',
            left: 'auto !important',
            transform: 'none !important',
            height: 'auto !important'
        }
    }
}), { name: 'DashboardCardGrid' });
const DASHBOARD_WIDGET = Symbol('DASHBOARD_WIDGET');
const breakpoints = {
    xs: 0,
    xl: 1150
};
const breakpointCols = {
    xs: 4,
    xl: 4
};
/**
 * Grid layout for dashboard cards
 */
const DashboardCardGrid = (props) => {
    var _a, _b, _c;
    var _d;
    const classes = useStyle(props);
    const { children, onCreateCard, gridProperties, autoHeight } = props, other = __rest(props, ["children", "onCreateCard", "gridProperties", "autoHeight"]);
    const { getWidget } = useShellStore();
    const rglRef = useRef();
    const [ref, { width }] = useMeasure();
    const theme = useTheme();
    const { droppingWidgetType } = useDragLayer((monitor) => {
        if (monitor.getItemType() === DASHBOARD_WIDGET) {
            const { id: wigetType } = monitor.getItem();
            return { droppingWidgetType: wigetType };
        }
        return { droppingWidgetType: null };
    });
    const [droppingItemLayout, setDroppingItemLayout] = useState(null);
    useEffect(() => {
        let isMounted = true;
        // Asynchronously resolve the widget definition to get its layout properties
        const resolveLayout = async (widgetDefPromise) => {
            try {
                const module = await widgetDefPromise;
                // Handle ES modules with default exports
                const widgetDef = (module === null || module === void 0 ? void 0 : module.default) || module;
                // Use the external layout getter, assuming it can handle the resolved definition
                const layout = getWidgetLayout(widgetDef);
                if (isMounted) {
                    setDroppingItemLayout(Object.assign({ i: uuid() }, layout));
                }
            }
            catch (e) {
                console.error(`Error resolving layout for widget type "${droppingWidgetType}"`, e);
                // Fallback to a default layout on error
                const fallbackLayout = getWidgetLayout(null);
                if (isMounted) {
                    setDroppingItemLayout(Object.assign({ i: uuid() }, fallbackLayout));
                }
            }
        };
        if (droppingWidgetType) {
            const res = getWidget(droppingWidgetType);
            // Check if the result is a promise (for async widgets)
            if (res === null || res === void 0 ? void 0 : res.then) {
                setDroppingItemLayout(null); // Clear previous layout while loading
                resolveLayout(res);
            }
            else {
                // Handle synchronously available widget definitions
                const layout = getWidgetLayout(res);
                setDroppingItemLayout(Object.assign({ i: uuid() }, layout));
            }
        }
        else {
            setDroppingItemLayout(null);
        }
        return () => {
            isMounted = false;
        };
    }, [droppingWidgetType, getWidget]);
    const drag = useCallback((layout, oldLayoutItem, layoutItem, placeholder) => {
        // Cards larger than 1 should snap to columns that are a multiple of 2
        // if (layoutItem.w > 1) {
        //   // @fixme This affects the visual placeholder, but doesn't actually fix the layout item when its dropped
        //   placeholder.x = layoutItem.x = Math.floor(layoutItem.x / 2) * 2;
        // }
    }, []);
    const resize = useCallback((layout, oldLayoutItem, layoutItem, placeholder) => {
        // Widths larger than 1 should be a multiple of 2
        // The small size of columns is just so we can have small 1x1 tiles that are 1/2 the size of normal cards
        // if (layoutItem.w > 1) {
        //   const w = Math.floor(layoutItem.w / 2) * 3;
        //   layoutItem.w = w;
        //   placeholder.w = w;
        // }
        // There is no 3 (i.e. 6) column layout so don't allow cards to be that size either
        if (layoutItem.w >= 6 && layoutItem.w < 8) {
            layoutItem.w = 4;
            placeholder.w = 4;
        }
    }, []);
    const drop = useCallback((layout, item) => {
        if (droppingWidgetType) {
            const { x, y, w, h } = item;
            const { breakpoint } = rglRef.current.state;
            if (onCreateCard)
                onCreateCard({
                    widgetType: droppingWidgetType,
                    id: uuid(),
                    layout: {
                        [breakpoint]: {
                            x,
                            y,
                            w,
                            h
                        }
                    },
                    params: []
                });
        }
    }, [droppingWidgetType, onCreateCard]);
    return (React.createElement("div", { ref: ref, className: classes.root }, width ? (React.createElement(ResponsiveGridLayout, Object.assign({ ref: rglRef }, other, { width: width, breakpoints: breakpoints, cols: breakpointCols, rowHeight: 128, margin: [theme.spacing(3), theme.spacing(3)], containerPadding: [0, 0], draggableHandle: "[data-handle]", onDrag: drag, onResize: resize, onDrop: drop, isDroppable: (gridProperties === null || gridProperties === void 0 ? void 0 : gridProperties.isDroppable) || false, isDraggable: (gridProperties === null || gridProperties === void 0 ? void 0 : gridProperties.isDraggable) || false, droppingItem: droppingItemLayout, className: autoHeight ? classes.autoHeightContainer : '', style: autoHeight
            ? {}
            : {
                height: '100%'
            }, useCSSTransforms: (_d = (_c = (_b = (_a = children[0]) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.params) === null || _c === void 0 ? void 0 : _c.applyWidgetTransformStyling) !== null && _d !== void 0 ? _d : true }), children)) : null));
};
export default DashboardCardGrid;
//# sourceMappingURL=DashboardCardGrid.js.map