import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
// (C) 2020-2026 GoodData Corporation
import { useCallback, useMemo, useRef, useState } from "react";
import cx from "classnames";
import { v4 as uuid } from "uuid";
import { isCrossFiltering, isDrillToAttributeUrl, isDrillToCustomUrl, isDrillToDashboard, isDrillToInsight, isKeyDriveAnalysis, } from "@gooddata/sdk-model";
import { useAutoupdateRef } from "@gooddata/sdk-ui";
import { OverlayController, OverlayControllerProvider } from "@gooddata/sdk-ui-kit";
import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
import { selectBackendCapabilities } from "../../../model/store/backendCapabilities/backendCapabilitiesSelectors.js";
import { selectDisableDefaultDrills, selectLocale } from "../../../model/store/config/configSelectors.js";
import { selectDashboardFiltersWithoutCrossFiltering } from "../../../model/store/filtering/dashboardFilterSelectors.js";
import { selectWidgetDrills } from "../../../model/store/tabs/layout/layoutSelectors.js";
import { isDrillDownDefinition, } from "../../../types.js";
import { DASHBOARD_DRILL_MENU_Z_INDEX } from "../../constants/zIndex.js";
import { IntlWrapper } from "../../localization/IntlWrapper.js";
import { useDrills } from "../hooks/useDrills.js";
import { filterDrillFromAttributeByPriority } from "../utils/drillDownUtils.js";
import { DrillSelectDropdown } from "./DrillSelectDropdown.js";
/**
 * @internal
 */
