// (C) 2024-2026 GoodData Corporation
import { createSelector } from "@reduxjs/toolkit";
import { generateDateFilterLocalIdentifier } from "@gooddata/sdk-backend-base";
import { areObjRefsEqual, dashboardAttributeFilterItemLocalIdentifier, isAllDashboardMeasureValueFilter, isAllValuesDashboardAttributeFilter, isDashboardAttributeFilterItem, isDashboardCommonDateFilter, isDashboardDateFilter, isDashboardDateFilterWithDimension, isDashboardMeasureValueFilter, newAllTimeDashboardDateFilter, } from "@gooddata/sdk-model";
import { selectCrossFilteringItems, selectCrossFilteringItemsByTab } from "../drill/drillSelectors.js";
import { selectAttributeFilterConfigsOverrides, selectAttributeFilterConfigsOverridesByTab, } from "../tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
import { selectDateFilterConfigOverrides, selectDateFilterConfigOverridesByTab, } from "../tabs/dateFilterConfig/dateFilterConfigSelectors.js";
import { selectDateFilterConfigsOverrides, selectDateFilterConfigsOverridesByTab, } from "../tabs/dateFilterConfigs/dateFilterConfigsSelectors.js";
import { selectFilterContextFilters, selectFiltersByTab, } from "../tabs/filterContext/filterContextSelectors.js";
import { selectTabs } from "../tabs/tabsSelectors.js";
const commonDateFilter = newAllTimeDashboardDateFilter(undefined, generateDateFilterLocalIdentifier(0));
/**
 * @alpha
 */
export const selectDashboardFiltersWithoutCrossFiltering = createSelector(selectFilterContextFilters, selectCrossFilteringItems, (dashboardFilters, crossFilteringItems) => {
    const dashboardFiltersWithCommonDateFilter = dashboardFilters.some(isDashboardCommonDateFilter)
        ? dashboardFilters
        : [commonDateFilter, ...dashboardFilters];
    return removeCrossFilteringFilters(dashboardFiltersWithCommonDateFilter, crossFilteringItems);
});
/**
 * @alpha
 */
export const selectDashboardHiddenFilters = createSelector(selectDashboardFiltersWithoutCrossFiltering, selectDateFilterConfigOverrides, selectDateFilterConfigsOverrides, selectAttributeFilterConfigsOverrides, (dashboardFiltersWithoutCrossFiltering, commonDateFilterConfig, dateFilterWithDimensionConfigs, attributeFilterConfigs) => {
    return dashboardFiltersWithoutCrossFiltering.filter((filter) => isFilterContextItemHidden(filter, {
        commonDateFilterConfig,
        dateFilterWithDimensionConfigs,
        attributeFilterConfigs,
    }));
});
/**
 * @alpha
 */
export const selectDashboardLockedFilters = createSelector(selectDashboardFiltersWithoutCrossFiltering, selectDateFilterConfigOverrides, selectDateFilterConfigsOverrides, selectAttributeFilterConfigsOverrides, (dashboardFiltersWithoutCrossFiltering, commonDateFilterConfig, dateFilterWithDimensionConfigs, attributeFilterConfigs) => {
    return dashboardFiltersWithoutCrossFiltering.filter((filter) => isFilterContextItemLocked(filter, {
        commonDateFilterConfig,
        dateFilterWithDimensionConfigs,
        attributeFilterConfigs,
    }));
});
/**
 * @alpha
 */
export const selectAutomationAvailableDashboardFilters = createSelector(selectDashboardFiltersWithoutCrossFiltering, selectDateFilterConfigOverrides, selectDateFilterConfigsOverrides, selectAttributeFilterConfigsOverrides, (dashboardFiltersWithoutCrossFiltering, commonDateFilterConfig, dateFilterWithDimensionConfigs, attributeFilterConfigs) => {
    const withCommonDateFilter = dashboardFiltersWithoutCrossFiltering.some(isDashboardCommonDateFilter)
        ? dashboardFiltersWithoutCrossFiltering
        : [commonDateFilter, ...dashboardFiltersWithoutCrossFiltering];
    return removeHiddenFilters(withCommonDateFilter, {
        commonDateFilterConfig,
        dateFilterWithDimensionConfigs,
        attributeFilterConfigs,
    });
});
/**
 * @alpha
 */
export const selectAutomationDefaultSelectedFilters = createSelector(selectAutomationAvailableDashboardFilters, (availableDashboardFilters) => {
    return removeEmptyDashboardFilters(availableDashboardFilters);
});
/**
 * @alpha
 */
