// (C) 2022-2026 GoodData Corporation
import { ClientFormatterFacade } from "@gooddata/number-formatter";
import { areObjRefsEqual, attributeAlias, isAttributeElementsByValue, isLocalIdRef, isMeasureGroupDescriptor, isNegativeAttributeFilter, isPositiveAttributeFilter, isRelativeDateFilter, measureAlias, measureIdentifier, measureTitle, } from "@gooddata/sdk-model";
import { AI_OPERATOR, AI_OPERATORS, getComparisonOperatorTitle, getRelativeOperatorTitle, } from "@gooddata/sdk-ui-ext";
import { DEFAULT_MEASURE_FORMAT } from "../constants.js";
import { isChangeOperator, isDifferenceOperator } from "./guards.js";
/**
 * @internal
 */
export function getMeasureFormat(measure, measureFormatMap = {}) {
    if (!measure) {
        return DEFAULT_MEASURE_FORMAT;
    }
    // custom format set in the bucket
    if (measure?.measure.format) {
        return measure.measure.format;
    }
    // measure format from the catalog
    const resolvedIdentifier = measureIdentifier(measure);
    return (resolvedIdentifier && measureFormatMap[resolvedIdentifier]) ?? DEFAULT_MEASURE_FORMAT;
}
/**
 * @internal
 */
export function getAttributeRelatedFilterInfo(attributes, alert, attr) {
    const attribute = attributes.find((a) => a.attribute.attribute.localIdentifier === attr?.attribute.localIdentifier);
    return {
        attribute,
        ...getAttributeRelatedFilter(attribute, alert),
    };
}
/**
 * @internal
 */
export function getMeasureTitle(measure) {
    return measure ? (measureAlias(measure) ?? measureTitle(measure)) : undefined;
}
/**
 * @internal
 */
export function getAttributeTitle(attribute) {
    return attribute ? attributeAlias(attribute) : undefined;
}
/**
 * @internal
 */
export function getOperatorTitle(intl, alert) {
    if (alert?.condition.type === "relative") {
        return getRelativeOperatorTitle(alert.condition.operator, alert.condition.measure.operator, intl);
    }
    if (alert?.condition.type === "comparison") {
        return getComparisonOperatorTitle(alert.condition.operator, intl);
    }
    return "";
}
/**
 * @internal
 */
export function getValueSuffix(alert) {
    if (isChangeOperator(alert)) {
        return "%";
    }
    if (isDifferenceOperator(alert)) {
        return undefined;
    }
    return undefined;
}
/**
 * @internal
 */
export function getAlertThreshold(alert) {
    if (alert?.condition?.type === "anomalyDetection") {
        return undefined;
    }
    if (alert?.condition?.type === "relative") {
        return alert.condition.threshold;
    }
    return alert?.condition?.right;
}
/**
 * @internal
 */
export function getAlertMeasure(measures, alert) {
    const condition = alert?.condition;
    if (condition?.type === "anomalyDetection") {
        return measures.find((m) => m.measure.measure.localIdentifier === condition.measure.id);
    }
    if (condition?.type === "relative") {
        return (measures.find((m) => m.measure.measure.localIdentifier === condition.measure.left.id) ??
            measures.find((m) => m.measure.measure.localIdentifier === condition.measure.right.id));
    }
    return measures.find((m) => m.measure.measure.localIdentifier === condition?.left.id);
}
/**
 * @internal
 */
export function getAlertMeasureFormat(alert) {
    const condition = alert?.condition;
    if (condition?.type === "anomalyDetection") {
        return condition.measure.format ?? DEFAULT_MEASURE_FORMAT;
    }
    if (condition?.type === "relative") {
        return condition.measure.left.format ?? condition.measure.right.format ?? DEFAULT_MEASURE_FORMAT;
    }
    return condition?.left.format ?? DEFAULT_MEASURE_FORMAT;
}
/**
 * @internal
 */
