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 __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
import { DataTypes, DCROperationTypes } from '@reltio/mdm-sdk';
import { prepareChangesList } from './changesList';
import { addressDeepNestedRefPropagationChanges, addressDeepNestedThreeLevelChanges, affiliationsChangeRow, deepNestedInnerChangeRow, deepNestedParentFromChildChanges, deepNestedRowWithExistingPath } from './changesList.test-data';
var createDiff = function (overrides) {
    if (overrides === void 0) { overrides = {}; }
    return (__assign({ level: 0, label: 'Test', attributeType: {
            uri: 'configuration/entityTypes/HCP/attributes/Name',
            name: 'Name',
            label: 'Name',
            type: 'String'
        } }, overrides));
};
var createTitle = function (label) { return ({ label: label }); };
describe('prepareChangesList', function () {
    describe('filterImageSubAttributes', function () {
        it('should filter sub-attributes of image type attributes', function () {
            var imageAttr = createDiff({
                level: 0,
                label: 'Photo',
                attributeType: {
                    uri: 'attr/Photo',
                    name: 'Photo',
                    label: 'Photo',
                    type: DataTypes.TYPE_IMAGE
                }
            });
            var imageSub1 = createDiff({ level: 1, label: 'FileName' });
            var imageSub2 = createDiff({ level: 1, label: 'FileSize' });
            var normalAttr = createDiff({ level: 0, label: 'Name' });
            var result = prepareChangesList([imageAttr, imageSub1, imageSub2, normalAttr]);
            var labels = result.map(function (item) { return item.label; });
            expect(labels).toContain('Photo');
            expect(labels).toContain('Name');
            expect(labels).not.toContain('FileName');
            expect(labels).not.toContain('FileSize');
        });
        it('should keep non-image nested attributes and their children unchanged', function () {
            var nested = createDiff({
                level: 0,
                label: 'Details',
                attributeType: { uri: 'attr/Details', name: 'Details', label: 'Details', type: 'Nested' }
            });
            var child = createDiff({ level: 1, label: 'Notes' });
            var result = prepareChangesList([nested, child]);
            expect(result).toHaveLength(2);
        });
        it('should reset image skip when a Title item is encountered', function () {
            var imageAttr = createDiff({
                level: 0,
                label: 'Photo',
                attributeType: {
                    uri: 'attr/Photo',
                    name: 'Photo',
                    label: 'Photo',
                    type: DataTypes.TYPE_IMAGE
                }
            });
            var imageSub = createDiff({ level: 1, label: 'FileName' });
            var title = createTitle('Section');
            var normalAttr = createDiff({ level: 1, label: 'Name' });
            var result = prepareChangesList([imageAttr, imageSub, title, normalAttr]);
            var labels = result.map(function (item) { return item.label; });
            expect(labels).toEqual(['Photo', 'Section', 'Name']);
        });
    });
    describe('displayOptions', function () {
        it('should set showLabel=true for first ADDED item in a group', function () {
            var _a, _b;
            var attrType = {
                uri: 'configuration/entityTypes/HCP/attributes/Name',
                name: 'Name',
                label: 'Name',
                type: 'String'
            };
            var diff1 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType, level: 0 });
            var diff2 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType, level: 0 });
            var result = prepareChangesList([diff1, diff2]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.showLabel).toBe(true);
            expect((_b = result[1].displayOptions) === null || _b === void 0 ? void 0 : _b.showLabel).toBe(false);
        });
        it('should set showAddButton=true only for last ADDED item in group of multi-value attr', function () {
            var _a, _b;
            var attrType = {
                uri: 'configuration/entityTypes/HCP/attributes/Name',
                name: 'Name',
                label: 'Name',
                type: 'String'
            };
            var diff1 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType, level: 0 });
            var diff2 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType, level: 0 });
            var result = prepareChangesList([diff1, diff2]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.showAddButton).toBe(false);
            expect((_b = result[1].displayOptions) === null || _b === void 0 ? void 0 : _b.showAddButton).toBe(true);
        });
        it('should set showAddButton=false for single-value attributes', function () {
            var _a;
            var attrType = {
                uri: 'configuration/entityTypes/HCP/attributes/Id',
                name: 'Id',
                label: 'Id',
                type: 'String',
                singleValue: true
            };
            var diff = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType, level: 0 });
            var result = prepareChangesList([diff]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.showAddButton).toBe(false);
        });
        it('should set showAddButton=false for role and tag attributes', function () {
            var _a, _b;
            var roleType = { uri: 'roles', name: 'roles', label: 'Roles', type: 'String' };
            var tagType = { uri: 'tags', name: 'tags', label: 'Tags', type: 'String' };
            var diff1 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: roleType, level: 0 });
            var diff2 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: tagType, level: 0 });
            var result = prepareChangesList([diff1, diff2]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.showAddButton).toBe(false);
            expect((_b = result[1].displayOptions) === null || _b === void 0 ? void 0 : _b.showAddButton).toBe(false);
        });
        it('should set showLabel=true and showAddButton=false for non-ADDED non-EDITED operations', function () {
            var _a, _b;
            var diff = createDiff({ operation: DCROperationTypes.DELETED, level: 0 });
            var result = prepareChangesList([diff]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.showLabel).toBe(true);
            expect((_b = result[0].displayOptions) === null || _b === void 0 ? void 0 : _b.showAddButton).toBe(false);
        });
        it('should set showLabel=false for EDITED operations', function () {
            var _a;
            var diff = createDiff({ operation: DCROperationTypes.EDITED, level: 0 });
            var result = prepareChangesList([diff]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.showLabel).toBe(false);
        });
        it('should set showAddButton=false for cardinality maxValue=1 attributes', function () {
            var _a;
            var attrType = {
                uri: 'configuration/entityTypes/HCP/attributes/Single',
                name: 'Single',
                label: 'Single',
                type: 'String',
                cardinality: { maxValue: 1 }
            };
            var diff = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType, level: 0 });
            var result = prepareChangesList([diff]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.showAddButton).toBe(false);
        });
        it('should set hasSameAttributeSiblings=true for all items in a multi-value ADDED group', function () {
            var _a, _b;
            var attrType = {
                uri: 'configuration/entityTypes/HCP/attributes/Name',
                name: 'Name',
                label: 'Name',
                type: 'String'
            };
            var diff1 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType, level: 0 });
            var diff2 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType, level: 0 });
            var result = prepareChangesList([diff1, diff2]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.hasSameAttributeSiblings).toBe(true);
            expect((_b = result[1].displayOptions) === null || _b === void 0 ? void 0 : _b.hasSameAttributeSiblings).toBe(true);
        });
        it('should set hasSameAttributeSiblings=false for a single ADDED item', function () {
            var _a;
            var attrType = {
                uri: 'configuration/entityTypes/HCP/attributes/Name',
                name: 'Name',
                label: 'Name',
                type: 'String'
            };
            var diff = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType, level: 0 });
            var result = prepareChangesList([diff]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.hasSameAttributeSiblings).toBe(false);
        });
        it('should set hasSameAttributeSiblings=false for ADDED items with different attribute URIs', function () {
            var _a, _b;
            var attrType1 = {
                uri: 'configuration/entityTypes/HCP/attributes/Name',
                name: 'Name',
                label: 'Name',
                type: 'String'
            };
            var attrType2 = {
                uri: 'configuration/entityTypes/HCP/attributes/Email',
                name: 'Email',
                label: 'Email',
                type: 'String'
            };
            var diff1 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType1, level: 0 });
            var diff2 = createDiff({ operation: DCROperationTypes.ADDED, attributeType: attrType2, level: 0 });
            var result = prepareChangesList([diff1, diff2]);
            expect((_a = result[0].displayOptions) === null || _a === void 0 ? void 0 : _a.hasSameAttributeSiblings).toBe(false);
            expect((_b = result[1].displayOptions) === null || _b === void 0 ? void 0 : _b.hasSameAttributeSiblings).toBe(false);
        });
    });
    describe('fillParentPaths', function () {
        it('fills parent without attributePath from descendant when value is not inner DCR change', function () {
            var result = prepareChangesList(deepNestedParentFromChildChanges());
            expect(result[0].attributePath).toBe('DeepNested/2ph3uHFx');
        });
        it('fills nested-in-nested parents without paths when only leaf has attributePath (reverse pass)', function () {
            var result = prepareChangesList(addressDeepNestedThreeLevelChanges());
            expect(result[0].attributePath).toBe('DeepNested/4FcgXO5o');
            expect(result[1].attributePath).toBe('DeepNested/4FcgXO5o/SecondLevelNested/2v13QcOX');
        });
        it('fills path from attributeValue.value when inner change carries attributePath', function () {
            var result = prepareChangesList(deepNestedInnerChangeRow());
            expect(result[0].attributePath).toBe('DeepNested/4FcgXO5o/SecondLevelNested');
            expect(result[0].refAttributeType).toBe('configuration/entityTypes/HCP/attributes/Address/attributes/DeepNested/attributes/SecondLevelNested');
            expect(result[0].refObjectURI).toBe('relations/0LbuUWU');
        });
        it('fills parent path and ref fields via descendant when inner change path is absent', function () {
            var result = prepareChangesList(addressDeepNestedRefPropagationChanges());
            expect(result[0].attributePath).toBe('DeepNested/2ph3uHFx');
            expect(result[0].refAttributeType).toBe('configuration/entityTypes/HCP/attributes/Address/attributes/DeepNested');
            expect(result[0].refObjectURI).toBe('relations/0LbuUWU');
        });
        it('does not change attributePath when already set on complex row', function () {
            var result = prepareChangesList(deepNestedRowWithExistingPath());
            expect(result[0].attributePath).toBe('DeepNested/2ph3uHFx');
        });
        it('leaves reference row paths unset and still fills following nested rows', function () {
            var _a, _b, _c;
            var affOnly = prepareChangesList([affiliationsChangeRow]);
            expect(affOnly).toHaveLength(1);
            var aff = affOnly[0];
            expect(aff.attributePath).toBeUndefined();
            expect((_a = aff.displayOptions) === null || _a === void 0 ? void 0 : _a.showLabel).toBe(false);
            expect((_b = aff.displayOptions) === null || _b === void 0 ? void 0 : _b.showAddButton).toBe(false);
            expect((_c = aff.displayOptions) === null || _c === void 0 ? void 0 : _c.hasSameAttributeSiblings).toBe(false);
            var combined = prepareChangesList(__spreadArray([affiliationsChangeRow], deepNestedParentFromChildChanges(), true));
            expect(combined).toHaveLength(3);
            expect(combined[0].attributePath).toBeUndefined();
            expect(combined[1].attributePath).toBe('DeepNested/2ph3uHFx');
            expect(combined[0].operation).toBe(DCROperationTypes.EDITED);
        });
    });
});
