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 __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 React, { useCallback, useContext, useEffect, useMemo } from 'react';
import classnames from 'classnames';
import { has, pipe } from 'ramda';
import { useContextSelector } from '@fluentui/react-context-selector';
import AddIcon from '@mui/icons-material/Add';
import DeleteIcon from '@mui/icons-material/Delete';
import Typography from '@mui/material/Typography';
import i18n from 'ui-i18n';
import { attributeUriToSearchUri, ErrorType, getAttributeValue, getAttrDataTypeDefinition, getErrorId, getErrorMessage, getErrorType, isDependentLookupAttrType, isEditableMode as checkIsEditableMode, Mode, DataTypes } from '@reltio/mdm-sdk';
import { DataTypeValue } from '../DataTypeValue';
import { DataTypeValueEditor } from '../DataTypeValueEditor';
import { ErrorWrapper } from '../ErrorWrapper';
import { SmallIconButton } from '../SmallIconButton';
import { prepareChangeData } from './helpers';
import { attributeValueToEditorValue } from '../helpers/attributesView';
import { withAsyncMount } from '../HOCs/withAsyncMount';
import { withContext } from '../HOCs/withContext';
import { ProfilePerspectiveViewContext } from '../contexts/ProfilePerspectiveViewContext';
import { ScrollToElementContext, isHighlightedErrorType } from '../contexts/ScrollToElementContext';
import { useMdmDependentLookupEditorContext } from '../contexts/MdmModuleContext';
import { useScrollToAttributeError } from '../hooks/useScrollToAttributeError';
import { useAutopopulationContextValue } from './useAutopopulationContextValue';
import { useAttributeValuePermissions } from './useAttributeValuePermissions';
import { DependentLookupAutopopulationContext } from '../contexts/DependentLookupAutopopulationContext';
import { useStyles } from './styles';
import { AddressAutoCompleteContext } from '../contexts/AutoCompleteContext';
import { AttributeValueContext } from '../contexts/AttributeValueContext';
import { AuthoringPerspectiveViewContext } from '../contexts/AuthoringPerspectiveViewContext';
var AsyncMountPlaceholder = function () {
    var styles = useStyles();
    return React.createElement("div", { className: styles.placeholder });
};
var SimpleAttributeEditor = function (_a) {
    var _b, _c;
    var _d;
    var className = _a.className, attributeValue = _a.attributeValue, attributeType = _a.attributeType, isReltioCrosswalk = _a.isReltioCrosswalk, ownError = _a.ownError, mode = _a.mode, onAddOneMore = _a.onAddOneMore, onDeleteAttribute = _a.onDeleteAttribute, onChangeAttribute = _a.onChangeAttribute, onDeactivateError = _a.onDeactivateError, additionalControlsRenderer = _a.additionalControlsRenderer, state = _a.state, highlightedError = _a.highlightedError, _e = _a.isEmptyEditor, isEmptyEditor = _e === void 0 ? false : _e, isFirstEditor = _a.isFirstEditor, otherProps = __rest(_a, ["className", "attributeValue", "attributeType", "isReltioCrosswalk", "ownError", "mode", "onAddOneMore", "onDeleteAttribute", "onChangeAttribute", "onDeactivateError", "additionalControlsRenderer", "state", "highlightedError", "isEmptyEditor", "isFirstEditor"]);
    var styles = useStyles();
    var deleted = state === 'deleted';
    var edited = state === 'edited';
    var isEditableMode = checkIsEditableMode(mode);
    var _f = useAttributeValuePermissions({
        attributeValue: attributeValue,
        attributeType: attributeType,
        mode: mode,
        isReltioCrosswalk: isReltioCrosswalk
    }), canCreate = _f.canCreate, canEdit = _f.canEdit, canDelete = _f.canDelete;
    var showToEdit = canEdit && isEditableMode && !attributeValue.masked;
    var errorMessage = getErrorMessage(ownError);
    var dependentLookupEditorContext = useMdmDependentLookupEditorContext(attributeValue, attributeType);
    var isAutocompleteTriggerAttribute = useContextSelector(AddressAutoCompleteContext, function (c) { return c === null || c === void 0 ? void 0 : c.isAutocompleteTriggerAttribute; });
    var _g = useScrollToAttributeError({ highlightedError: highlightedError, isSimple: true }), ref = _g.ref, errorClassName = _g.errorClassName;
    useEffect(function () {
        // when editor is empty but has default lookup code, onChangeAttribute will be called by useLookupsResolver
        if (isEmptyEditor && isDependentLookupAttrType(attributeType) && !has('lookupCode', attributeValue)) {
            onChangeAttribute({
                attributeType: attributeType,
                uri: attributeValue.uri,
                value: attributeValue.value,
                silent: true
            });
        }
    }, [isEmptyEditor]);
    var dataTypeDefinition = useMemo(function () {
        var dataTypeDefinition = getAttrDataTypeDefinition(attributeType);
        if (isFirstEditor && (isAutocompleteTriggerAttribute === null || isAutocompleteTriggerAttribute === void 0 ? void 0 : isAutocompleteTriggerAttribute(attributeType))) {
            return __assign(__assign({}, dataTypeDefinition), { type: DataTypes.TYPE_ADDRESS_AUTOCOMPLETE });
        }
        return dataTypeDefinition;
    }, [attributeType, isAutocompleteTriggerAttribute, isFirstEditor]);
    var value = useMemo(function () { return attributeValueToEditorValue(attributeValue, dataTypeDefinition); }, [attributeValue, dataTypeDefinition]);
    var deactivateError = useCallback(function () {
        if (ownError) {
            onDeactivateError(getErrorId(ownError));
        }
    }, [ownError, onDeactivateError]);
    var onValueEditorChange = useCallback(pipe(prepareChangeData(attributeValue, attributeType), onChangeAttribute, deactivateError), [attributeValue, attributeType, onChangeAttribute, deactivateError]);
    var onDelete = function () {
        onDeleteAttribute({ uri: attributeValue.uri, attributeType: attributeType });
        if (getErrorType(ownError) !== ErrorType.missed) {
            deactivateError();
        }
    };
    var maxCardinalityIsOne = ((_d = attributeType === null || attributeType === void 0 ? void 0 : attributeType.cardinality) === null || _d === void 0 ? void 0 : _d.maxValue) === 1;
    var showAddButton = !!onAddOneMore &&
        canCreate &&
        !attributeType.singleValue &&
        !attributeValue.masked &&
        mode !== Mode.Viewing &&
        !maxCardinalityIsOne;
    var showDeleteButton = !deleted && !!onDeleteAttribute && canDelete && !attributeValue.masked && mode !== Mode.Viewing;
    var hasError = !!errorMessage;
    var deletedProps = deleted ? { disabled: true, isCrossedOut: true } : {};
    var isProfilePerspectiveView = useContext(ProfilePerspectiveViewContext);
    var isAuthoringPerspectiveView = useContext(AuthoringPerspectiveViewContext);
    var isEntityPerspectiveView = isProfilePerspectiveView || isAuthoringPerspectiveView;
    var autopopulationContextValue = useAutopopulationContextValue({
        enabled: isEntityPerspectiveView && isDependentLookupAttrType(attributeType),
        attributeTypeUri: attributeType === null || attributeType === void 0 ? void 0 : attributeType.uri,
        valueUri: attributeValue.uri
    }).autopopulationContextValue;
    return (React.createElement("div", { ref: ref, "data-reltio-id": "simple-attribute-editor", className: classnames(styles.editor, className, errorClassName) },
        React.createElement(ErrorWrapper, { errorMessage: errorMessage, className: styles.errorWrapper },
            React.createElement("div", { className: classnames(styles['editor-value'], (_b = {}, _b[styles.deleted] = deleted, _b), (_c = {}, _c[styles['editor-read-only-value']] = !showToEdit, _c)), "data-reltio-id": "reltio-attribute-value" }, showToEdit ? (React.createElement(DependentLookupAutopopulationContext.Provider, { value: autopopulationContextValue },
                React.createElement(AttributeValueContext.Provider, { value: attributeValue },
                    React.createElement(DataTypeValueEditor, __assign({ fieldName: attributeUriToSearchUri(attributeType.uri), value: value, dataTypeDefinition: dataTypeDefinition, error: hasError, onChange: onValueEditorChange, fullWidth: true }, dependentLookupEditorContext, otherProps, deletedProps))))) : (React.createElement(DataTypeValue, { value: getAttributeValue(attributeValue), dataTypeDefinition: dataTypeDefinition })))),
        React.createElement("div", { "data-reltio-id": "reltio-attribute-actions", className: styles['editor-actions'] },
            edited && (React.createElement(Typography, { variant: "caption", className: styles.editedLabel },
                "(",
                i18n.text('edited'),
                ")")),
            showAddButton && (React.createElement(SmallIconButton, { icon: AddIcon, onClick: onAddOneMore, size: "L", className: classnames(styles.addButton, styles.button), "data-reltio-id": "reltio-add-one-more-simple-attribute-button" })),
            additionalControlsRenderer && additionalControlsRenderer({ attributeType: attributeType, attributeValue: attributeValue }),
            showDeleteButton && (React.createElement(SmallIconButton, { className: styles.button, icon: DeleteIcon, onClick: onDelete, size: "L", "data-reltio-id": "reltio-delete-simple-attribute-button" })))));
};
var SimpleAttributeEditorWithScrollToElementContext = withContext(ScrollToElementContext, function (contextValue, _a) {
    var attributeValue = _a.attributeValue;
    var _b = contextValue || {}, element = _b.element, type = _b.type;
    var isHighlighted = isHighlightedErrorType(type) && (element === null || element === void 0 ? void 0 : element.uri) === attributeValue.uri;
    return { highlightedError: isHighlighted ? contextValue : null };
}, SimpleAttributeEditor);
export default withAsyncMount(SimpleAttributeEditorWithScrollToElementContext, AsyncMountPlaceholder);
