// (C) 2025-2026 GoodData Corporation
import { bucketAttribute, idRef, insightBucket, insightProperties, insightVisualizationUrl, newAttribute, } from "@gooddata/sdk-model";
import { BucketNames } from "@gooddata/sdk-ui";
import { isConcreteViewportPreset, normalizeGeoLegendPosition } from "@gooddata/sdk-ui-geo/internal";
import { isGeoBasemapConfigEnabled, isGeoChartsViewportConfigEnabled, } from "../../../constants/featureFlags.js";
import { sanitizeGeoMapStyleOptions } from "../../../constants/geoMapStyle.js";
import { ANALYTICAL_ENVIRONMENT, DASHBOARDS_ENVIRONMENT } from "../../../constants/properties.js";
import { sdkModelPropMetas } from "../../../utils/embeddingCodeGenerator/insightToPropsConverter/convenience.js";
/**
 * Builds geo visualization configuration for both legacy and next-gen geo pushpin charts.
 *
 * @param params - Configuration parameters
 * @returns Complete geo chart configuration
 * @internal
 */
export function buildGeoVisualizationConfig({ options, supportedControls, colorMapping, environment, featureFlags, }) {
    const { config = {}, customVisualizationConfig = {}, a11yTitle } = options;
    const { center, zoom, legend, viewport = {}, ...restSupportedControls } = supportedControls;
    const { basemap: rawBasemap, tileset: legacyTileset, colorScheme: rawColorScheme, ...restSupportedControlsWithoutGeoStyle } = restSupportedControls;
    const { isInEditMode, isExportMode } = config;
    const isBasemapConfigEnabled = isGeoBasemapConfigEnabled(featureFlags);
    const sanitizedGeoMapStyle = sanitizeGeoMapStyleOptions({
        basemap: rawBasemap,
        legacyTileset,
        colorScheme: rawColorScheme,
    });
    const isViewportConfigEnabled = isGeoChartsViewportConfigEnabled(featureFlags);
    const isPresetViewportAreaSelected = isConcreteViewportPreset(viewport.area);
    const sanitizedViewport = isViewportConfigEnabled
        ? viewport
        : {
            ...viewport,
            area: viewport.area === "custom" ? "auto" : viewport.area,
            navigation: undefined,
        };
    // Preserve legacy center/zoom behavior when feature flag is off.
    // With viewport config enabled, center/zoom represent "custom" viewport and must not override presets.
    const shouldUseCenterAndZoom = !isViewportConfigEnabled || !isPresetViewportAreaSelected;
    const centerAndZoomProp = shouldUseCenterAndZoom
        ? {
            ...(center ? { center } : {}),
            ...(typeof zoom === "number" ? { zoom } : {}),
        }
        : {};
    const normalizedLegend = legend
        ? {
            ...legend,
            position: normalizeGeoLegendPosition(legend.position),
        }
        : undefined;
    // Build legend configuration
    let legendProp = normalizedLegend ? { legend: normalizedLegend } : {};
    if (environment === DASHBOARDS_ENVIRONMENT) {
        // In dashboards, use responsive legend with popup
        legendProp = {
            legend: {
                ...normalizedLegend,
                responsive: "autoPositionWithPopup",
            },
        };
    }
    // Build viewport configuration with frozen state during edit/export
    const viewportProp = {
        viewport: {
            ...sanitizedViewport,
            frozen: isInEditMode || isExportMode,
        },
    };
    // Determine cooperative gestures behavior
    const isKDInViewMode = environment !== ANALYTICAL_ENVIRONMENT && !isInEditMode;
    const cooperativeGestures = customVisualizationConfig?.cooperativeGestures === undefined
        ? isKDInViewMode
        : customVisualizationConfig.cooperativeGestures;
    const applyViewportNavigation = environment === DASHBOARDS_ENVIRONMENT
        ? true
        : environment === ANALYTICAL_ENVIRONMENT
            ? false
            : undefined;
    // Merge all configuration
    const geoConfig = {
        ...restSupportedControlsWithoutGeoStyle,
        ...config,
        ...centerAndZoomProp,
        ...legendProp,
        ...viewportProp,
        ...customVisualizationConfig,
        basemap: sanitizedGeoMapStyle.basemap,
        colorScheme: sanitizedGeoMapStyle.colorScheme,
        separators: config.separators,
        colorPalette: config.colorPalette,
        colorMapping,
        cooperativeGestures,
        a11yTitle,
        enableGeoBasemapConfig: isBasemapConfigEnabled,
        enableGeoChartA11yImprovements: featureFlags?.["enableGeoChartA11yImprovements"] ?? false,
        enableGeoChartsViewportConfig: isViewportConfigEnabled,
        applyViewportNavigation,
    };
    return geoConfig;
}
const supportedGeoConfigProperties = new Set([
    "center",
    "zoom",
    "cooperativeGestures",
    "legend",
    "limit",
    "mapStyle",
    "basemap",
    "colorScheme",
    "selectedSegmentItems",
    "separators",
    "viewport",
    "points",
    "showLabels",
]);
export function geoConfigFromInsight(insight, ctx) {
    const properties = insightProperties(insight);
    const controls = properties?.["controls"] ?? {};
    const normalizedLegend = controls.legend
        ? {
            ...controls.legend,
            position: normalizeGeoLegendPosition(controls.legend.position),
        }
        : undefined;
    const sanitizedGeoMapStyle = sanitizeGeoMapStyleOptions({
        basemap: controls.basemap,
        legacyTileset: controls.tileset,
        colorScheme: controls.colorScheme,
    });
    const withValuesFromContext = {
        ...controls,
        ...(normalizedLegend ? { legend: normalizedLegend } : {}),
        basemap: sanitizedGeoMapStyle.basemap,
        colorScheme: sanitizedGeoMapStyle.colorScheme,
        ...(ctx?.settings?.separators ? { separators: ctx?.settings?.separators } : {}),
    };
    return Object.fromEntries(Object.entries(withValuesFromContext).filter(([key, value]) => supportedGeoConfigProperties.has(key) &&
        !(value === null || value === undefined)));
}
export function geoInsightConversion(propName, bucketName) {
    return {
        propName,
        propType: sdkModelPropMetas.Attribute.Single,
        itemAccessor(insight, ctx) {
            return getLocationAttributeFromInsight(insight, ctx, bucketName);
        },
    };
}
function getLocationAttributeFromInsight(insight, ctx, bucketName) {
    if (bucketName === BucketNames.AREA) {
        const bucket = insightBucket(insight, bucketName);
        return bucket && bucketAttribute(bucket);
    }
    if (bucketName === BucketNames.LOCATION &&
        !ctx?.backend?.capabilities.supportsSeparateLatitudeLongitudeLabels) {
        const bucket = insightBucket(insight, bucketName);
        return bucket ? bucketAttribute(bucket) : undefined;
    }
    else if (
    // dont rely on Latitude being already in bucket, take both lat and long from properties
    (bucketName === BucketNames.LATITUDE || bucketName === BucketNames.LONGITUDE) &&
        ctx?.backend?.capabilities.supportsSeparateLatitudeLongitudeLabels) {
        const properties = insightProperties(insight);
        const controls = properties?.["controls"] ?? {};
        const identifier = controls[bucketName];
        const localId = bucketName === BucketNames.LATITUDE ? "latitude_df" : "longitude_df";
        return newAttribute(idRef(identifier, "displayForm"), (a) => a.localId(localId));
    }
    return undefined;
}
export function isGeoChart(insightDefinition) {
    const type = insightVisualizationUrl(insightDefinition).split(":")[1];
    return type === "pushpin";
}
//# sourceMappingURL=geoConfigBuilder.js.map