export const selectAutomationCommonDateFilterId = createSelector(selectAutomationAvailableDashboardFilters, (availableDashboardFilters) => {
    const dashboardCommonDateFilter = availableDashboardFilters.find(isDashboardCommonDateFilter);
    return dashboardCommonDateFilter?.dateFilter.localIdentifier;
});
//
// Utils
//
const removeCrossFilteringFilters = (filters, crossFilteringItems) => {
    const crossFilteringFilterLocalIdentifiers = crossFilteringItems.flatMap((item) => item.filterLocalIdentifiers);
    return filters.filter((filter) => {
        if (isDashboardAttributeFilterItem(filter)) {
            const localIdentifier = dashboardAttributeFilterItemLocalIdentifier(filter);
            if (localIdentifier) {
                return !crossFilteringFilterLocalIdentifiers.includes(localIdentifier);
            }
        }
        return true;
    });
};
export function removeEmptyDashboardFilters(filters = []) {
    return filters.filter((filter) => {
        if (isDashboardAttributeFilterItem(filter)) {
            return !isAllValuesDashboardAttributeFilter(filter);
        }
        if (isDashboardMeasureValueFilter(filter)) {
            return !isAllDashboardMeasureValueFilter(filter);
        }
        return true;
    });
}
function removeHiddenFilters(filters, filterConfigurations) {
    return filters.filter((filter) => {
        return !isFilterContextItemHidden(filter, filterConfigurations);
    });
}
export const isFilterContextItemHidden = (filter, filterConfigurations) => {
    const { dateFilterWithDimensionConfigs, attributeFilterConfigs, commonDateFilterConfig } = filterConfigurations;
    if (isDashboardAttributeFilterItem(filter)) {
        const attributeFilterLocalIdentifier = dashboardAttributeFilterItemLocalIdentifier(filter);
        const config = attributeFilterConfigs.find((attributeFilterConfig) => attributeFilterConfig.localIdentifier === attributeFilterLocalIdentifier);
        return config?.mode === "hidden";
    }
    else if (isDashboardDateFilter(filter)) {
        if (isDashboardCommonDateFilter(filter)) {
            return commonDateFilterConfig?.mode === "hidden";
        }
        else if (isDashboardDateFilterWithDimension(filter)) {
            const config = dateFilterWithDimensionConfigs.find((date) => areObjRefsEqual(date.dateDataSet, filter.dateFilter.dataSet));
            return config?.config.mode === "hidden";
        }
    }
    return false;
};
export const isFilterContextItemLocked = (filter, filterConfigurations) => {
    const { dateFilterWithDimensionConfigs, attributeFilterConfigs, commonDateFilterConfig } = filterConfigurations;
    if (isDashboardAttributeFilterItem(filter)) {
        const attributeFilterLocalIdentifier = dashboardAttributeFilterItemLocalIdentifier(filter);
        const config = attributeFilterConfigs.find((attributeFilterConfig) => attributeFilterConfig.localIdentifier === attributeFilterLocalIdentifier);
        return config?.mode === "readonly";
    }
    else if (isDashboardDateFilter(filter)) {
        if (isDashboardCommonDateFilter(filter)) {
            return commonDateFilterConfig?.mode === "readonly";
        }
        else if (isDashboardDateFilterWithDimension(filter)) {
            const config = dateFilterWithDimensionConfigs.find((date) => areObjRefsEqual(date.dateDataSet, filter.dateFilter.dataSet));
            return config?.config.mode === "readonly";
        }
    }
    return false;
};
//
// Per-tab automation filter selectors
//
/**
 * Returns automation-available filters structured per tab.
 * Each entry includes tab information and the filters applicable to that tab.
 * This selector is useful for whole dashboard automations when dashboard tabs are enabled.
 *
 * @alpha
 */
export const selectAutomationFiltersByTab = createSelector(selectTabs, selectFiltersByTab, selectDateFilterConfigOverridesByTab, selectDateFilterConfigsOverridesByTab, selectAttributeFilterConfigsOverridesByTab, selectCrossFilteringItemsByTab, (tabs, filtersByTab, dateFilterConfigByTab, dateFilterConfigsByTab, attributeFilterConfigsByTab, crossFilteringItemsByTab) => {
    if (!tabs || tabs.length === 0) {
        return [];
    }
    return tabs.map((tab) => {
        const tabId = tab.localIdentifier;
        const tabTitle = tab.title ?? "";
        const rawFilters = filtersByTab[tabId] ?? [];
        // Get cross-filtering items for this specific tab
        const tabCrossFilteringItems = crossFilteringItemsByTab[tabId] ?? [];
        // Remove cross-filtering filters for this tab
        const filtersWithoutCrossFiltering = removeCrossFilteringFilters(rawFilters, tabCrossFilteringItems);
        // Ensure common date filter exists
        const filtersWithCommonDate = filtersWithoutCrossFiltering.some(isDashboardCommonDateFilter)
            ? filtersWithoutCrossFiltering
            : [commonDateFilter, ...filtersWithoutCrossFiltering];
        // Get filter configs for this tab
        const commonDateFilterConfig = dateFilterConfigByTab[tabId];
        const dateFilterWithDimensionConfigs = dateFilterConfigsByTab[tabId] ?? [];
        const attributeFilterConfigs = attributeFilterConfigsByTab[tabId] ?? [];
        const filterConfigurations = {
            commonDateFilterConfig,
            dateFilterWithDimensionConfigs,
            attributeFilterConfigs,
        };
        // Get available filters (hidden removed)
        const availableFilters = removeHiddenFilters(filtersWithCommonDate, filterConfigurations);
        // Get locked filters
        const lockedFilters = filtersWithCommonDate.filter((filter) => isFilterContextItemLocked(filter, filterConfigurations));
        // Get hidden filters
        const hiddenFilters = filtersWithCommonDate.filter((filter) => isFilterContextItemHidden(filter, filterConfigurations));
        // Get default selected filters (noop "All" filters removed — attribute and MVF)
        const defaultSelectedFilters = removeEmptyDashboardFilters(availableFilters);
        return {
            tabId,
            tabTitle,
            availableFilters,
            defaultSelectedFilters,
            lockedFilters,
            hiddenFilters,
        };
    });
});