export function getAlertComparison(measure, alert) {
    const condition = alert?.condition;
    if (measure && condition?.type === "relative") {
        return (measure.comparators.find((c) => c.measure.measure.localIdentifier === condition.measure.left.id) ??
            measure.comparators.find((c) => c.measure.measure.localIdentifier === condition.measure.right.id));
    }
    return undefined;
}
/**
 * @internal
 */
export function getAlertAttribute(attributes, alert) {
    const attr = alert?.alert?.execution.attributes[0];
    if (attr?.attribute) {
        const { attribute, filterValue } = getAttributeRelatedFilterInfo(attributes, alert, attr);
        return [attribute, filterValue];
    }
    return [undefined, undefined];
}
/**
 * @internal
 */
export function getAlertFilters(alert) {
    const localFilters = alert?.metadata?.filters ?? [];
    const filters = alert?.alert?.execution?.filters ?? [];
    const attrs = (alert?.alert?.execution.attributes ?? []).map((a) => a.attribute.localIdentifier);
    return filters.filter((f) => {
        const sliceLocalId = getSliceFilterDisplayFormLocalId(f);
        if (sliceLocalId) {
            return !attrs.includes(sliceLocalId);
        }
        if (isRelativeDateFilter(f)) {
            return !localFilters.includes(f.relativeDateFilter.localIdentifier ?? "");
        }
        return true;
    });
}
/**
 * @internal
 */
export function getAlertCompareOperator(alert) {
    if (alert?.condition.type === "comparison") {
        return alert.condition.operator;
    }
    return undefined;
}
/**
 * @internal
 */
export function getAlertRelativeOperator(alert) {
    if (alert?.condition.type === "relative") {
        return [alert.condition.operator, alert.condition.measure.operator];
    }
    return undefined;
}
/**
 * @internal
 */
export function getAlertAiOperator(alert) {
    if (alert?.condition.type === "anomalyDetection") {
        return `${AI_OPERATOR}.${AI_OPERATORS.ANOMALY_DETECTION}`;
    }
    return undefined;
}
/**
 * @internal
 */
export function getAlertSensitivity(alert) {
    if (alert?.condition.type === "anomalyDetection") {
        return alert.condition.sensitivity;
    }
    return undefined;
}
/**
 * @internal
 */
export function getAlertGranularity(alert) {
    if (alert?.condition.type === "anomalyDetection") {
        return alert.condition.granularity;
    }
    return undefined;
}
/**
 * @internal
 */
export function getSelectedCatalogAttribute(catalogAttributes, catalogDateDatasets, attribute) {
    const catalogDateAttributes = catalogDateDatasets.flatMap((dateDataset) => dateDataset.dateAttributes);
    const item = getCatalogAttribute([...catalogAttributes, ...catalogDateAttributes], attribute.attribute);
    if (!item) {
        return undefined;
    }
    return {
        ...item.attribute,
        title: getAttributeTitle(attribute.attribute) ?? item.attribute?.title,
    };
}
/**
 * @internal
 */
export function getSelectedCatalogAttributeValue(attribute, getAttributeValue, selectedValue) {
    if (!attribute) {
        return undefined;
    }
    const values = getAttributeValue(attribute);
    return (values.find((value) => value.name === selectedValue) ??
        values.find((value) => value.value === selectedValue));
}
/**
 * @internal
 */
