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 i18n from 'ui-i18n';
import { assoc, chain, curry, descend, filter, find, flatten, isNil, last, map, pathOr, pickBy, pipe, prop, propEq, propOr, reduce, reject, sortWith, uniq, uniqBy, values } from 'ramda';
import { areOneHierarchyUris, DataTypes, findValueInAttributesByUriSuffix, getBaseUri, getCrosswalksTypes, getDefaultSurvivorshipStrategy, getLastUriPart, getReferencedAttrTypeUrisFromAttrType, getSurvivorshipStrategy, isComplexAttribute, isOv, isReference, isTempUri, ParticipationStatus } from '@reltio/mdm-sdk';
import { HeadCellRenderer } from './components/HeadCellRenderer';
import { AttributesHeadCellRenderer } from './components/AttributesHeadCellRenderer';
import { DefaultCellValueRenderer } from './components/DefaultCellValueRenderer';
import { AttributeValuesRenderer } from './components/AttributeValuesRenderer';
import { OvValuesRenderer } from './components/OvValuesRenderer';
import { CountRenderer } from './components/CountRenderer';
import { RuleTypeRenderer } from './components/RuleTypeRenderer';
import { WinnerSourcesRenderer } from './components/WinnerSourcesRenderer';
export var COLUMNS_DATA = [
    {
        id: 'ovValues',
        get label() {
            return i18n.text('Attributes & OV');
        },
        hideable: false,
        initialWidth: 360,
        minWidth: 250
    },
    {
        id: 'winnerSources',
        get label() {
            return i18n.text('Winner source systems');
        },
        initialWidth: 220
    },
    {
        id: 'ruleType',
        get label() {
            return i18n.text('Rule type');
        },
        initialWidth: 200
    },
    {
        id: 'count',
        get label() {
            return i18n.text('Count');
        },
        initialWidth: 80,
        minWidth: 80
    },
    {
        id: 'values',
        get label() {
            return i18n.text('Attribute values');
        },
        hideable: false
    }
];
var isOvValue = function (value) { return isOv(value) && !isTempUri(value.uri); };
export var DEFAULT_VISIBLE_COLUMNS = ['ovValues', 'ruleType', 'values'];
var getCellValueRenderer = function (columnId) {
    switch (columnId) {
        case 'ovValues':
            return OvValuesRenderer;
        case 'values':
            return AttributeValuesRenderer;
        case 'count':
            return CountRenderer;
        case 'ruleType':
            return RuleTypeRenderer;
        case 'winnerSources':
            return WinnerSourcesRenderer;
        default:
            return DefaultCellValueRenderer;
    }
};
export var countAttributeValues = function (type, values, crosswalksMap) {
    if (values === void 0) { values = []; }
    switch (type) {
        case DataTypes.TYPE_REFERENCE:
        case DataTypes.TYPE_NESTED:
        case DataTypes.TYPE_IMAGE:
            return values.length;
        default:
            return values.reduce(function (acc, value) { return acc + pathOr(0, [value.uri, 'length'], crosswalksMap); }, 0);
    }
};
var isSourceSystemRule = function (ruleType) {
    return (ruleType === null || ruleType === void 0 ? void 0 : ruleType.uri) === 'configuration/survivorshipStrategies/SRC_SYS';
};
var isOtherAttributeWinnerRule = function (ruleType) {
    return (ruleType === null || ruleType === void 0 ? void 0 : ruleType.uri) === 'configuration/survivorshipStrategies/OtherAttributeWinnerCrosswalk';
};
var isMinMaxValueRule = function (ruleType) {
    return (ruleType === null || ruleType === void 0 ? void 0 : ruleType.uri) === 'configuration/survivorshipStrategies/MinValue' ||
        (ruleType === null || ruleType === void 0 ? void 0 : ruleType.uri) === 'configuration/survivorshipStrategies/MaxValue';
};
var getSourcesUriOrderFromMetadata = pipe(getCrosswalksTypes, sortWith([descend(propOr(-1, 'priority'))]), map(prop('uri')));
var fixReferencedAttributeUri = curry(function (parentType, attrTypeUri) {
    if (isReference(parentType) && attrTypeUri) {
        var referencedAttrUri = pipe(getReferencedAttrTypeUrisFromAttrType, find(function (uri) { return uri.slice(getBaseUri(uri).length) === attrTypeUri.slice(parentType.uri.length); }))(parentType);
        return referencedAttrUri || attrTypeUri;
    }
    else {
        return attrTypeUri;
    }
});
export var collectRuleNames = function (rule) {
    if (!rule) {
        return [];
    }
    if (typeof rule === 'string') {
        return [rule];
    }
    var entries = Object.entries(rule);
    return entries.flatMap(function (_a) {
        var key = _a[0], value = _a[1];
        return __spreadArray([key], value.flatMap(collectRuleNames), true);
    });
};
export var getFallbackLabels = function (metadata, ovDetails) {
    if ((ovDetails === null || ovDetails === void 0 ? void 0 : ovDetails.participationStatus) && ovDetails.participationStatus !== ParticipationStatus.Strategy) {
        return [];
    }
    var appliedRules = ovDetails === null || ovDetails === void 0 ? void 0 : ovDetails.appliedSurvivorshipRules;
    var rules = collectRuleNames(appliedRules);
    if (rules.length <= 1) {
        return [];
    }
    return rules.map(function (uri) { var _a; return ((_a = getSurvivorshipStrategy(metadata, uri)) === null || _a === void 0 ? void 0 : _a.label) || uri; });
};
var getStrategyAdditionalFields = function (metadata, strategy, mapping, attributeType, currentSurvivorshipGroup) {
    var fixUri = fixReferencedAttributeUri(attributeType);
    var primaryAttributeUri = isOtherAttributeWinnerRule(strategy) ? fixUri(mapping === null || mapping === void 0 ? void 0 : mapping.primaryAttributeUri) : undefined;
    var comparisonAttributeUri = isComplexAttribute(attributeType) && isMinMaxValueRule(strategy)
        ? fixUri(mapping === null || mapping === void 0 ? void 0 : mapping.comparisonAttributeUri)
        : undefined;
    var sourcesUriOrder = isSourceSystemRule(strategy)
        ? uniq(__spreadArray(__spreadArray(__spreadArray([], ((mapping === null || mapping === void 0 ? void 0 : mapping.sourcesUriOrder) || []), true), ((currentSurvivorshipGroup === null || currentSurvivorshipGroup === void 0 ? void 0 : currentSurvivorshipGroup.sourcesUriOrder) || []), true), getSourcesUriOrderFromMetadata(metadata), true))
        : undefined;
    return {
        primaryAttributeUri: primaryAttributeUri,
        comparisonAttributeUri: comparisonAttributeUri,
        sourcesUriOrder: sourcesUriOrder
    };
};
var getAppliedSurvivorshipRules = function (metadata, mapping, attributeType, attributeValues, currentSurvivorshipGroup) {
    if (isComplexAttribute(attributeType) || !attributeValues) {
        return [];
    }
    return pipe(filter(isOvValue), map(function (value) {
        var ovDetails = value.ovDetails;
        if (!ovDetails || !ovDetails.appliedSurvivorshipRules) {
            return null;
        }
        if (ovDetails.participationStatus === ParticipationStatus.Strategy) {
            return { type: 'rule', data: ovDetails.appliedSurvivorshipRules, valueUri: value.uri };
        }
        return { type: 'status', data: ovDetails.participationStatus, valueUri: value.uri };
    }), reject(isNil), map(function (ruleOrStatus) {
        if (ruleOrStatus.type === 'status') {
            return ruleOrStatus;
        }
        var appliedRules = collectRuleNames(ruleOrStatus.data);
        var lastRule = getSurvivorshipStrategy(metadata, last(appliedRules));
        return lastRule
            ? {
                type: 'rule',
                valueUri: ruleOrStatus.valueUri,
                data: __assign({ strategy: lastRule }, getStrategyAdditionalFields(metadata, lastRule, mapping, attributeType, currentSurvivorshipGroup))
            }
            : null;
    }), reject(isNil))(attributeValues);
};
export var getRuleTypeValues = function (metadata, attributeType, parentTypeUri, attributeValues, activeSurvivorshipGroupUri) {
    var _a, _b, _c, _d;
    var parentType = __spreadArray(__spreadArray([], metadata.entityTypes, true), (metadata.relationTypes || []), true).find(propEq('uri', parentTypeUri));
    var survivorshipGroups = (_a = parentType === null || parentType === void 0 ? void 0 : parentType.survivorshipGroups) !== null && _a !== void 0 ? _a : [];
    var currentSurvivorshipGroup = (activeSurvivorshipGroupUri && survivorshipGroups.find(propEq('uri', activeSurvivorshipGroupUri))) ||
        survivorshipGroups.find(propEq('default', true));
    var mapping = (_b = currentSurvivorshipGroup === null || currentSurvivorshipGroup === void 0 ? void 0 : currentSurvivorshipGroup.mapping) === null || _b === void 0 ? void 0 : _b.find(propEq('attribute', attributeType.uri));
    var defaultRuleType = getSurvivorshipStrategy(metadata, mapping === null || mapping === void 0 ? void 0 : mapping.survivorshipStrategy) || getDefaultSurvivorshipStrategy(metadata);
    var appliedSurvivorshipRules = getAppliedSurvivorshipRules(metadata, mapping, attributeType, attributeValues, currentSurvivorshipGroup);
    if (appliedSurvivorshipRules.length > 0) {
        return { ruleTypes: appliedSurvivorshipRules };
    }
    return {
        ruleTypes: [
            {
                type: 'rule',
                valueUri: (_d = (_c = attributeValues === null || attributeValues === void 0 ? void 0 : attributeValues[0]) === null || _c === void 0 ? void 0 : _c.uri) !== null && _d !== void 0 ? _d : '',
                data: __assign({ strategy: defaultRuleType }, getStrategyAdditionalFields(metadata, defaultRuleType, mapping, attributeType, currentSurvivorshipGroup))
            }
        ]
    };
};
export var getWinnerCrosswalks = function (attributeValues, crosswalksMap) {
    if (attributeValues === void 0) { attributeValues = []; }
    return pipe(filter(isOvValue), chain(function (value) {
        return pipe(pickBy(function (_, attrUri) {
            var isInHierarchy = areOneHierarchyUris(attrUri, value.uri);
            var subAttrUriSuffix = isInHierarchy ? attrUri.slice(value.uri.length + 1) : '';
            var subAttrValue = subAttrUriSuffix &&
                findValueInAttributesByUriSuffix(value.value, subAttrUriSuffix);
            return isInHierarchy && (!subAttrValue || isOvValue(subAttrValue));
        }), values, flatten)(crosswalksMap);
    }), uniqBy(prop('uri')))(attributeValues);
};
export var getBasicTableColumnsData = map(function (_a) {
    var id = _a.id, label = _a.label, initialWidth = _a.initialWidth, minWidth = _a.minWidth;
    return ({
        id: id,
        label: label,
        initialWidth: initialWidth,
        minWidth: minWidth,
        autoResize: !initialWidth,
        resizable: true,
        sortable: false,
        headCellRenderer: id === 'ovValues' ? AttributesHeadCellRenderer : HeadCellRenderer,
        rowCellValueRenderer: getCellValueRenderer(id)
    });
});
var getRowValueForColumn = function (columnId, metadata, parentTypeUri, attributeType, crosswalksMap, attributeValues, activeSurvivorshipGroupUri) {
    switch (columnId) {
        case 'ovValues':
            return {
                attributeType: attributeType,
                values: attributeValues === null || attributeValues === void 0 ? void 0 : attributeValues.filter(isOvValue)
            };
        case 'values':
            return {
                attributeType: attributeType,
                attributeValues: attributeValues,
                crosswalksMap: crosswalksMap
            };
        case 'count':
            return countAttributeValues(attributeType.type, attributeValues, crosswalksMap);
        case 'ruleType':
            return getRuleTypeValues(metadata, attributeType, parentTypeUri, attributeValues, activeSurvivorshipGroupUri);
        case 'winnerSources':
            return { crosswalks: getWinnerCrosswalks(attributeValues, crosswalksMap) };
        default:
            return null;
    }
};
export var getBasicTableRowsData = function (metadata, parentTypeUri, attrTypes, columns, crosswalksMap, attributes, activeSurvivorshipGroupUri) {
    if (attrTypes === void 0) { attrTypes = []; }
    return attrTypes.map(function (attributeType) {
        var attrName = getLastUriPart(attributeType.uri);
        var attrValues = attributes[attrName];
        var crosswalksMapForAttribute = isReference(attributeType) ? crosswalksMap.relation : crosswalksMap.entity;
        return pipe(reduce(function (acc, columnId) {
            return assoc(columnId, getRowValueForColumn(columnId, metadata, parentTypeUri, attributeType, crosswalksMapForAttribute, attrValues, activeSurvivorshipGroupUri), acc);
        }, {}), assoc('rawValue', attrValues))(columns);
    });
};
