import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
// (C) 2007-2026 GoodData Corporation
import { useCallback, useMemo, useRef } from "react";
import cx from "classnames";
import { isEqual } from "lodash-es";
import { DashboardLayoutFacade } from "../../../_staging/dashboard/flexibleLayout/facade/layout.js";
import { getItemIndex, serializeLayoutSectionPath } from "../../../_staging/layout/coordinates.js";
import { layoutTransformer } from "../../../_staging/slideshow/layoutTransformer.js";
import { isInitialPlaceholderWidget } from "../../../widgets/placeholders/types.js";
import { emptyDOMRect } from "../../constants.js";
import { useDashboardItemPathAndSize } from "../../dashboard/components/DashboardItemPathAndSizeContext.js";
import { useScreenSize } from "../../dashboard/components/DashboardScreenSizeContext.js";
import { useSlideSizeStyle } from "../../dashboardContexts/useSlideData.js";
import { useDashboardExportData } from "../../export/useExportData.js";
import { SectionHotspot } from "../dragAndDrop/draggableWidget/SectionHotspot.js";
import { DashboardLayoutSection } from "./DashboardLayoutSection.js";
import { GridLayoutElement } from "./GridLayoutElement.js";
import { getResizedItemPositions, unifyDashboardLayoutItemHeights } from "./utils/sizing.js";
const defaultSectionKeyGetter = ({ section }) => serializeLayoutSectionPath(section.index());
/**
 * DashboardLayout is customizable component for rendering {@link IDashboardLayout}.
 *
 * @alpha
 */
export function DashboardLayout({ layout, sectionKeyGetter = defaultSectionKeyGetter, sectionRenderer, sectionHeaderRenderer, itemKeyGetter, itemRenderer, widgetRenderer, gridRowRenderer, className, onMouseLeave, exportTransformer, renderMode = "view", focusObject, }) {
    const layoutRef = useRef(null);
    const { layoutItemPath, layoutItemSize } = useDashboardItemPathAndSize();
    const { layoutFacade, resizedItemPositions } = useMemo(() => {
        const exportMode = renderMode === "export" && layoutItemPath === undefined;
        let unifiedLayout = unifyDashboardLayoutItemHeights(layout, layoutItemSize, layoutItemPath);
        if (exportMode) {
            unifiedLayout =
                exportTransformer?.(unifiedLayout, focusObject) ??
                    layoutTransformer(unifiedLayout, focusObject);
        }
        const layoutFacade = DashboardLayoutFacade.for(unifiedLayout, layoutItemPath);
        const resizedItemPositions = exportMode
            ? []
            : getResizedItemPositions(layout, layoutFacade.raw(), [], layoutItemPath);
        return { layoutFacade, resizedItemPositions };
    }, [layout, renderMode, layoutItemPath, layoutItemSize, exportTransformer, focusObject]);
    const sectionRendererWrapped = useCallback((renderProps) => sectionRenderer ? (sectionRenderer({
        ...renderProps,
    })) : (_jsx(renderProps.DefaultSectionRenderer, { ...renderProps })), [sectionRenderer]);
    const getLayoutDimensions = useCallback(function () {
        return layoutRef?.current ? layoutRef.current.getBoundingClientRect() : emptyDOMRect;
    }, []);
    const widgetRendererWrapped = useCallback((renderProps) => {
        const isResizedByLayoutSizingStrategy = resizedItemPositions.some((position) => isEqual(position, [
            renderProps.item.section().index().sectionIndex,
            getItemIndex(renderProps.item.index()),
        ]));
        return widgetRenderer ? (widgetRenderer({
            ...renderProps,
            isResizedByLayoutSizingStrategy,
            getLayoutDimensions: getLayoutDimensions,
        })) : (_jsx(renderProps.DefaultWidgetRenderer, { ...renderProps, isResizedByLayoutSizingStrategy: isResizedByLayoutSizingStrategy, getLayoutDimensions: getLayoutDimensions }));
    }, [resizedItemPositions, widgetRenderer, getLayoutDimensions]);
    const screenSize = useScreenSize();
    const isNestedLayout = layoutItemPath !== undefined;
    const type = isNestedLayout ? "nested" : "root";
    const sectionIndex = useMemo(() => ({
        parent: layoutItemPath,
        sectionIndex: layout.sections.length,
    }), [layout, layoutItemPath]);
    // do not render the tailing section hotspot if there is only one section in the layout, and it has only initial placeholders in it
    const shouldRenderSectionHotspot = renderMode === "edit" &&
        (layout.sections.length > 1 ||
            (layout.sections.length === 1 &&
                layout.sections[0].items.some((i) => !isInitialPlaceholderWidget(i.widget)) &&
                !isNestedLayout));
    const slideStyles = useSlideSizeStyle(renderMode, type);
    const exportData = useDashboardExportData(renderMode, "loaded", type);
    return (_jsxs(GridLayoutElement, { type: type, layoutItemSize: layoutItemSize, className: cx({
            "gd-dashboards": !isNestedLayout,
        }, className), onMouseLeave: onMouseLeave, ref: layoutRef, exportStyles: slideStyles, exportData: exportData, children: [layoutFacade.sections().map((section) => {
                return (_jsx(DashboardLayoutSection, { section: section, sectionRenderer: sectionRendererWrapped, sectionHeaderRenderer: sectionHeaderRenderer, itemKeyGetter: itemKeyGetter, itemRenderer: itemRenderer, gridRowRenderer: gridRowRenderer, widgetRenderer: widgetRendererWrapped, renderMode: renderMode, getLayoutDimensions: getLayoutDimensions, parentLayoutItemSize: layoutItemSize, parentLayoutPath: layoutItemPath }, sectionKeyGetter({ section, screen: screenSize })));
            }), shouldRenderSectionHotspot ? (_jsx(GridLayoutElement, { type: "item", layoutItemSize: layoutItemSize, children: _jsx(SectionHotspot, { index: sectionIndex, targetPosition: "below", itemSize: layoutItemSize }) })) : null] }));
}
