"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 __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectionEditor = void 0;
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 EditModeAttributesList_1 = require("../EditModeAttributesList");
var ConnectionRelationTypeSelector_1 = require("../ConnectionRelationTypeSelector");
var ErrorWrapper_1 = require("../ErrorWrapper");
var EntitySelector_1 = require("../EntitySelector");
var MdmModuleContext_1 = require("../contexts/MdmModuleContext");
var useDidUpdateEffect_1 = require("../hooks/useDidUpdateEffect");
var styles_1 = require("./styles");
var ConnectionEditor = function (_a) {
    var _b;
    var connection = _a.connection, relatedEntity = _a.relatedEntity, _c = _a.inRelationTypes, inRelationTypes = _c === void 0 ? [] : _c, _d = _a.outRelationTypes, outRelationTypes = _d === void 0 ? [] : _d, showEmptyEditors = _a.showEmptyEditors, entityErrorMessage = _a.entityErrorMessage, onChangeAttribute = _a.onChangeAttribute, onRemoveAttribute = _a.onRemoveAttribute, onAddAttributes = _a.onAddAttributes, onChangeRelationType = _a.onChangeRelationType, onChangeEntity = _a.onChangeEntity;
    var styles = (0, styles_1.useStyles)();
    var relation = connection.relation, entity = connection.entity;
    var _e = relation || {}, attributes = _e.attributes, relationUri = _e.uri, _f = _e.type, relationTypeUri = _f === void 0 ? '' : _f, direction = _e.direction;
    var isRelationTypeSelected = Boolean(relationTypeUri);
    var metadata = (0, MdmModuleContext_1.useMdmMetadata)();
    var globalSearchRequestOptions = (0, MdmModuleContext_1.useMdmGlobalSearchRequestOptions)(['ovOnly']);
    var attributeListEntity = (0, react_1.useMemo)(function () {
        return relation && __assign({ attributes: attributes }, (0, mdm_sdk_1.getActivenessAttributes)(relation));
    }, [relation, attributes]);
    var relationAttrTypes = (0, react_1.useMemo)(function () { return (0, mdm_sdk_1.getRelationAttributesList)(metadata, relationTypeUri); }, [relationTypeUri, metadata]);
    var availableEntityTypeUris = (0, react_1.useMemo)(function () {
        return isRelationTypeSelected
            ? (0, mdm_sdk_1.getSuitableEntityTypeUrisForRelationTypes)(direction === mdm_sdk_1.Directions.OUT, metadata, [
                (0, mdm_sdk_1.getRelationType)(metadata, relationTypeUri)
            ])
            : (0, ramda_1.uniq)((0, mdm_sdk_1.getSuitableEntityTypeUrisForRelationTypes)(true, metadata, outRelationTypes).concat((0, mdm_sdk_1.getSuitableEntityTypeUrisForRelationTypes)(false, metadata, inRelationTypes)));
    }, [isRelationTypeSelected, relationTypeUri, metadata, inRelationTypes, outRelationTypes]);
    var selectorCompatibleRelation = (0, react_1.useMemo)(function () {
        return relation && {
            relationType: relation.type,
            direction: relation.direction
        };
    }, [relation]);
    var selectorCompatibleEntity = (0, react_1.useMemo)(function () {
        return entity && {
            entityUri: entity.uri,
            entityType: entity.type,
            entityLabel: (0, mdm_sdk_1.getLabel)(entity.label)
        };
    }, [entity]);
    var availableInRelationTypes = (0, react_1.useMemo)(function () {
        return entity && entity.uri
            ? inRelationTypes.filter((0, mdm_sdk_1.isAvailableRelationBetweenEntities)(false, entity, relatedEntity, metadata))
            : inRelationTypes;
    }, [entity, inRelationTypes, relatedEntity, metadata]);
    var availableOutRelationTypes = (0, react_1.useMemo)(function () {
        return entity && entity.uri
            ? outRelationTypes.filter((0, mdm_sdk_1.isAvailableRelationBetweenEntities)(true, entity, relatedEntity, metadata))
            : outRelationTypes;
    }, [entity, outRelationTypes, relatedEntity, metadata]);
    (0, react_1.useEffect)(function () {
        // autoselecting relation type on mount
        var _a = (0, mdm_sdk_1.getDefaultRelationTypeObject)(inRelationTypes, outRelationTypes) || {}, type = _a.type, direction = _a.direction;
        if (!relationTypeUri && type && onChangeRelationType) {
            onChangeRelationType({ type: type.uri, direction: direction });
        }
    }, [relationTypeUri, inRelationTypes, outRelationTypes, onChangeRelationType]);
    (0, useDidUpdateEffect_1.useDidUpdateEffect)(function () {
        // autoselecting relation type on entity change
        var _a = (0, mdm_sdk_1.getDefaultRelationTypeObject)(availableInRelationTypes, availableOutRelationTypes) || {}, type = _a.type, direction = _a.direction;
        if (!relationTypeUri && type) {
            onChangeRelationType({ type: type.uri, direction: direction });
        }
    }, [relationTypeUri, entity, availableInRelationTypes, availableOutRelationTypes, onChangeEntity]);
    var handleChangeRelationType = (0, react_1.useCallback)(function (_a) {
        var type = _a.type, direction = _a.direction;
        onChangeRelationType({ type: type.uri, direction: direction });
    }, [onChangeRelationType]);
    return (react_1.default.createElement(react_1.default.Fragment, null,
        onChangeRelationType && (react_1.default.createElement(ConnectionRelationTypeSelector_1.ConnectionRelationTypeSelector, { className: styles.item, relation: selectorCompatibleRelation, metadata: metadata, inRelationTypes: inRelationTypes, outRelationTypes: outRelationTypes, onChange: handleChangeRelationType })),
        onChangeEntity && (react_1.default.createElement(ErrorWrapper_1.ErrorWrapper, { errorMessage: entityErrorMessage, className: styles.item },
            react_1.default.createElement(EntitySelector_1.EntitySelector, { key: relationTypeUri, className: (0, classnames_1.default)((_b = {}, _b[styles.dense] = entityErrorMessage, _b)), entity: selectorCompatibleEntity || {}, entityTypesUris: availableEntityTypeUris, globalSearchRequestOptions: globalSearchRequestOptions, mode: mdm_sdk_1.Mode.Editing, onChange: onChangeEntity, onCreate: undefined, metadata: metadata, attributeTypesSelectionStrategy: undefined }))),
        relationTypeUri && (react_1.default.createElement(EditModeAttributesList_1.EditModeAttributesList, { attrTypes: relationAttrTypes, entity: attributeListEntity, showEmptyEditors: showEmptyEditors, mode: mdm_sdk_1.Mode.Editing, parentUri: relationUri, onAddAttributes: onAddAttributes, onChangeAttribute: onChangeAttribute, onDeleteAttribute: onRemoveAttribute }))));
};
exports.ConnectionEditor = ConnectionEditor;
