"use strict";
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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
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;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = __importStar(require("react"));
var classnames_1 = __importDefault(require("classnames"));
var ramda_1 = require("ramda");
var mdm_sdk_1 = require("@reltio/mdm-sdk");
var EditModeComplexAttribute_1 = require("../EditModeComplexAttribute");
var EntitySelector_1 = require("../EntitySelector");
var ErrorWrapper_1 = require("../ErrorWrapper");
var withContext_1 = require("../HOCs/withContext");
var ConfigPermissionsContext_1 = require("../contexts/ConfigPermissionsContext");
var ScrollToElementContext_1 = require("../contexts/ScrollToElementContext");
var MdmModuleContext_1 = require("../contexts/MdmModuleContext");
var useScrollToAttributeError_1 = require("../hooks/useScrollToAttributeError");
var AutoCompleteContext_1 = require("../contexts/AutoCompleteContext");
var styles_1 = require("./styles");
var ReferenceAttributeEditor = function (props) {
    var _a;
    var styles = (0, styles_1.useStyles)();
    var highlightedError = props.highlightedError, ownProps = __rest(props, ["highlightedError"]);
    var attributeValue = ownProps.attributeValue, attributeType = ownProps.attributeType, mode = ownProps.mode, crosswalks = ownProps.crosswalks, errors = ownProps.errors, onChangeAttribute = ownProps.onChangeAttribute;
    var initialAttributeValue = (0, react_1.useRef)(attributeValue);
    var _b = (0, useScrollToAttributeError_1.useScrollToAttributeError)({ highlightedError: highlightedError, isSimple: true }), ref = _b.ref, errorClassName = _b.errorClassName;
    var entityUri = (0, mdm_sdk_1.getReferencedEntityUriFromAttrValue)(attributeValue);
    var entityDeleted = (0, MdmModuleContext_1.useMdmAction)('entityDeleted');
    var entityCreated = (0, MdmModuleContext_1.useMdmAction)('entityCreated');
    var errorDeactivated = (0, MdmModuleContext_1.useMdmAction)('errorDeactivated');
    var mdmModifiedEntity = (0, MdmModuleContext_1.useMdmModifiedEntity)(entityUri);
    var modifiedEntity = (0, mdm_sdk_1.isTempUri)(entityUri) ? mdmModifiedEntity : null;
    var metadata = (0, MdmModuleContext_1.useMdmMetadata)();
    var globalSearchRequestOptions = (0, MdmModuleContext_1.useMdmGlobalSearchRequestOptions)(['ovOnly']);
    var showMasking = (0, MdmModuleContext_1.useMdmShowMasking)();
    var referencedEntity = (0, mdm_sdk_1.getReferencedEntityFromAttrValue)(attributeValue);
    var referencedRelation = (0, mdm_sdk_1.getReferencedRelationFromAttrValue)(attributeValue);
    var referencedEntityTypeUri = (0, mdm_sdk_1.getReferencedEntityTypeUriFromAttrType)(attributeType);
    var referencedEntityType = (0, mdm_sdk_1.getEntityType)(metadata, referencedEntityTypeUri);
    var label = modifiedEntity
        ? (0, mdm_sdk_1.evaluateDeepEntityLabel)(modifiedEntity, referencedEntityType.dataLabelPattern)
        : attributeValue.label;
    var entityTypesUris = (0, react_1.useMemo)(function () { return [referencedEntityTypeUri]; }, [referencedEntityTypeUri]);
    var allCrosswalks = (0, react_1.useMemo)(function () { return (0, mdm_sdk_1.addReferencedRelationCrosswalks)(crosswalks, referencedRelation); }, [crosswalks, referencedRelation]);
    var referencedEntityMissedError = (0, react_1.useMemo)(function () { return (0, mdm_sdk_1.getReferencedEntityActiveError)(attributeValue, errors); }, [attributeValue, errors]);
    var selectedEntity = (0, react_1.useMemo)(function () {
        return referencedEntity && {
            entityUri: (0, mdm_sdk_1.getReferencedEntityUri)(referencedEntity),
            entityType: (0, mdm_sdk_1.getReferencedEntityTypeUri)(referencedEntity),
            entityLabel: attributeValue.label
        };
    }, [referencedEntity, attributeValue.label]);
    var editableAttrTypes = (0, react_1.useMemo)(function () {
        return (0, mdm_sdk_1.getReferencedRelationAttrTypesUris)(attributeType)
            .map(function (attrTypeUri) { return (0, mdm_sdk_1.findAttributeTypeByUri)(metadata, attrTypeUri); })
            .filter(ramda_1.identity);
    }, [attributeType, metadata]);
    var newEntityAttrTypesSelectionStrategy = (0, react_1.useCallback)(function (entityType) { return (0, mdm_sdk_1.referencedEntityAttributeTypesSelectionStrategy)(attributeType, entityType); }, [attributeType]);
    var onChangeEntity = (0, react_1.useCallback)(function (entity) {
        if (modifiedEntity) {
            entityDeleted(modifiedEntity.uri);
        }
        var initialAttrValue = initialAttributeValue.current;
        var isInitialEntity = !(0, ramda_1.isEmpty)(entity) && entity.uri === (0, mdm_sdk_1.getReferencedEntityUriFromAttrValue)(initialAttrValue);
        var modifiedValue = __assign(__assign({}, attributeValue), { label: entity.label, refEntity: isInitialEntity ? initialAttrValue.refEntity : (0, mdm_sdk_1.convertReferencedEntityForAttrValue)(entity), refRelation: isInitialEntity
                ? initialAttrValue.refRelation
                : (0, mdm_sdk_1.createReferencedRelationForAttrValue)(attributeValue) });
        onChangeAttribute({ value: modifiedValue, attributeType: attributeType, uri: attributeValue.uri });
        if (referencedEntityMissedError) {
            errorDeactivated((0, mdm_sdk_1.getErrorId)(referencedEntityMissedError));
        }
    }, [
        attributeValue,
        attributeType,
        modifiedEntity,
        onChangeAttribute,
        entityDeleted,
        errorDeactivated,
        referencedEntityMissedError
    ]);
    var onCreateEntity = (0, react_1.useCallback)(function (entityTypeUri, initValue) {
        var newEntityAttrTypes = (0, ramda_1.pipe)(newEntityAttrTypesSelectionStrategy, (0, mdm_sdk_1.getCreatableAttributeTypes)(mode))(referencedEntityType);
        var newEntity = (0, mdm_sdk_1.createTemporaryEntity)({
            entityTypeUri: entityTypeUri,
            initValue: initValue,
            attributeTypes: newEntityAttrTypes,
            metadata: metadata,
            mode: mode
        });
        onChangeEntity(newEntity);
        entityCreated(newEntity);
    }, [newEntityAttrTypesSelectionStrategy, mode, referencedEntityType, metadata, onChangeEntity, entityCreated]);
    var _c = (0, ConfigPermissionsContext_1.useAttributeValueConfigPermissions)(attributeValue.uri), configCanCreate = _c.canCreate, configCanUpdate = _c.canUpdate;
    var canChangeReferencedEntity = (0, react_1.useMemo)(function () {
        return configCanUpdate &&
            (0, mdm_sdk_1.checkCanEditAttribute)({
                attributeType: attributeType,
                attributeValue: attributeValue,
                mode: mode,
                isReltioCrosswalk: (0, mdm_sdk_1.isReltioCrosswalk)(crosswalks, attributeValue)
            });
    }, [attributeType, attributeValue, mode, crosswalks, configCanUpdate]);
    var canCreateReferencedEntity = (0, react_1.useMemo)(function () { return configCanCreate && (0, mdm_sdk_1.checkMetadataForCreate)(mode, referencedEntityType); }, [mode, referencedEntityType, configCanCreate]);
    var errorMessage = (0, mdm_sdk_1.getErrorMessage)(referencedEntityMissedError);
    var isMasked = showMasking && (0, mdm_sdk_1.isAttributeHasMaskedValue)(attributeValue);
    return (react_1.default.createElement(EditModeComplexAttribute_1.EditModeComplexAttribute, __assign({}, ownProps, { label: (0, mdm_sdk_1.getLabel)(label), attributeTypesList: editableAttrTypes, crosswalks: allCrosswalks, metadata: metadata }),
        react_1.default.createElement("div", { ref: ref, className: errorClassName },
            react_1.default.createElement(ErrorWrapper_1.ErrorWrapper, { errorMessage: errorMessage },
                react_1.default.createElement(AutoCompleteContext_1.AddressAutoCompleteProvider, { entityUri: entityUri },
                    react_1.default.createElement(EntitySelector_1.EntitySelector, { className: (0, classnames_1.default)(styles.item, (_a = {},
                            _a[styles.dense] = errorMessage || (selectedEntity && (0, mdm_sdk_1.isTempUri)(selectedEntity.entityUri)),
                            _a)), entity: selectedEntity || {}, entityTypesUris: entityTypesUris, globalSearchRequestOptions: globalSearchRequestOptions, mode: mode, isDisabled: !canChangeReferencedEntity || !!attributeValue.masked, onChange: onChangeEntity, onCreate: canCreateReferencedEntity ? onCreateEntity : undefined, metadata: metadata, attributeTypesSelectionStrategy: newEntityAttrTypesSelectionStrategy, isMasked: isMasked }))))));
};
exports.default = (0, withContext_1.withContext)(ScrollToElementContext_1.ScrollToElementContext, function (contextValue, _a) {
    var attributeValue = _a.attributeValue, attributeType = _a.attributeType;
    var _b = contextValue || {}, element = _b.element, type = _b.type;
    var isHighlighted = (0, ScrollToElementContext_1.isHighlightedErrorType)(type) &&
        (0, mdm_sdk_1.isAttributeTypeError)(element, attributeValue.uri, attributeType.uri);
    return { highlightedError: isHighlighted ? contextValue : null };
}, ReferenceAttributeEditor);
