// (C) 2019-2026 GoodData Corporation
import { useCallback, useEffect, useMemo, useState } from "react";
import { isEqual } from "lodash-es";
import { useIntl } from "react-intl";
import { isAutomationExternalUserRecipient, isAutomationUnknownUserRecipient, isAutomationUserRecipient, } from "@gooddata/sdk-model";
import { fillMissingTitles } from "@gooddata/sdk-ui";
import { convertCurrentUserToAutomationRecipient, convertCurrentUserToWorkspaceUser, convertExternalRecipientToAutomationRecipient, } from "../../../../_staging/automation/index.js";
import { useDashboardSelector } from "../../../../model/react/DashboardStoreProvider.js";
import { selectCatalogAttributes, selectCatalogDateDatasets, } from "../../../../model/store/catalog/catalogSelectors.js";
import { selectEnableAlertAttributes, selectEnableAlertOncePerInterval, selectEnableComparisonInAlerting, selectEnableExternalRecipients, selectLocale, selectSeparators, selectSettings, selectTimezone, selectWeekStart, } from "../../../../model/store/config/configSelectors.js";
import { selectEntitlementMinimumRecurrenceMinutes } from "../../../../model/store/entitlements/entitlementsSelectors.js";
import { selectExecutionResultByRef } from "../../../../model/store/executionResults/executionResultsSelectors.js";
import { selectAutomationCommonDateFilterId, selectDashboardHiddenFilters, } from "../../../../model/store/filtering/dashboardFilterSelectors.js";
import { selectDashboardDescriptor, selectDashboardId } from "../../../../model/store/meta/metaSelectors.js";
import { selectWidgetLocalIdToTabIdMap } from "../../../../model/store/tabs/layout/layoutSelectors.js";
import { selectCurrentUser } from "../../../../model/store/user/userSelectors.js";
import { selectUsers } from "../../../../model/store/users/usersSelectors.js";
import { getAppliedWidgetFilters, getVisibleFiltersByFilters, resolveMvfDimensionalityLocalRefs, } from "../../../automationFilters/utils.js";
import { isEmail } from "../../../scheduledEmail/utils/validate.js";
import { createDefaultAlert } from "../utils/convertors.js";
import { getAlertAiOperator, getAlertAttribute, getAlertCompareOperator, getAlertComparison, getAlertGranularity, getAlertMeasure, getAlertRelativeOperator, getAlertSensitivity, getMeasureFormatsFromExecution, } from "../utils/getters.js";
import { isAlertValueDefined } from "../utils/guards.js";
import { getSupportedInsightAttributesByInsight, getSupportedInsightMeasuresByInsight, } from "../utils/items.js";
import { transformAlertByAnomalyDetection, transformAlertByAttribute, transformAlertByComparisonOperator, transformAlertByDestination, transformAlertByGranularity, transformAlertByMetric, transformAlertByRelativeOperator, transformAlertBySensitivity, transformAlertByValue, } from "../utils/transformation.js";
import { useAlertValidation } from "./useAlertValidation.js";
import { useAttributeValuesFromExecResults } from "./useAttributeValuesFromExecResults.js";
import { useThresholdValue } from "./useThresholdValue.js";
const DEFAULT_MIN_RECURRENCE_MINUTES = "60";
export function useEditAlert({ alertToEdit, notificationChannels, insight, widget, editedAutomationFilters, maxAutomationsRecipients, setEditedAutomationFilters, availableFiltersAsVisibleFilters, filtersForNewAutomation, externalRecipientOverride, }) {
    const intl = useIntl();
    // Selectors
    const locale = useDashboardSelector(selectLocale);
    const canManageComparison = useDashboardSelector(selectEnableComparisonInAlerting);
    const catalogDateDatasets = useDashboardSelector(selectCatalogDateDatasets);
    const execResult = useDashboardSelector(selectExecutionResultByRef(widget?.ref));
    const catalogAttributes = useDashboardSelector(selectCatalogAttributes);
    const currentUser = useDashboardSelector(selectCurrentUser);
    const users = useDashboardSelector(selectUsers);
    const enabledExternalRecipients = useDashboardSelector(selectEnableExternalRecipients);
    const descriptor = useDashboardSelector(selectDashboardDescriptor);
    const settings = useDashboardSelector(selectSettings);
    const canManageAttributes = useDashboardSelector(selectEnableAlertAttributes);
    const dashboardId = useDashboardSelector(selectDashboardId);
    const separators = useDashboardSelector(selectSeparators);
    const dashboardHiddenFilters = useDashboardSelector(selectDashboardHiddenFilters);
    const enableAlertOncePerInterval = useDashboardSelector(selectEnableAlertOncePerInterval);
    const commonDateFilterId = useDashboardSelector(selectAutomationCommonDateFilterId);
    const weekStart = useDashboardSelector(selectWeekStart);
    const timezone = useDashboardSelector(selectTimezone);
    const minimumRecurrenceMinutesEntitlement = useDashboardSelector(selectEntitlementMinimumRecurrenceMinutes);
    const allowHourlyRecurrence = parseInt(minimumRecurrenceMinutesEntitlement?.value ?? DEFAULT_MIN_RECURRENCE_MINUTES, 10) === 60;
    const widgetTabMap = useDashboardSelector(selectWidgetLocalIdToTabIdMap);
    // Determine target tab ID if widget is present
    const targetTabIdentifier = widget?.localIdentifier ? widgetTabMap[widget.localIdentifier] : undefined;
    // Computed values
    const isNewAlert = !alertToEdit;
    const [effectiveInsight, setEffectiveInsight] = useState(insight);
    useEffect(() => {
        if (insight) {
            void fillMissingTitles(insight, locale, 9999).then(setEffectiveInsight);
        }
    }, [insight, locale]);
    const measureFormatMap = useMemo(() => {
        return getMeasureFormatsFromExecution(execResult?.executionResult);
    }, [execResult?.executionResult]);
    const supportedMeasures = useMemo(() => getSupportedInsightMeasuresByInsight(effectiveInsight, catalogDateDatasets, canManageComparison), [effectiveInsight, catalogDateDatasets, canManageComparison]);
    const supportedAttributes = useMemo(() => getSupportedInsightAttributesByInsight(insight, catalogDateDatasets), [insight, catalogDateDatasets]);
    const { isResultLoading, getAttributeValues, getMetricValue } = useAttributeValuesFromExecResults(execResult);
    // Default values
    const defaultMeasure = supportedMeasures[0];
    const defaultUser = convertCurrentUserToWorkspaceUser(users ?? [], currentUser);
    const defaultRecipient = externalRecipientOverride
        ? convertExternalRecipientToAutomationRecipient(externalRecipientOverride)
        : convertCurrentUserToAutomationRecipient(users ?? [], currentUser);
    const defaultNotificationChannelId = notificationChannels[0]?.id;
    // Local state
    const [warningMessage, setWarningMessage] = useState(undefined);
    const [isTitleValid, setIsTitleValid] = useState(true);
    const [triggerIntervalDirty, setTriggerIntervalDirty] = useState(false);
    const resolvedAlertToEdit = (() => {
        if (!alertToEdit) {
            return undefined;
        }
        const filters = alertToEdit.alert?.execution?.filters;
        if (!alertToEdit.alert || !filters?.length || !insight) {
            return alertToEdit;
        }
        const resolvedFilters = resolveMvfDimensionalityLocalRefs(filters, insight);
        if (resolvedFilters === filters) {
            return alertToEdit;
        }
        return {
            ...alertToEdit,
            alert: {
                ...alertToEdit.alert,
                execution: {
                    ...alertToEdit.alert.execution,
                    filters: resolvedFilters,
                },
            },
        };
    })();
    const [editedAutomation, setEditedAutomation] = useState(resolvedAlertToEdit ??
        createDefaultAlert(getAppliedWidgetFilters(editedAutomationFilters ?? [], dashboardHiddenFilters, widget, insight, commonDateFilterId, true), supportedMeasures, defaultMeasure, defaultNotificationChannelId, defaultRecipient, measureFormatMap, undefined, descriptor.evaluationFrequency
            ? {
                cron: descriptor.evaluationFrequency,
                timezone: settings.alertDefault?.defaultTimezone,
            }
            : undefined, getVisibleFiltersByFilters(editedAutomationFilters, availableFiltersAsVisibleFilters, true), widget?.localIdentifier, dashboardId, widget?.title, targetTabIdentifier));
    const [originalAutomation] = useState(editedAutomation);
    //
    // Selected values
    //
    const selectedMeasure = getAlertMeasure(supportedMeasures, editedAutomation?.alert);
    const selectedComparisonOperator = getAlertCompareOperator(editedAutomation?.alert);
    const selectedRelativeOperator = getAlertRelativeOperator(editedAutomation?.alert);
    const selectedAiOperator = getAlertAiOperator(editedAutomation?.alert);
    const selectedComparator = getAlertComparison(selectedMeasure, editedAutomation?.alert);
    const selectedSensitivity = getAlertSensitivity(editedAutomation?.alert);
    const selectedGranularity = getAlertGranularity(editedAutomation?.alert);
    const [selectedAttribute, selectedValue] = getAlertAttribute(supportedAttributes, editedAutomation);
    const selectedNotificationChannel = notificationChannels.find((channel) => channel.id === editedAutomation?.notificationChannel);
    const allowExternalRecipients = selectedNotificationChannel?.allowedRecipients === "external" && enabledExternalRecipients;
    const allowOnlyLoggedUserRecipients = selectedNotificationChannel?.allowedRecipients === "creator";
    const { isValid: isOriginalAutomationValid, invalidityReason } = useAlertValidation(originalAutomation);
    const isParentValid = invalidityReason !== "missingWidget";
    //
    // Handlers
    //
    const onTitleChange = (value, isValid) => {
        setIsTitleValid(isValid);
        setEditedAutomation((s) => (s ? { ...s, title: value } : undefined));
    };
    const onMeasureChange = useCallback((measure) => {
        setEditedAutomation((alert) => alert
            ? transformAlertByMetric(supportedMeasures, alert, measure, measureFormatMap, weekStart, timezone)
            : undefined);
    }, [measureFormatMap, supportedMeasures, weekStart, timezone]);
    const onAttributeChange = useCallback((attribute, value) => {
        setEditedAutomation((alert) => alert
            ? transformAlertByAttribute(supportedAttributes, alert, attribute, value)
            : undefined);
    }, [supportedAttributes]);
    const onValueChange = useCallback((value) => {
        setEditedAutomation((alert) => alert ? transformAlertByValue(alert, value) : undefined);
    }, []);
    const onComparisonOperatorChange = useCallback((measure, comparisonOperator) => {
        setEditedAutomation((alert) => alert
            ? transformAlertByComparisonOperator(supportedMeasures, alert, measure, comparisonOperator)
            : undefined);
    }, [supportedMeasures]);
    const onRelativeOperatorChange = useCallback((measure, relativeOperator, arithmeticOperator) => {
        setEditedAutomation((alert) => alert
            ? transformAlertByRelativeOperator(supportedMeasures, alert, measure, relativeOperator, arithmeticOperator, measureFormatMap)
            : undefined);
    }, [measureFormatMap, supportedMeasures]);
    const onAnomalyDetectionChange = useCallback((measure) => {
        setTriggerIntervalDirty(false);
        setEditedAutomation((alert) => transformAlertByAnomalyDetection(supportedMeasures, alert, measure, weekStart, timezone, enableAlertOncePerInterval));
    }, [supportedMeasures, weekStart, timezone, enableAlertOncePerInterval]);
    const onComparisonTypeChange = useCallback((measure, relativeOperator, comparisonType) => {
        if (!measure || !relativeOperator || !relativeOperator) {
            return;
        }
        const [relativeOperatorValue, arithmeticOperator] = relativeOperator;
        setEditedAutomation((alert) => alert
            ? transformAlertByRelativeOperator(supportedMeasures, alert, measure, relativeOperatorValue, arithmeticOperator, measureFormatMap, comparisonType)
            : undefined);
    }, [measureFormatMap, supportedMeasures]);
    const onSensitivityChange = useCallback((sensitivity) => {
        setEditedAutomation((alert) => transformAlertBySensitivity(alert, sensitivity));
    }, []);
    const onTriggerIntervalChange = useCallback((triggerInterval, dirty = true) => {
        setTriggerIntervalDirty(dirty);
        setEditedAutomation((s) => s
            ? {
                ...s,
                alert: { ...s.alert, trigger: { ...s.alert.trigger, interval: triggerInterval } },
            }
            : undefined);
    }, []);
    const onGranularityChange = useCallback((measure, granularity) => {
        if (!measure) {
            return;
        }
        setEditedAutomation((alert) => transformAlertByGranularity(supportedMeasures, alert, measure, granularity, weekStart));
        if (!triggerIntervalDirty) {
            onTriggerIntervalChange(granularity === "HOUR" ? "DAY" : granularity, false);
        }
    }, [onTriggerIntervalChange, supportedMeasures, triggerIntervalDirty, weekStart]);
    const onDestinationChange = useCallback((destinationId) => {
        const previousDestination = notificationChannels.find((channel) => alertToEdit?.notificationChannel === channel.id);
        const selectedDestination = notificationChannels.find((channel) => destinationId === channel.id);
        /**
         * When allowed recipients are changed from "ALL" to "CREATOR", show warning message
         */
        const showWarningMessage = selectedDestination?.allowedRecipients === "creator" &&
            previousDestination?.allowedRecipients !== "creator";
        setWarningMessage(showWarningMessage
            ? intl.formatMessage({ id: "insightAlert.config.warning.destination" })
            : undefined);
        /**
         * Reset recipients when new notification channel only allows the author/creator
         */
        const updatedRecipients = selectedDestination?.allowedRecipients === "creator"
            ? [convertCurrentUserToAutomationRecipient(users ?? [], currentUser)]
            : undefined;
        setEditedAutomation((alert) => alert
            ? transformAlertByDestination(alert, destinationId, updatedRecipients)
            : undefined);
    }, [alertToEdit?.notificationChannel, currentUser, notificationChannels, intl, users]);
    const onTriggerModeChange = useCallback((triggerMode) => {
        setEditedAutomation((s) => s
            ? {
                ...s,
                alert: { ...s.alert, trigger: { ...s.alert.trigger, mode: triggerMode } },
            }
            : undefined);
    }, []);
    const onRecipientsChange = useCallback((updatedRecipients) => {
        setEditedAutomation((s) => s
            ? {
                ...s,
                recipients: updatedRecipients,
            }
            : undefined);
    }, []);
    const onFiltersChange = useCallback((filters) => {
        setEditedAutomationFilters(filters);
        setEditedAutomation((s) => {
            if (!s) {
                return undefined;
            }
            const appliedFilters = getAppliedWidgetFilters(filters, dashboardHiddenFilters, widget, insight, commonDateFilterId, true);
            const visibleFilters = getVisibleFiltersByFilters(filters, availableFiltersAsVisibleFilters, true);
            const updatedAutomationWithFilters = {
                ...s,
                alert: {
                    ...s.alert,
                    execution: {
                        ...s.alert.execution,
                        filters: appliedFilters,
                    },
                },
                metadata: {
                    ...s.metadata,
                    visibleFilters,
                },
            };
            const updatedAutomationWithAttribute = transformAlertByAttribute(supportedAttributes, updatedAutomationWithFilters, selectedAttribute, {
                name: selectedValue ?? "",
                title: "",
                value: "",
            });
            return selectedMeasure
                ? transformAlertByMetric(supportedMeasures, updatedAutomationWithAttribute, selectedMeasure, measureFormatMap, weekStart, timezone)
                : updatedAutomationWithAttribute;
        });
    }, [
        setEditedAutomationFilters,
        setEditedAutomation,
        availableFiltersAsVisibleFilters,
        widget,
        insight,
        dashboardHiddenFilters,
        commonDateFilterId,
        //
        selectedAttribute,
        selectedValue,
        supportedAttributes,
        //
        selectedMeasure,
        supportedMeasures,
        measureFormatMap,
        //
        weekStart,
        timezone,
    ]);
    const onApplyCurrentFilters = useCallback(() => {
        onFiltersChange(filtersForNewAutomation);
    }, [filtersForNewAutomation, onFiltersChange]);
    const { value, onChange, onBlur, errorMessage: thresholdErrorMessage, } = useThresholdValue(onValueChange, getMetricValue, isNewAlert, editedAutomation?.alert, selectedRelativeOperator, selectedMeasure, selectedAttribute, selectedValue);
    const hasValidThreshold = isAlertValueDefined(editedAutomation?.alert);
    const validationErrorMessage = isOriginalAutomationValid
        ? undefined
        : intl.formatMessage({ id: "insightAlert.config.invalidWidget" });
    const hasRecipients = (editedAutomation?.recipients?.length ?? 0) > 0;
    const hasValidExternalRecipients = allowExternalRecipients
        ? true
        : !editedAutomation?.recipients?.some(isAutomationExternalUserRecipient);
    const hasValidCreatorRecipient = allowOnlyLoggedUserRecipients
        ? editedAutomation?.recipients?.length === 1 &&
            editedAutomation?.recipients[0].id === defaultRecipient.id
        : true;
    const hasNoUnknownRecipients = !editedAutomation?.recipients?.some(isAutomationUnknownUserRecipient);
    const respectsRecipientsLimit = (editedAutomation?.recipients?.length ?? 0) <= maxAutomationsRecipients;
    const hasFilledEmails = selectedNotificationChannel?.destinationType === "smtp"
        ? editedAutomation?.recipients?.every((recipient) => isAutomationUserRecipient(recipient) ? isEmail(recipient.email ?? "") : true)
        : true;
    const isValid = !!editedAutomation &&
        hasRecipients &&
        respectsRecipientsLimit &&
        hasValidExternalRecipients &&
        hasValidCreatorRecipient &&
        hasNoUnknownRecipients &&
        hasFilledEmails &&
        hasValidThreshold &&
        isTitleValid;
    const isSubmitDisabled = !isValid || (alertToEdit && isEqual(originalAutomation, editedAutomation));
    return {
        onTitleChange,
        onRecipientsChange,
        onFiltersChange,
        onApplyCurrentFilters,
        onMeasureChange,
        getAttributeValues,
        onAttributeChange,
        onComparisonOperatorChange,
        onRelativeOperatorChange,
        onAnomalyDetectionChange,
        onSensitivityChange,
        onGranularityChange,
        onChange,
        onBlur,
        onComparisonTypeChange,
        onDestinationChange,
        onTriggerModeChange,
        onTriggerIntervalChange,
        selectedMeasure,
        supportedMeasures,
        canManageAttributes,
        selectedAttribute,
        selectedValue,
        supportedAttributes,
        catalogAttributes,
        catalogDateDatasets,
        isResultLoading,
        selectedAiOperator,
        selectedSensitivity,
        selectedGranularity,
        selectedComparisonOperator,
        selectedRelativeOperator,
        value,
        selectedComparator,
        canManageComparison,
        separators,
        warningMessage,
        defaultUser,
        originalAutomation,
        editedAutomation,
        allowOnlyLoggedUserRecipients,
        allowExternalRecipients,
        validationErrorMessage,
        isSubmitDisabled,
        isParentValid,
        thresholdErrorMessage,
        allowHourlyRecurrence,
    };
}
//# sourceMappingURL=useEditAlert.js.map