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);
};
import React, { useCallback, useEffect, useMemo } from 'react';
import classnames from 'classnames';
import { uniq } from 'ramda';
import { Directions, getActivenessAttributes, getSuitableEntityTypeUrisForRelationTypes, getDefaultRelationTypeObject, getLabel, getRelationAttributesList, getRelationType, isAvailableRelationBetweenEntities, Mode } from '@reltio/mdm-sdk';
import { EditModeAttributesList } from '../EditModeAttributesList';
import { ConnectionRelationTypeSelector } from '../ConnectionRelationTypeSelector';
import { ErrorWrapper } from '../ErrorWrapper';
import { EntitySelector } from '../EntitySelector';
import { useMdmGlobalSearchRequestOptions, useMdmMetadata } from '../contexts/MdmModuleContext';
import { useDidUpdateEffect } from '../hooks/useDidUpdateEffect';
import { useStyles } from './styles';
export 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 = 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 = useMdmMetadata();
    var globalSearchRequestOptions = useMdmGlobalSearchRequestOptions(['ovOnly']);
    var attributeListEntity = useMemo(function () {
        return relation && __assign({ attributes: attributes }, getActivenessAttributes(relation));
    }, [relation, attributes]);
    var relationAttrTypes = useMemo(function () { return getRelationAttributesList(metadata, relationTypeUri); }, [relationTypeUri, metadata]);
    var availableEntityTypeUris = useMemo(function () {
        return isRelationTypeSelected
            ? getSuitableEntityTypeUrisForRelationTypes(direction === Directions.OUT, metadata, [
                getRelationType(metadata, relationTypeUri)
            ])
            : uniq(getSuitableEntityTypeUrisForRelationTypes(true, metadata, outRelationTypes).concat(getSuitableEntityTypeUrisForRelationTypes(false, metadata, inRelationTypes)));
    }, [isRelationTypeSelected, relationTypeUri, metadata, inRelationTypes, outRelationTypes]);
    var selectorCompatibleRelation = useMemo(function () {
        return relation && {
            relationType: relation.type,
            direction: relation.direction
        };
    }, [relation]);
    var selectorCompatibleEntity = useMemo(function () {
        return entity && {
            entityUri: entity.uri,
            entityType: entity.type,
            entityLabel: getLabel(entity.label)
        };
    }, [entity]);
    var availableInRelationTypes = useMemo(function () {
        return entity && entity.uri
            ? inRelationTypes.filter(isAvailableRelationBetweenEntities(false, entity, relatedEntity, metadata))
            : inRelationTypes;
    }, [entity, inRelationTypes, relatedEntity, metadata]);
    var availableOutRelationTypes = useMemo(function () {
        return entity && entity.uri
            ? outRelationTypes.filter(isAvailableRelationBetweenEntities(true, entity, relatedEntity, metadata))
            : outRelationTypes;
    }, [entity, outRelationTypes, relatedEntity, metadata]);
    useEffect(function () {
        // autoselecting relation type on mount
        var _a = getDefaultRelationTypeObject(inRelationTypes, outRelationTypes) || {}, type = _a.type, direction = _a.direction;
        if (!relationTypeUri && type && onChangeRelationType) {
            onChangeRelationType({ type: type.uri, direction: direction });
        }
    }, [relationTypeUri, inRelationTypes, outRelationTypes, onChangeRelationType]);
    useDidUpdateEffect(function () {
        // autoselecting relation type on entity change
        var _a = 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 = useCallback(function (_a) {
        var type = _a.type, direction = _a.direction;
        onChangeRelationType({ type: type.uri, direction: direction });
    }, [onChangeRelationType]);
    return (React.createElement(React.Fragment, null,
        onChangeRelationType && (React.createElement(ConnectionRelationTypeSelector, { className: styles.item, relation: selectorCompatibleRelation, metadata: metadata, inRelationTypes: inRelationTypes, outRelationTypes: outRelationTypes, onChange: handleChangeRelationType })),
        onChangeEntity && (React.createElement(ErrorWrapper, { errorMessage: entityErrorMessage, className: styles.item },
            React.createElement(EntitySelector, { key: relationTypeUri, className: classnames((_b = {}, _b[styles.dense] = entityErrorMessage, _b)), entity: selectorCompatibleEntity || {}, entityTypesUris: availableEntityTypeUris, globalSearchRequestOptions: globalSearchRequestOptions, mode: Mode.Editing, onChange: onChangeEntity, onCreate: undefined, metadata: metadata, attributeTypesSelectionStrategy: undefined }))),
        relationTypeUri && (React.createElement(EditModeAttributesList, { attrTypes: relationAttrTypes, entity: attributeListEntity, showEmptyEditors: showEmptyEditors, mode: Mode.Editing, parentUri: relationUri, onAddAttributes: onAddAttributes, onChangeAttribute: onChangeAttribute, onDeleteAttribute: onRemoveAttribute }))));
};
