var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import { useCallback, useMemo } from 'react';
import jsonLogic from 'json-logic-js';
import { useTransactionStore } from '../../stores/transactionStore';
import { useUser } from '../auth';
import { TransactionActionTypeEnums, TransactionEventTypeEnums } from '../../enums';
export const useTransactionEngine = (transactionTypeId) => {
    const user = useUser();
    const transactionTypesMap = useTransactionStore((state) => state.transactionTypesMap);
    const transactionType = transactionTypesMap
        ? transactionTypesMap[transactionTypeId]
        : null;
    const evaluateRule = useCallback((rule, udpTransaction) => {
        let udpTransactionEvaluationData = {
            currentStatusId: udpTransaction === null || udpTransaction === void 0 ? void 0 : udpTransaction.currentStatusId,
            currentDomainValue: udpTransaction === null || udpTransaction === void 0 ? void 0 : udpTransaction.entityBusinessObject,
            tenantUserRoleIds: (user === null || user === void 0 ? void 0 : user.roleIds) || []
        };
        return jsonLogic.apply(rule, udpTransactionEvaluationData);
    }, [user === null || user === void 0 ? void 0 : user.roleIds]);
    const getTransactionTypeTransactionActions = useCallback((udpTransaction, ruleTypeId = null) => {
        var _a;
        const transactionActions = (_a = transactionType === null || transactionType === void 0 ? void 0 : transactionType.udpTransactionTypeUdpTransactionTypeConfiguration) === null || _a === void 0 ? void 0 : _a.reduce((actions, config) => {
            const ruleLogic = config === null || config === void 0 ? void 0 : config.expressionLogic;
            if (!ruleTypeId) {
                return actions;
            }
            if (config.transactionRuleTypeId === ruleTypeId &&
                config.enabled &&
                ruleLogic) {
                const result = evaluateRule(ruleLogic, udpTransaction);
                if (result) {
                    const configActions = (config === null || config === void 0 ? void 0 : config.udpTransactionTypeConfigurationUdpTransactionTypeConfigurationTransactionAction) ||
                        [];
                    const nestedActions = configActions
                        .map((action) => action.udpTransactionTypeConfigurationTransactionActionUdpTransactionTypeTransactionAction)
                        .filter((action) => action);
                    if (nestedActions.length > 0) {
                        actions = actions.concat(nestedActions);
                    }
                }
                return actions;
            }
            return actions;
        }, []);
        return transactionActions;
    }, [transactionType, evaluateRule]);
    const hasRevisions = useMemo(() => {
        return transactionType === null || transactionType === void 0 ? void 0 : transactionType.hasRevision;
    }, [transactionType]);
    const hasClosedStatus = useMemo(() => {
        var _a;
        return (_a = transactionType === null || transactionType === void 0 ? void 0 : transactionType.udpTransactionTypeUdpTransactionTypeStatus) === null || _a === void 0 ? void 0 : _a.some((status) => status.isClosedStatus);
    }, [transactionType]);
    const canCancel = useMemo(() => {
        var _a;
        return ((transactionType === null || transactionType === void 0 ? void 0 : transactionType.archiveOnCancel) ||
            ((_a = transactionType === null || transactionType === void 0 ? void 0 : transactionType.udpTransactionTypeUdpTransactionTypeStatus) === null || _a === void 0 ? void 0 : _a.some((status) => status.isCancelledStatus)));
    }, [transactionType]);
    const transactionTypeStatuses = useMemo(() => transactionType === null || transactionType === void 0 ? void 0 : transactionType.udpTransactionTypeUdpTransactionTypeStatus, [transactionType]);
    const transactionTypeGridColumns = useMemo(() => {
        if (Array.isArray(transactionType === null || transactionType === void 0 ? void 0 : transactionType.domainFields)) {
            return (transactionType === null || transactionType === void 0 ? void 0 : transactionType.domainFields) || [];
        }
        else if ((transactionType === null || transactionType === void 0 ? void 0 : transactionType.domainFields) &&
            Object.keys(transactionType.domainFields).length) {
            const orderedColumns = Object.entries(transactionType.domainFields)
                .map(([propertyName, value]) => (Object.assign({ propertyName }, value)))
                .sort((a, b) => a.order - b.order);
            return orderedColumns || [];
        }
        return [];
    }, [transactionType]);
    const transactionTypeColumnDefProperties = useMemo(() => {
        var _a;
        return (_a = transactionType === null || transactionType === void 0 ? void 0 : transactionType.pageConfiguration) === null || _a === void 0 ? void 0 : _a.columnDefProperties;
    }, [transactionType]);
    const transactionTypePageConfiguration = useMemo(() => {
        const _a = (transactionType === null || transactionType === void 0 ? void 0 : transactionType.pageConfiguration) || {}, { columnDefProperties } = _a, other = __rest(_a, ["columnDefProperties"]);
        return other;
    }, [transactionType]);
    const transactionTypeStatusColorsMap = useMemo(() => {
        var _a;
        const statusColorsMap = {};
        (_a = transactionType === null || transactionType === void 0 ? void 0 : transactionType.udpTransactionTypeUdpTransactionTypeStatus) === null || _a === void 0 ? void 0 : _a.forEach((status) => {
            statusColorsMap[status.name] = status.color || 'default';
        });
        return statusColorsMap;
    }, [transactionType]);
    const getHiddenFields = useCallback((udpTransaction) => {
        const transactionActions = getTransactionTypeTransactionActions(udpTransaction, TransactionEventTypeEnums.Form);
        if (!transactionActions)
            return [];
        let hiddenFields = [];
        transactionActions
            .filter((action) => action.transactionActionId ===
            TransactionActionTypeEnums.Set_Fields_Hidden)
            .forEach((action) => {
            var _a;
            if ((_a = action.parameters) === null || _a === void 0 ? void 0 : _a.hiddenFields) {
                hiddenFields = hiddenFields.concat(action.parameters.hiddenFields);
            }
        });
        return hiddenFields;
    }, [getTransactionTypeTransactionActions]);
    const getRequiredFields = useCallback((udpTransaction) => {
        const transactionActions = getTransactionTypeTransactionActions(udpTransaction, TransactionEventTypeEnums.Form);
        if (!transactionActions)
            return [];
        let requiredFields = [];
        transactionActions
            .filter((action) => action.transactionActionId ===
            TransactionActionTypeEnums.Set_Mandatory_Fields)
            .forEach((action) => {
            var _a;
            if ((_a = action.parameters) === null || _a === void 0 ? void 0 : _a.mandatoryFields) {
                requiredFields = requiredFields.concat(action.parameters.mandatoryFields);
            }
        });
        return requiredFields;
    }, [getTransactionTypeTransactionActions]);
    const getUiActionRenderParameters = useCallback((uiActionType) => {
        var _a;
        const uiAction = (_a = transactionType === null || transactionType === void 0 ? void 0 : transactionType.udpTransactionTypeUdpTransactionUiAction) === null || _a === void 0 ? void 0 : _a.find((action) => action.transactionUiActionTypeId === uiActionType);
        return (uiAction === null || uiAction === void 0 ? void 0 : uiAction.parameters) || null;
    }, [transactionType]);
    const formatLabel = (label, obj) => {
        const fields = label === null || label === void 0 ? void 0 : label.split('+');
        const keys = fields === null || fields === void 0 ? void 0 : fields.map((field) => field.trim());
        if (keys) {
            const skippableKeys = [];
            const updatedKeys = keys.map((key, index) => {
                const matchedKey = key.charAt(0) === '"';
                if (matchedKey) {
                    skippableKeys.push(index);
                    key = key.replace(/"/g, '');
                }
                return key;
            });
            const values = [];
            for (let j = 0; j < keys.length; j++) {
                let property = keys[j];
                if (property) {
                    const splitProperties = property.split('.');
                    if (splitProperties.length > 1) {
                        let constructedValue = null;
                        splitProperties.forEach((property) => {
                            const matches = property.match(/\[(.*?)\]/);
                            let objIndex = null;
                            let arrIndex = null;
                            if (matches) {
                                arrIndex = parseInt(matches[1]);
                                objIndex = matches.index;
                            }
                            if (typeof arrIndex === 'number' && objIndex) {
                                const formattedProperty = property.substring(0, objIndex);
                                if (!constructedValue) {
                                    if (obj[formattedProperty]) {
                                        constructedValue = obj[formattedProperty][arrIndex];
                                    }
                                }
                                else {
                                    if (constructedValue[formattedProperty]) {
                                        constructedValue =
                                            constructedValue[formattedProperty][arrIndex];
                                    }
                                }
                            }
                            else {
                                if (!constructedValue) {
                                    constructedValue = obj[property];
                                }
                                else {
                                    constructedValue = constructedValue[property];
                                }
                            }
                        });
                        if (typeof constructedValue === 'boolean' ||
                            typeof constructedValue === 'number') {
                            constructedValue = constructedValue.toString();
                        }
                        values.push(constructedValue);
                        continue;
                    }
                }
                let value = obj[property];
                if (typeof value === 'boolean' || typeof value === 'number') {
                    value = value.toString();
                }
                values.push(value);
            }
            let displayName = updatedKeys.join('+');
            for (let k = 0; k < updatedKeys.length; k++) {
                if (!skippableKeys.includes(k)) {
                    if (values[k]) {
                        displayName = displayName.replace(`${updatedKeys[k]}`, values[k]);
                    }
                    else {
                        displayName = displayName.replace(`${updatedKeys[k]}`, '');
                    }
                }
            }
            return displayName.replaceAll('+', ' ');
        }
        else {
            return label;
        }
    };
    const getTransactionTypeLabel = useCallback((udpTransaction) => {
        if (!(transactionType === null || transactionType === void 0 ? void 0 : transactionType.domainFieldLabel))
            return null;
        return formatLabel(transactionType.domainFieldLabel, (udpTransaction === null || udpTransaction === void 0 ? void 0 : udpTransaction.entityBusinessObject) || {});
    }, [transactionType]);
    const closedStatuses = useMemo(() => {
        var _a;
        if (!hasClosedStatus)
            return [];
        return (_a = transactionType === null || transactionType === void 0 ? void 0 : transactionType.udpTransactionTypeUdpTransactionTypeStatus) === null || _a === void 0 ? void 0 : _a.filter((status) => status.isClosedStatus);
    }, [hasClosedStatus, transactionType]);
    const checkIfTransactionIsClosed = useCallback((udpTransaction) => {
        if (!closedStatuses || closedStatuses.length === 0)
            return false;
        return closedStatuses.some((closedStatus) => closedStatus.transactionTypeStatusId ===
            (udpTransaction === null || udpTransaction === void 0 ? void 0 : udpTransaction.currentStatusId));
    }, [closedStatuses]);
    return {
        currentTransactionType: transactionType,
        evaluateRule,
        getTransactionTypeTransactionActions,
        hasRevisions,
        getHiddenFields,
        getRequiredFields,
        closedStatuses,
        hasClosedStatus,
        transactionTypeGridColumns,
        transactionTypeColumnDefProperties,
        transactionTypePageConfiguration,
        getUiActionRenderParameters,
        checkIfTransactionIsClosed,
        getTransactionTypeLabel,
        transactionTypeStatusColorsMap,
        transactionTypeStatuses,
        canCancel
    };
};
//# sourceMappingURL=useTransactionEngine.js.map