// (C) 2019-2025 GoodData Corporation
import stringify from "json-stable-stringify";
import { uniqBy } from "lodash-es";
import { sanitizeDateFilterOption } from "./sanitization.js";
/**
 * Merges presets so that presets that are semantically unique are de-duplicated.
 */
const mergePresets = (projectPresets, dashboardPresets) => {
    const merged = [...(projectPresets || []), ...(dashboardPresets || [])].map(sanitizeDateFilterOption);
    return uniqBy(merged, stringify);
};
const addPresets = (dashboardConfig) => (projectConfig) => {
    if (!dashboardConfig.addPresets) {
        return projectConfig;
    }
    const absolutePresets = mergePresets(projectConfig?.absolutePresets ?? [], dashboardConfig.addPresets?.absolutePresets ?? []);
    const relativePresets = mergePresets(projectConfig?.relativePresets ?? [], dashboardConfig.addPresets?.relativePresets ?? []);
    return {
        ...projectConfig,
        ...(absolutePresets.length ? { absolutePresets } : null),
        ...(relativePresets.length ? { relativePresets } : null),
    };
};
const hideNonArrayOptionType = (key) => (dashboardConfig) => (projectConfig) => {
    const configKey = projectConfig[key];
    if (!configKey) {
        return projectConfig;
    }
    if (!configKey.visible || !dashboardConfig.hideOptions) {
        return projectConfig;
    }
    return dashboardConfig.hideOptions?.includes(configKey.localIdentifier)
        ? {
            ...projectConfig,
            [key]: {
                ...projectConfig[key],
                visible: false,
            },
        }
        : projectConfig;
};
const hideAllTime = hideNonArrayOptionType("allTime");
const hideEmptyValues = hideNonArrayOptionType("emptyValues");
const hideAbsoluteForm = hideNonArrayOptionType("absoluteForm");
const hideRelativeForm = hideNonArrayOptionType("relativeForm");
const shouldHideRelativePreset = (preset, dashboardConfig) => {
    const hideForGranularity = dashboardConfig.hideGranularities?.includes(preset.granularity);
    const hideForId = dashboardConfig.hideOptions?.includes(preset.localIdentifier);
    return hideForGranularity || hideForId || false;
};
const hideAbsolutePresets = (dashboardConfig) => (projectConfig) => {
    if (!projectConfig.absolutePresets?.length || !dashboardConfig.hideOptions) {
        return projectConfig;
    }
    const absolutePresets = projectConfig.absolutePresets.map((preset) => dashboardConfig.hideOptions?.includes(preset.localIdentifier)
        ? {
            ...preset,
            visible: false,
        }
        : preset);
    return {
        ...projectConfig,
        absolutePresets,
    };
};
const hideRelativePresets = (dashboardConfig) => (projectConfig) => {
    const canDashboardConfigHideRelativePreset = dashboardConfig.hideOptions || dashboardConfig.hideGranularities;
    if (!projectConfig.relativePresets?.length || !canDashboardConfigHideRelativePreset) {
        return projectConfig;
    }
    const relativePresets = projectConfig.relativePresets.map((preset) => shouldHideRelativePreset(preset, dashboardConfig)
        ? {
            ...preset,
            visible: false,
        }
        : preset);
    return {
        ...projectConfig,
        relativePresets,
    };
};
const hideRelativeFormGranularities = (dashboardConfig) => (projectConfig) => {
    if (!projectConfig.relativeForm?.visible || !dashboardConfig.hideGranularities) {
        return projectConfig;
    }
    const granularities = projectConfig.relativeForm.availableGranularities.filter((granularity) => !(dashboardConfig.hideGranularities?.includes(granularity) ?? false));
    const { relativeForm, ...projectConfigWithoutRelativeForm } = projectConfig;
    return granularities.length > 0
        ? {
            ...projectConfig,
            relativeForm: {
                ...relativeForm,
                availableGranularities: granularities,
            },
        }
        : projectConfigWithoutRelativeForm;
};
/**
 * Merges the date filter config with the dashboard-level overrides. The overrides may hide some presets
 * or add custom presets. This function addresses all that and returns the final merged Date Filter Config.
 *
 * @param config - date filter config
 * @param dashboardOverrides - dashboard-level overrides.
 */
export function mergeDateFilterConfigs(config, dashboardOverrides) {
    return [
        addPresets(dashboardOverrides),
        hideAllTime(dashboardOverrides),
        hideEmptyValues(dashboardOverrides),
        hideAbsoluteForm(dashboardOverrides),
        hideRelativeForm(dashboardOverrides),
        hideRelativeFormGranularities(dashboardOverrides),
        hideAbsolutePresets(dashboardOverrides),
        hideRelativePresets(dashboardOverrides),
    ].reduce((acc, fn) => fn(acc), config);
}
