var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
import React, { useCallback, useMemo, useState } from 'react';
import { createContext } from '@fluentui/react-context-selector';
import { nanoid } from 'nanoid';
import { createNewAttributeValue, isComplexAttribute, isImage } from '@reltio/mdm-sdk';
import { useMdmMetadata } from '../../../../contexts/MdmModuleContext';
import { getAvailableSubAttributesForNestedOrReference } from '../../helpers/moreAttributesScope';
export var ADDED_ID_SEPARATOR = '|';
export var ADDED_CHANGE_ID_PREFIX = "added".concat(ADDED_ID_SEPARATOR);
export var AddedAttributesContext = createContext({
    getAddedAttributes: undefined,
    addAddedAttributes: undefined,
    removeAddedAttribute: undefined,
    updateAddedAttributeRefEntity: undefined,
    resetState: undefined
});
var getInitialAttributeValue = function (attrType) {
    if (isComplexAttribute(attrType) || isImage(attrType))
        return undefined;
    var _a = createNewAttributeValue(attrType), value = _a.value, lookupCode = _a.lookupCode;
    if (value === '' && !lookupCode)
        return undefined;
    return lookupCode ? { value: value, lookupCode: lookupCode } : { value: value };
};
var generateAddedAttributeId = function (parentId) {
    return parentId ? "".concat(parentId).concat(ADDED_ID_SEPARATOR).concat(nanoid()) : "".concat(ADDED_CHANGE_ID_PREFIX).concat(nanoid());
};
var createAddedAttribute = function (_a) {
    var attributeType = _a.attributeType, objectUri = _a.objectUri, parentLineId = _a.parentLineId, parentId = _a.parentId, changeOverrides = _a.changeOverrides;
    var finalChangeOverrides = changeOverrides
        ? __assign(__assign(__assign({}, changeOverrides), (changeOverrides.attributePath && {
            attributePath: "".concat(changeOverrides.attributePath, "/").concat(attributeType.name)
        })), (changeOverrides.refAttributeType && {
            refAttributeType: "".concat(changeOverrides.refAttributeType, "/attributes/").concat(attributeType.name)
        })) : undefined;
    var initialValue = getInitialAttributeValue(attributeType);
    return __assign({ attributeType: attributeType, id: generateAddedAttributeId(parentId), objectUri: objectUri, parentLineId: parentLineId, parentId: parentId, changeOverrides: finalChangeOverrides }, (initialValue && { initialValue: initialValue }));
};
export var AddedAttributesProvider = function (_a) {
    var children = _a.children;
    var metadata = useMdmMetadata();
    var _b = useState([]), state = _b[0], setState = _b[1];
    var getAddedAttributes = useCallback(function () { return state; }, [state]);
    var createAddedAttributes = useCallback(function (_a) {
        var attributeType = _a.attributeType, objectUri = _a.objectUri, parentLineId = _a.parentLineId, parentId = _a.parentId, changeOverrides = _a.changeOverrides;
        var addedAttribute = createAddedAttribute({
            attributeType: attributeType,
            objectUri: objectUri,
            parentLineId: parentLineId,
            parentId: parentId,
            changeOverrides: changeOverrides
        });
        var result = [addedAttribute];
        if (isComplexAttribute(attributeType)) {
            var subAttributes = getAvailableSubAttributesForNestedOrReference(metadata, attributeType);
            for (var _i = 0, subAttributes_1 = subAttributes; _i < subAttributes_1.length; _i++) {
                var attr = subAttributes_1[_i];
                if (attr.required) {
                    result.push.apply(result, createAddedAttributes({
                        attributeType: attr,
                        objectUri: objectUri,
                        parentId: addedAttribute.id
                    }));
                }
                else {
                    result.push(createAddedAttribute({
                        attributeType: attr,
                        objectUri: objectUri,
                        parentId: addedAttribute.id
                    }));
                }
            }
        }
        return result;
    }, [metadata]);
    var addAddedAttributes = useCallback(function (_a) {
        var attributeTypes = _a.attributeTypes, objectUri = _a.objectUri, parentLineId = _a.parentLineId, parentId = _a.parentId, changeOverrides = _a.changeOverrides;
        if (attributeTypes.length === 0)
            return [];
        var addedIds = [];
        setState(function (prev) {
            var newAddedAttributes = attributeTypes.flatMap(function (attributeType) {
                return createAddedAttributes({ attributeType: attributeType, objectUri: objectUri, parentLineId: parentLineId, parentId: parentId, changeOverrides: changeOverrides });
            });
            addedIds.push.apply(addedIds, newAddedAttributes.map(function (attr) { return attr.id; }));
            return __spreadArray(__spreadArray([], prev, true), newAddedAttributes, true);
        });
        return addedIds;
    }, [createAddedAttributes]);
    var removeAddedAttribute = useCallback(function (id) {
        setState(function (prev) {
            return prev.filter(function (addedAttribute) {
                return addedAttribute.id !== id && !addedAttribute.id.startsWith("".concat(id).concat(ADDED_ID_SEPARATOR));
            });
        });
    }, []);
    var updateAddedAttributeRefEntity = useCallback(function (id, refEntity) {
        setState(function (prev) { return prev.map(function (attr) { return (attr.id === id ? __assign(__assign({}, attr), { refEntity: refEntity }) : attr); }); });
    }, []);
    var resetState = useCallback(function () {
        setState([]);
    }, []);
    var value = useMemo(function () { return ({
        getAddedAttributes: getAddedAttributes,
        addAddedAttributes: addAddedAttributes,
        removeAddedAttribute: removeAddedAttribute,
        updateAddedAttributeRefEntity: updateAddedAttributeRefEntity,
        resetState: resetState
    }); }, [getAddedAttributes, addAddedAttributes, removeAddedAttribute, updateAddedAttributeRefEntity, resetState]);
    return React.createElement(AddedAttributesContext.Provider, { value: value }, children);
};