export function getCatalogAttribute(attributes, attribute) {
    return attributes.find((attr) => {
        return (areObjRefsEqual(attr.attribute.ref, attribute.attribute.displayForm) ||
            attr.attribute.displayForms.some((displayForm) => areObjRefsEqual(displayForm.ref, attribute.attribute.displayForm)));
    });
}
export function getFiltersAttribute(datasetsWithGranularity, dataset) {
    const found = datasetsWithGranularity.find(([ref]) => areObjRefsEqual(ref, dataset.dataSet.ref));
    if (found) {
        const attribute = dataset.dateAttributes.find((a) => a.granularity === found[1]);
        if (attribute) {
            return [attribute];
        }
    }
    return [];
}
//utils
function getAttributeRelatedFilter(attr, alert) {
    const filter = alert?.alert?.execution.filters.filter((f) => {
        return getSliceFilterDisplayFormLocalId(f) === attr?.attribute.attribute.localIdentifier;
    })[0];
    if (isPositiveAttributeFilter(filter) && isAttributeElementsByValue(filter.positiveAttributeFilter.in)) {
        return {
            filterDefinition: filter,
            filterValue: filter.positiveAttributeFilter.in.values[0],
        };
    }
    if (isNegativeAttributeFilter(filter) &&
        isAttributeElementsByValue(filter.negativeAttributeFilter.notIn)) {
        return {
            filterDefinition: filter,
            filterValue: undefined,
        };
    }
    return {
        filterDefinition: undefined,
        filterValue: undefined,
    };
}
function getSliceFilterDisplayFormLocalId(filter) {
    // "For attribute" alert slice filters are selection-based filters using localIdRef display forms.
    if (isPositiveAttributeFilter(filter) && isLocalIdRef(filter.positiveAttributeFilter.displayForm)) {
        return filter.positiveAttributeFilter.displayForm.localIdentifier;
    }
    if (isNegativeAttributeFilter(filter) && isLocalIdRef(filter.negativeAttributeFilter.displayForm)) {
        return filter.negativeAttributeFilter.displayForm.localIdentifier;
    }
    return undefined;
}
/**
 * Prepare a mapping between measure identifiers and measure formats.
 * Obtain the information from the execution result measure group dimension headers.
 * @internal
 */
export function getMeasureFormatsFromExecution(execResult) {
    const dimensions = execResult?.dimensions ?? [];
    for (const dim of dimensions) {
        const measureGroup = dim.headers.find(isMeasureGroupDescriptor);
        if (measureGroup) {
            return measureGroup.measureGroupHeader.items.reduce((acc, item) => {
                const identifier = item.measureHeaderItem?.identifier;
                const format = item.measureHeaderItem?.format;
                if (identifier) {
                    acc[identifier] = format;
                }
                return acc;
            }, {});
        }
    }
    return {};
}
export function getDescription(intl, measures, alert, separators) {
    const selectedMeasure = getAlertMeasure(measures, alert?.alert);
    const name = selectedMeasure ? (getMeasureTitle(selectedMeasure.measure) ?? "") : "";
    const valueSuffix = getValueSuffix(alert?.alert) ?? "";
    const title = getOperatorTitle(intl, alert?.alert).toLowerCase();
    const threshold = getAlertThreshold(alert?.alert);
    const formattedValue = formatValue(threshold, getMeasureFormat(selectedMeasure?.measure), separators);
    const description = [name, title, `${formattedValue}${valueSuffix}`].filter(Boolean).join(" ");
    return description[0].toUpperCase() + description.slice(1);
}
export function getSubtitle(intl, widgetName, alert, separators) {
    const valueSuffix = getValueSuffix(alert.alert) ?? "";
    const threshold = getAlertThreshold(alert.alert);
    const formattedValue = formatValue(threshold, getAlertMeasureFormat(alert.alert), separators);
    return [`${getOperatorTitle(intl, alert.alert)} ${formattedValue}${valueSuffix}`, widgetName]
        .filter(Boolean)
        .join(" • ");
}
function formatValue(value, format, separators) {
    try {
        const convertedValue = ClientFormatterFacade.convertValue(value);
        if (convertedValue !== null && isNaN(convertedValue)) {
            return "";
        }
        const { formattedValue } = ClientFormatterFacade.formatValue(convertedValue, format, separators);
        return formattedValue;
    }
    catch {
        return String(value);
    }
}
//# sourceMappingURL=getters.js.map