import React, { useMemo, useState } from 'react';
import { ascend, filter, has, isNil, map, pipe, prop, propEq, without } from 'ramda';
import i18n from 'ui-i18n';
import moment from 'moment';
import { CrosswalksAttrTypes, formatDateTime, getCrosswalksTypes, getSourceSystemLabel, parseTimestamp } from '@reltio/mdm-sdk';
import Typography from '@mui/material/Typography';
import DeleteIcon from '@mui/icons-material/Delete';
import { SimpleDropDownSelector } from '../../../SimpleDropDownSelector';
import { TextEditor } from '../../../TextEditor';
import { ConfirmDeleteDialog } from '../../../ConfirmDeleteDialog';
import { MoreAttributesButton } from '../../../MoreAttributesButton';
import { SmallIconButtonWithTooltip } from '../../../SmallIconButton';
import { SourceIcon } from '../../../SourceIcon';
import { useMdmMetadata } from '../../../contexts/MdmModuleContext';
import { CopyableValueField } from '../CopyableValueField';
import { CrosswalkDateEditor } from '../CrosswalkDateEditor';
import { useStyles } from './styles';
export var CrosswalkAttributes = function (_a) {
    var crosswalk = _a.crosswalk, _b = _a.canEditAttribute, canEditAttribute = _b === void 0 ? true : _b, onEditAttribute = _a.onEditAttribute, onDeleteAttribute = _a.onDeleteAttribute;
    var styles = useStyles();
    var _c = useState([]), addedAttributes = _c[0], setAddedAttributes = _c[1];
    var _d = useState(null), pendingDeletionAttrUri = _d[0], setPendingDeletionAttrUri = _d[1];
    var metadata = useMdmMetadata();
    var isTempCrosswalk = !('uri' in crosswalk);
    var addSelectedAttributes = function (selectedAttributes) {
        if (selectedAttributes.length > 0) {
            setAddedAttributes(function (addedAttributes) { return addedAttributes.concat(map(prop('uri'), selectedAttributes)); });
        }
    };
    var handleDeleteAttribute = function (attributeName) {
        setAddedAttributes(function (addedAttributes) { return without([attributeName], addedAttributes); });
        if (!isNil(crosswalk[attributeName])) {
            onDeleteAttribute(attributeName);
        }
    };
    var attributes = useMemo(function () { return [
        {
            label: CrosswalksAttrTypes.sourceSystems.label,
            uri: 'type'
        },
        {
            label: CrosswalksAttrTypes.value.label,
            uri: 'value'
        },
        {
            label: CrosswalksAttrTypes.sourceTable.label,
            uri: 'sourceTable',
            canBeAdded: isTempCrosswalk,
            canBeDeleted: isTempCrosswalk
        },
        {
            label: CrosswalksAttrTypes.createDate.label,
            uri: 'createDate'
        },
        {
            label: CrosswalksAttrTypes.updateDate.label,
            uri: 'updateDate'
        },
        {
            label: CrosswalksAttrTypes.deleteDate.label,
            uri: 'deleteDate',
            canBeAdded: true,
            canBeDeleted: true
        },
        {
            label: CrosswalksAttrTypes.reltioLoadDate.label,
            uri: 'reltioLoadDate'
        },
        {
            label: CrosswalksAttrTypes.publishDate.label,
            uri: 'sourcePublishDate'
        }
    ]; }, []);
    var extraAttributes = pipe(filter(propEq('canBeAdded', true)), filter(function (item) { return !has(item.uri, crosswalk); }), filter(function (item) { return !addedAttributes.includes(item.uri); }))(attributes);
    var renderAttributeValue = function (attributeName, attributeValue) {
        var _a;
        switch (attributeName) {
            case 'type': {
                var sourceSystemLabel = getSourceSystemLabel(metadata, attributeValue);
                return isTempCrosswalk ? (React.createElement(SimpleDropDownSelector, { label: '', placeholder: attributeValue, className: styles.editor, value: { value: attributeValue, label: sourceSystemLabel }, options: getCrosswalksTypes(metadata)
                        .sort(ascend(prop('label')))
                        .map(function (_a) {
                        var uri = _a.uri, label = _a.label;
                        return ({
                            value: uri,
                            label: label
                        });
                    }), onChange: function (_a) {
                        var value = _a.value;
                        return onEditAttribute(attributeName, value);
                    }, TextFieldProps: {
                        InputProps: {
                            disableUnderline: true
                        },
                        inputProps: (_a = {}, _a['data-reltio-id'] = 'crosswalk-attribute-type-selector', _a)
                    } })) : (React.createElement(React.Fragment, null,
                    React.createElement(SourceIcon, { className: styles.sourceIcon, sourceType: attributeValue }),
                    React.createElement(Typography, { className: styles.text, variant: 'body2' }, sourceSystemLabel)));
            }
            case 'sourceTable':
                return isTempCrosswalk ? (React.createElement(TextEditor, { multiple: false, multiline: false, getValueLabel: undefined, classes: { root: styles.editor }, required: true, variant: "filled", value: attributeValue, onInput: function (e) {
                        return onEditAttribute(attributeName, e.target.value);
                    }, size: "small", InputProps: {
                        disableUnderline: true,
                        classes: { input: styles.input }
                    } })) : (React.createElement(Typography, { className: styles.text, variant: 'body2' }, attributeValue));
            case 'value':
                return isTempCrosswalk ? (React.createElement(TextEditor, { multiple: false, multiline: false, getValueLabel: undefined, classes: { root: styles.editor }, required: true, variant: "filled", value: attributeValue, onInput: function (e) {
                        return onEditAttribute(attributeName, e.target.value);
                    }, size: "small", InputProps: {
                        disableUnderline: true,
                        classes: { input: styles.input }
                    } })) : (React.createElement(CopyableValueField, { value: attributeValue }));
            case 'deleteDate':
                return (React.createElement(CrosswalkDateEditor, { value: attributeValue && moment.utc(parseTimestamp(attributeValue)).valueOf(), onChange: function (value) { return onEditAttribute(attributeName, value === null || value === void 0 ? void 0 : value.toString()); }, classes: { root: styles.editor }, disabled: !canEditAttribute }));
            case 'sourcePublishDate':
            case 'createDate':
            case 'updateDate':
            case 'reltioLoadDate':
                return (React.createElement(Typography, { className: styles.text, variant: 'body2' }, formatDateTime(attributeValue)));
            default:
                return null;
        }
    };
    return (React.createElement(React.Fragment, null,
        extraAttributes.length > 0 && canEditAttribute && (React.createElement(MoreAttributesButton, { label: i18n.text('Add attributes'), onApply: addSelectedAttributes, data: extraAttributes })),
        attributes.map(function (attribute) {
            return attribute.uri in crosswalk || addedAttributes.includes(attribute.uri) ? (React.createElement("div", { key: attribute.uri, className: styles.attributeWrapper },
                React.createElement(Typography, { variant: 'body2', className: styles.attributeTitle }, "".concat(attribute.label, ":")),
                React.createElement("div", { className: styles.attributeValue },
                    renderAttributeValue(attribute.uri, crosswalk[attribute.uri]),
                    attribute.canBeDeleted && (React.createElement(SmallIconButtonWithTooltip, { icon: DeleteIcon, disabled: !canEditAttribute, onClick: function () { return setPendingDeletionAttrUri(attribute.uri); }, size: "XS", tooltipTitle: i18n.text('Delete attribute'), showForDisabled: true }))))) : null;
        }),
        React.createElement(ConfirmDeleteDialog, { open: !!pendingDeletionAttrUri, onClose: function () { return setPendingDeletionAttrUri(null); }, onConfirm: function () { return handleDeleteAttribute(pendingDeletionAttrUri); } })));
};