export function WithDrillSelect({ widgetRef, children, insight, returnFocusToInsight, onDrillStart, onDrillDownSuccess, onDrillToInsightSuccess, onDrillToDashboardSuccess, onDrillToAttributeUrlSuccess, onDrillToCustomUrlSuccess, onKeyDriverAnalysisSuccess, onError, }) {
    const { current: drillPickerId } = useRef(uuid());
    const [dropdownProps, setDropdownProps] = useState(null);
    const [isOpen, setIsOpen] = useState(true);
    const locale = useDashboardSelector(selectLocale);
    const disableDefaultDrills = useDashboardSelector(selectDisableDefaultDrills); // TODO: maybe remove?
    const filters = useDashboardSelector(selectDashboardFiltersWithoutCrossFiltering);
    const configuredDrills = useDashboardSelector(selectWidgetDrills(widgetRef));
    const { supportsAttributeHierarchies } = useDashboardSelector(selectBackendCapabilities);
    const drills = useDrills({
        onDrill: onDrillStart,
        onDrillSuccess: (s) => {
            if (disableDefaultDrills || s.payload.drillEvent.drillDefinitions.length === 0) {
                return;
            }
            const drillDefinitions = s.payload.drillEvent.drillDefinitions;
            const drillEvent = s.payload.drillEvent;
            const context = s.payload.drillContext;
            const validDrillDefinitions = supportsAttributeHierarchies
                ? drillDefinitions
                : filterDrillFromAttributeByPriority(drillDefinitions, configuredDrills);
            const type = getDrillDefinitionType(validDrillDefinitions);
            if (type === "single") {
                onSelect(validDrillDefinitions[0], undefined, drillEvent, s.correlationId, context);
            }
            else if (type === "multiple") {
                setDropdownProps({
                    drillDefinitions: validDrillDefinitions,
                    drillEvent: drillEvent,
                    drillContext: context,
                    correlationId: s.correlationId,
                });
                setIsOpen(true);
            }
        },
        onDrillDownSuccess,
        onDrillToInsightSuccess,
        onKeyDriverAnalysisSuccess,
        onDrillToDashboardSuccess,
        onDrillToAttributeUrlSuccess,
        onDrillToCustomUrlSuccess,
        onError: (e) => onError?.(e.payload.error),
    });
    const handleClose = useCallback(() => {
        setIsOpen(false);
    }, []);
    const handleCloseReturnFocus = useCallback(() => {
        returnFocusToInsight?.();
        handleClose();
    }, [handleClose, returnFocusToInsight]);
    const onSelectDepsRef = useAutoupdateRef({
        drills,
        dropdownProps: { correlationId: dropdownProps?.correlationId, drillEvent: dropdownProps?.drillEvent },
        insight,
        handleClose,
    });
    const onSelect = useCallback((drillDefinition, context, drillEvent, correlationId, drillContext) => {
        const { drills, dropdownProps, insight, handleClose } = onSelectDepsRef.current;
        const effectiveDrillEvent = drillEvent ?? dropdownProps?.drillEvent;
        const effectiveCorrelationId = correlationId ?? dropdownProps?.correlationId;
        const effectiveInsight = drillContext?.insight ?? insight;
        if (!effectiveDrillEvent) {
            return;
        }
        const isNavigatingByKeyboard = document.querySelector(":focus-visible") !== null;
        handleClose();
        if (isDrillDownDefinition(drillDefinition)) {
            drills.drillDown.run(effectiveInsight, drillDefinition, effectiveDrillEvent, effectiveCorrelationId);
            return;
        }
        if (isDrillToInsight(drillDefinition)) {
            drills.drillToInsight.run(drillDefinition, effectiveDrillEvent, effectiveCorrelationId);
            return;
        }
        if (isDrillToDashboard(drillDefinition)) {
            drills.drillToDashboard.run(drillDefinition, effectiveDrillEvent, effectiveCorrelationId);
            return;
        }
        if (isDrillToAttributeUrl(drillDefinition)) {
            drills.drillToAttributeUrl.run(drillDefinition, effectiveDrillEvent, effectiveCorrelationId);
            return;
        }
        if (isDrillToCustomUrl(drillDefinition)) {
            drills.drillToCustomUrl.run(drillDefinition, effectiveDrillEvent, effectiveCorrelationId);
            return;
        }
        if (isCrossFiltering(drillDefinition)) {
            drills.crossFiltering.run(insight, drillDefinition, effectiveDrillEvent, effectiveCorrelationId);
            if (!returnFocusToInsight) {
                return;
            }
            // We need to wait a bit so the chart reloads after the filter changes
            window.setTimeout(() => {
                returnFocusToInsight(isNavigatingByKeyboard);
            }, 150);
            return;
        }
        if (isKeyDriveAnalysis(drillDefinition)) {
            drills.keyDriverAnalysis.run(drillDefinition, effectiveDrillEvent, filters, context, effectiveCorrelationId);
        }
    }, [onSelectDepsRef, returnFocusToInsight, filters]);
    const dropDownAnchorClass = `s-drill-picker-${drillPickerId}`;
    const overlayController = useMemo(() => {
        return OverlayController.getInstance(DASHBOARD_DRILL_MENU_Z_INDEX);
    }, []);
    const drillDownDropdown = dropdownProps ? (_jsx(IntlWrapper, { locale: locale, children: _jsx(OverlayControllerProvider, { overlayController: overlayController, children: _jsx(DrillSelectDropdown, { ...dropdownProps, dropDownAnchorClass: dropDownAnchorClass, isOpen: isOpen, onClose: handleClose, onCloseReturnFocus: handleCloseReturnFocus, onSelect: onSelect }) }) })) : null;
    return (_jsxs("div", { className: cx("gd-drill-modal-wrapper-mask", dropDownAnchorClass), children: [children({ onDrill: drills.drill.run }), drillDownDropdown] }));
}
function getDrillDefinitionType(validDrillDefinitions) {
    if (validDrillDefinitions.length === 1) {
        const firstDrillDefinition = validDrillDefinitions[0];
        //NOTE: Key drive analysis has always items to choose
        if (firstDrillDefinition.type === "keyDriveAnalysis") {
            return "multiple";
        }
        return "single";
    }
    else if (validDrillDefinitions.length > 1) {
        return "multiple";
    }
    else {
        return "none";
    }
}
