import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
// (C) 2020-2026 GoodData Corporation
import { useCallback, useMemo } from "react";
import cx from "classnames";
import { max } from "lodash-es";
import { LRUCache } from "lru-cache";
import { isWidget, objRefToString, } from "@gooddata/sdk-model";
import { DashboardLayoutBuilder } from "../../_staging/dashboard/flexibleLayout/builder/layout.js";
import { serializeLayoutItemPath } from "../../_staging/layout/coordinates.js";
import { useDashboardSelector } from "../../model/react/DashboardStoreProvider.js";
import { selectFocusObject, selectIsExport } from "../../model/store/config/configSelectors.js";
import { selectInsightsMap } from "../../model/store/insights/insightsSelectors.js";
import { selectRenderMode } from "../../model/store/renderMode/renderModeSelectors.js";
import { selectLayout } from "../../model/store/tabs/layout/layoutSelectors.js";
import { useDashboardItemPathAndSize } from "../dashboard/components/DashboardItemPathAndSizeContext.js";
import { useScreenSize } from "../dashboard/components/DashboardScreenSizeContext.js";
import { useDashboardCustomizationsContext } from "../dashboardContexts/DashboardCustomizationsContext.js";
import { DefaultDashboardExportVariables } from "../export/DefaultDashboardExportVariables.js";
import { DashboardLayoutWidget } from "./DashboardLayoutWidget.js";
import { DashboardLayout } from "./DefaultDashboardLayoutRenderer/DashboardLayout.js";
import { renderModeAwareDashboardLayoutSectionHeaderRenderer } from "./DefaultDashboardLayoutRenderer/RenderModeAwareDashboardLayoutSectionHeaderRenderer.js";
import { renderModeAwareDashboardLayoutSectionRenderer } from "./DefaultDashboardLayoutRenderer/RenderModeAwareDashboardLayoutSectionRenderer.js";
import { getMemoizedWidgetSanitizer } from "./DefaultDashboardLayoutUtils.js";
import { EmptyDashboardLayout } from "./EmptyDashboardLayout.js";
import { EmptyDashboardNestedLayout } from "./EmptyDashboardNestedLayout.js";
/**
 * Get dashboard layout for exports.
 *  - Create new extra rows if current row has width of widgets greater than 12
 *
 * @internal
 * @param layout - dashboard layout to modify
 * @returns transformed layout
 */
function getDashboardLayoutForExport(layout) {
    const dashLayout = DashboardLayoutBuilder.for(layout);
    const layoutFacade = dashLayout.facade();
    const sections = layoutFacade.sections();
    const screenSplitSections = sections.map((section) => ({
        items: section.items().asGridRows("xl"),
        header: section.header(),
    }));
    dashLayout.removeSections();
    screenSplitSections.forEach((wrappedSection) => {
        wrappedSection.items.forEach((rowSection, index) => {
            // Also ensure that all items in a section have equal grid height - the max one.
            // This simulates non-export mode, where the flex-box stretches
            // all the items in a row to the equal height.
            // This is necessary as we have no control over the custom widgets heights.
            const sectionItemsGridHeights = rowSection.map((item) => item.size().xl.gridHeight);
            const maxGridHeight = max(sectionItemsGridHeights);
            dashLayout.createSection((section) => {
                rowSection.forEach((item) => {
                    if (index === 0) {
                        section.header(wrappedSection.header);
                    }
                    section.createItem({ ...item.size().xl, gridHeight: maxGridHeight }, (i) => i.widget(item.widget()));
                });
                return section;
            });
        });
    });
    return dashLayout.build();
}
const itemKeyGetter = (keyGetterProps) => {
    const widget = keyGetterProps.item.widget();
    if (isWidget(widget)) {
        return objRefToString(widget.ref);
    }
    return serializeLayoutItemPath(keyGetterProps.item.index());
};
/**
 * @alpha
 */
export function DefaultFlexibleDashboardLayout({ layout: providedLayout, onFiltersChange, onDrill, onError, dashboardItemClasses, }) {
    const selectedLayout = useDashboardSelector(selectLayout);
    const insights = useDashboardSelector(selectInsightsMap);
    const isExport = useDashboardSelector(selectIsExport);
    const renderMode = useDashboardSelector(selectRenderMode);
    const dashboardFocusObject = useDashboardSelector(selectFocusObject);
    const { existingExportTransformFn } = useDashboardCustomizationsContext();
    const screenSize = useScreenSize();
    const { layoutItemPath, layoutItemSize } = useDashboardItemPathAndSize();
    const layout = useMemo(() => ({
        ...(providedLayout ?? selectedLayout),
        ...(layoutItemSize ? { size: layoutItemSize[screenSize] } : {}),
    }), [providedLayout, selectedLayout, layoutItemSize, screenSize]);
    const isLayoutEmpty = !layout.sections.length;
    const getInsightByRef = useCallback((insightRef) => {
        return insights.get(insightRef);
    }, [insights]);
    const sanitizeWidgets = useMemo(() => {
        // keep the cache local so that it is cleared when the dashboard changes for example and this component is remounted
        const cache = new LRUCache({ max: 100 });
        return getMemoizedWidgetSanitizer(cache);
    }, []);
    const transformedLayout = useMemo(() => {
        if (isExport) {
            return getDashboardLayoutForExport(layout);
        }
        return DashboardLayoutBuilder.for(layout, layoutItemPath)
            .modifySections((section) => section.modifyItems(sanitizeWidgets(getInsightByRef)))
            .build();
    }, [isExport, layout, layoutItemPath, sanitizeWidgets, getInsightByRef]);
    const widgetRenderer = useCallback((renderProps) => {
        return (_jsx(DashboardLayoutWidget, { onError: onError, onDrill: onDrill, onFiltersChange: onFiltersChange, ...renderProps }));
    }, [onError, onDrill, onFiltersChange]);
    if (isLayoutEmpty) {
        if (providedLayout) {
            return _jsx(EmptyDashboardNestedLayout, {});
        }
        return _jsx(EmptyDashboardLayout, {});
    }
    return (_jsxs(_Fragment, { children: [!layoutItemPath || layoutItemPath.length === 0 ? (_jsx(DefaultDashboardExportVariables, { renderMode: renderMode })) : null, _jsx(DashboardLayout, { className: cx(dashboardItemClasses, {
                    "export-mode": isExport,
                    "export-slides-mode": renderMode === "export",
                }), layout: transformedLayout, parentLayoutItemSize: layoutItemSize, parentLayoutPath: layoutItemPath, exportTransformer: existingExportTransformFn, itemKeyGetter: itemKeyGetter, widgetRenderer: widgetRenderer, sectionRenderer: renderModeAwareDashboardLayoutSectionRenderer, sectionHeaderRenderer: renderModeAwareDashboardLayoutSectionHeaderRenderer, renderMode: renderMode, focusObject: dashboardFocusObject })
        ] }));
}
//# sourceMappingURL=DefaultFlexibleDashboardLayout.js.map