// (C) 2022-2026 GoodData Corporation
import { useCallback, useState } from "react";
import { isEqual } from "lodash-es";
import { useIntl } from "react-intl";
import { isAutomationExternalUserRecipient, isAutomationUnknownUserRecipient, isAutomationUserRecipient, } from "@gooddata/sdk-model";
import { useDashboardSelector } from "../../../../../../model/react/DashboardStoreProvider.js";
import { selectEnableAnomalyDetectionAlert, selectEnableExternalRecipients, selectTimezone, selectWeekStart, } from "../../../../../../model/store/config/configSelectors.js";
import { selectEntitlementMinimumRecurrenceMinutes } from "../../../../../../model/store/entitlements/entitlementsSelectors.js";
import { selectCanUseAiAssistant } from "../../../../../../model/store/permissions/permissionsSelectors.js";
import { selectCurrentUser } from "../../../../../../model/store/user/userSelectors.js";
import { selectUsers } from "../../../../../../model/store/users/usersSelectors.js";
import { getDescription, } from "../../../../../automations/alerting/DefaultAlertingDialog/utils/getters.js";
import { isAlertRecipientsValid, isAlertValueDefined, } from "../../../../../automations/alerting/DefaultAlertingDialog/utils/guards.js";
import { transformAlertByAnomalyDetection, transformAlertByAttribute, transformAlertByComparisonOperator, transformAlertByDestination, transformAlertByGranularity, transformAlertByMetric, transformAlertByRelativeOperator, transformAlertBySensitivity, transformAlertByTitle, transformAlertByValue, } from "../../../../../automations/alerting/DefaultAlertingDialog/utils/transformation.js";
import { isEmail } from "../../../../../automations/scheduledEmail/utils/validate.js";
import { convertCurrentUserToAutomationRecipient, convertCurrentUserToWorkspaceUser, } from "../../../../../automations/shared/utils/automationUtils.js";
const DEFAULT_MIN_RECURRENCE_MINUTES = "60";
export const useEditAlert = ({ metrics, attributes, alert, onCreate, onUpdate, measureFormatMap, destinations, separators, }) => {
    const [viewMode, setViewMode] = useState("edit");
    const [updatedAlert, setUpdatedAlert] = useState(alert);
    const [warningMessage, setWarningMessage] = useState(undefined);
    const currentUser = useDashboardSelector(selectCurrentUser);
    const users = useDashboardSelector(selectUsers);
    const enabledExternalRecipients = useDashboardSelector(selectEnableExternalRecipients);
    const enableAnomalyDetectionAlert = useDashboardSelector(selectEnableAnomalyDetectionAlert);
    const enableAiAssistant = useDashboardSelector(selectCanUseAiAssistant);
    const weekStart = useDashboardSelector(selectWeekStart);
    const timezone = useDashboardSelector(selectTimezone);
    const intl = useIntl();
    const minimumRecurrenceMinutesEntitlement = useDashboardSelector(selectEntitlementMinimumRecurrenceMinutes);
    const allowHourlyRecurrence = parseInt(minimumRecurrenceMinutesEntitlement?.value ?? DEFAULT_MIN_RECURRENCE_MINUTES, 10) === 60;
    const selectedDestination = destinations.find((destination) => destination.id === updatedAlert.notificationChannel);
    const defaultUser = convertCurrentUserToWorkspaceUser(users ?? [], currentUser);
    const allowExternalRecipients = selectedDestination?.allowedRecipients === "external" && enabledExternalRecipients;
    const allowOnlyLoggedUserRecipients = selectedDestination?.allowedRecipients === "creator";
    const changeMeasure = useCallback((measure) => {
        setUpdatedAlert((alert) => transformAlertByMetric(metrics, alert, measure, measureFormatMap, weekStart, timezone));
    }, [measureFormatMap, metrics, weekStart, timezone]);
    const changeAttribute = useCallback((attribute, value) => {
        setUpdatedAlert((alert) => transformAlertByAttribute(attributes, alert, attribute, value));
    }, [attributes]);
    const changeComparisonOperator = useCallback((measure, comparisonOperator) => {
        setUpdatedAlert((alert) => transformAlertByComparisonOperator(metrics, alert, measure, comparisonOperator));
    }, [metrics]);
    const changeAnomalyDetection = useCallback((measure) => {
        setUpdatedAlert((alert) => transformAlertByAnomalyDetection(metrics, alert, measure, weekStart, timezone));
    }, [metrics, weekStart, timezone]);
    const changeRelativeOperator = useCallback((measure, relativeOperator, arithmeticOperator) => {
        setUpdatedAlert((alert) => transformAlertByRelativeOperator(metrics, alert, measure, relativeOperator, arithmeticOperator, measureFormatMap));
    }, [measureFormatMap, metrics]);
    const changeValue = useCallback((value) => {
        setUpdatedAlert((alert) => transformAlertByValue(alert, value));
    }, []);
    const changeTitle = useCallback((value) => {
        setUpdatedAlert((alert) => transformAlertByTitle(alert, value));
    }, []);
    const changeSensitivity = useCallback((value) => {
        setUpdatedAlert((alert) => transformAlertBySensitivity(alert, value));
    }, []);
    const changeGranularity = useCallback((measure, value) => {
        if (!measure) {
            return;
        }
        setUpdatedAlert((alert) => transformAlertByGranularity(metrics, alert, measure, value, weekStart));
    }, [metrics, weekStart]);
    const changeDestination = useCallback((destinationId) => {
        const previousDestination = destinations.find((channel) => alert.notificationChannel === channel.id);
        const selectedDestination = destinations.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;
        setUpdatedAlert((alert) => transformAlertByDestination(alert, destinationId, updatedRecipients));
    }, [alert.notificationChannel, currentUser, destinations, intl, users]);
    const changeComparisonType = useCallback((measure, relativeOperator, comparisonType, granularity) => {
        if (!measure || !relativeOperator || !relativeOperator) {
            return;
        }
        const [relativeOperatorValue, arithmeticOperator] = relativeOperator;
        setUpdatedAlert((alert) => transformAlertByRelativeOperator(metrics, alert, measure, relativeOperatorValue, arithmeticOperator, measureFormatMap, comparisonType, granularity));
    }, [measureFormatMap, metrics]);
    const changeRecipients = useCallback((recipients) => {
        setUpdatedAlert((alert) => ({
            ...alert,
            recipients,
        }));
    }, []);
    const configureAlert = useCallback(() => {
        setViewMode("configuration");
    }, []);
    const cancelAlertConfiguration = useCallback(() => {
        setViewMode("edit");
    }, []);
    const saveAlertConfiguration = useCallback((alert) => {
        setUpdatedAlert(alert);
        cancelAlertConfiguration();
    }, [cancelAlertConfiguration]);
    const createAlert = useCallback(() => {
        const title = updatedAlert.title || getDescription(intl, metrics, updatedAlert, separators);
        onCreate?.({
            ...updatedAlert,
            title,
        });
    }, [intl, metrics, onCreate, separators, updatedAlert]);
    const updateAlert = useCallback(() => {
        const title = updatedAlert.title || getDescription(intl, metrics, updatedAlert, separators);
        onUpdate?.({
            ...updatedAlert,
            title,
        });
    }, [intl, metrics, onUpdate, separators, updatedAlert]);
    const isValueDefined = isAlertValueDefined(updatedAlert.alert);
    const isRecipientsValid = isAlertRecipientsValid(updatedAlert);
    const isExternalRecipientsValid = allowExternalRecipients
        ? true
        : !updatedAlert.recipients?.some(isAutomationExternalUserRecipient);
    const hasNoUnknownRecipients = !updatedAlert.recipients?.some(isAutomationUnknownUserRecipient);
    const isAlertChanged = !isEqual(updatedAlert, alert);
    const areEmailsValid = selectedDestination?.destinationType === "smtp"
        ? updatedAlert.recipients?.every((v) => isAutomationUserRecipient(v) ? isEmail(v.email ?? "") : true)
        : true;
    const canSubmit = isValueDefined &&
        isAlertChanged &&
        isRecipientsValid &&
        areEmailsValid &&
        isExternalRecipientsValid &&
        hasNoUnknownRecipients;
    return {
        defaultUser,
        viewMode,
        updatedAlert,
        canSubmit,
        allowOnlyLoggedUserRecipients,
        allowExternalRecipients,
        warningMessage,
        allowHourlyRecurrence,
        enableAnomalyDetectionAlert: enableAnomalyDetectionAlert && enableAiAssistant,
        //
        changeComparisonOperator,
        changeAnomalyDetection,
        changeRelativeOperator,
        changeMeasure,
        changeAttribute,
        changeValue,
        changeTitle,
        changeDestination,
        changeComparisonType,
        changeRecipients,
        changeSensitivity,
        changeGranularity,
        //
        configureAlert,
        saveAlertConfiguration,
        cancelAlertConfiguration,
        //
        createAlert,
        updateAlert,
    };
};
