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 React, { useCallback, useRef, useMemo, memo } from 'react';
import { always, evolve } from 'ramda';
import { SearchOperator, findClosestCommonAncestor, findRegularAttribute, getBaseUri, getEntityType } from '@reltio/mdm-sdk';
import { EmptyStub } from '../EmptyStub';
import { getAttributeSelectorItems } from '../helpers/attributesSelector';
import { getRowsDataFromFilters } from './helpers';
import { AttributesFilterSelector } from '../AttributesFilterSelector';
import { RowActions } from './components/RowActions';
import { QueryBuilderRowsGroup } from '../QueryBuilderRowsGroup';
import { useMdmMetadata } from '../contexts/MdmModuleContext';
import { AttributeSelector } from './components/AttributeSelector';
import { useFilterAutoFocus } from '../hooks/useFilterAutoFocus';
import { AttributesValuesEditor } from '../AttributesValuesEditor';
import styles from './AttributesFiltersBuilder.module.css';
var EMPTY_FILTER = { fieldName: null, filter: null, operator: SearchOperator.and, values: [] };
var EMPTY_OBJECT = {};
var AttributesFiltersBuilder = function (_a) {
    var _b = _a.classes, classes = _b === void 0 ? EMPTY_OBJECT : _b, attributesTypesGroups = _a.attributesTypesGroups, attributesTypesGroupFilter = _a.attributesTypesGroupFilter, filters = _a.filters, onChange = _a.onChange, _c = _a.components, components = _c === void 0 ? EMPTY_OBJECT : _c, onFilterAttributeChange = _a.onFilterAttributeChange;
    var _d = components, CustomValuesEditor = _d.ValuesEditor, CustomFilterSelector = _d.FilterSelector, _e = _d.LogicalOperator, LogicalOperator = _e === void 0 ? EmptyStub : _e;
    var actualFilters = useRef(filters);
    var attributesCountRef = useRef(null);
    var metadata = useMdmMetadata();
    actualFilters.current = filters;
    var rowClasses = useMemo(function () { return ({
        root: styles.root,
        attributeSelectorContainer: classes.attributeSelectorContainer || styles.attrSelector,
        valuesEditorContainer: classes.valuesEditorContainer || '',
        filterSelectorContainer: styles.filterSelector,
        actionsContainer: styles.actionContainer,
        rowActions: styles.rowActions
    }); }, [classes]);
    var currentEntityType = useMemo(function () {
        var entityTypesUris = attributesTypesGroups.map(function (_a) {
            var attributeTypes = _a.attributeTypes;
            var regularAttribute = findRegularAttribute(attributeTypes);
            return regularAttribute ? getBaseUri(regularAttribute.uri) : null;
        });
        var closestEntityTypeAncestorUri = findClosestCommonAncestor(metadata, entityTypesUris);
        return getEntityType(metadata, closestEntityTypeAncestorUri);
    }, [attributesTypesGroups, metadata]);
    var attributeSelectorItemsGroups = useMemo(function () { return getAttributeSelectorItems(metadata, attributesTypesGroups, attributesTypesGroupFilter); }, [metadata, attributesTypesGroups]);
    var rowsData = useMemo(function () { return (filters.length ? getRowsDataFromFilters(filters, attributeSelectorItemsGroups) : []); }, [attributeSelectorItemsGroups, filters]);
    var _f = useFilterAutoFocus(rowsData), attributeFilterRef = _f.attributeFilterRef, lastAttributesCountRef = _f.lastAttributesCountRef;
    attributesCountRef.current = rowsData.length;
    var handleAttributeSelectorOnOpen = useCallback(function () {
        lastAttributesCountRef.current = rowsData.length;
    }, [rowsData.length]);
    var lastRowAttributeSelectorProps = useMemo(function () { return ({
        onOpen: handleAttributeSelectorOnOpen
    }); }, [handleAttributeSelectorOnOpen]);
    var addRowAfterIndex = useCallback(function (index) {
        var newFilters = __spreadArray([], actualFilters.current, true);
        newFilters.splice(index + 1, 0, EMPTY_FILTER);
        onChange(newFilters);
    }, [onChange]);
    var removeRow = useCallback(function (index) {
        var newFilters = __spreadArray([], actualFilters.current, true);
        newFilters.splice(index, 1);
        onChange(newFilters);
    }, [onChange]);
    var duplicateRow = useCallback(function (index) {
        var newFilters = __spreadArray([], actualFilters.current, true);
        newFilters.splice(index + 1, 0, __assign({}, actualFilters.current[index]));
        onChange(newFilters);
    }, [onChange]);
    var changeFilter = useCallback(function (newFilter, id) {
        var _a;
        var newFilters = evolve((_a = {},
            _a[id] = always(newFilter),
            _a), actualFilters.current);
        onChange(newFilters);
    }, [onChange]);
    var addNewFilter = useCallback(function (newFilter) {
        onChange(__spreadArray(__spreadArray([], actualFilters.current, true), [newFilter], false));
    }, [onChange]);
    return (React.createElement(QueryBuilderRowsGroup, { rowClasses: rowClasses, rowsData: rowsData, AttributeSelectorComponent: AttributeSelector, FilterSelectorComponent: CustomFilterSelector || AttributesFilterSelector, ValuesEditorComponent: CustomValuesEditor || AttributesValuesEditor, ActionsComponent: RowActions, LogicOperatorComponent: LogicalOperator, filterSelectorRefIndex: lastAttributesCountRef.current, filterSelectorRef: attributeFilterRef, lastRowAttributeSelectorProps: lastRowAttributeSelectorProps, attributeSelectorItemsGroups: attributeSelectorItemsGroups, entityType: currentEntityType, changeFilter: changeFilter, addNewFilter: addNewFilter, addRowAfterIndex: addRowAfterIndex, removeRow: removeRow, duplicateRow: duplicateRow, onFilterAttributeChange: onFilterAttributeChange }));
};
export default memo(AttributesFiltersBuilder);
