"use strict";
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 __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useRelationsLoader = void 0;
var react_1 = require("react");
var ramda_1 = require("ramda");
var ui_i18n_1 = __importDefault(require("ui-i18n"));
var mdm_sdk_1 = require("@reltio/mdm-sdk");
var useSafePromise_1 = require("../useSafePromise");
var usePrevious_1 = require("../usePrevious");
var MdmModuleContext_1 = require("../../contexts/MdmModuleContext");
var buildSuggestedIds = (0, ramda_1.when)(ramda_1.identity, (0, ramda_1.pipe)(mdm_sdk_1.wrapInArrayIfNeeded, ramda_1.length, (0, ramda_1.times)(function (n) { return n + 1; })));
var isValidRequestConfig = function (config) {
    var _a;
    var entry = config;
    while (entry) {
        if (((_a = entry.entityTypes) === null || _a === void 0 ? void 0 : _a.length) === 0) {
            return false;
        }
        entry = entry.nextEntry;
    }
    return true;
};
var useRelationsLoader = function (_a) {
    var sorting = _a.sorting, filter = _a.filter, page = _a.page, rowsPerPage = _a.rowsPerPage, config = _a.config, entity = _a.entity, relationActivityFilter = _a.relationActivityFilter, mode = _a.mode, _b = _a.searchByOv, searchByOv = _b === void 0 ? false : _b, searchRelationsWithFilter = _a.searchRelationsWithFilter, showSnackbarMessage = _a.showSnackbarMessage;
    var _c = (0, react_1.useState)(false), isLoading = _c[0], setIsLoading = _c[1];
    var relationsLoaded = (0, MdmModuleContext_1.useMdmAction)('relationsLoaded');
    var tenant = (0, MdmModuleContext_1.useMdmTenant)();
    var metadata = (0, MdmModuleContext_1.useMdmMetadata)();
    var dtssPath = (0, MdmModuleContext_1.useMdmDtssPath)();
    var _d = (0, MdmModuleContext_1.useMdmGlobalSearchRequestOptions)() || {}, activityFilter = _d.activityFilter, globalFilter = _d.globalFilter;
    var lastLoadedTime = (0, MdmModuleContext_1.useMdmProfileLastLoadedTime)();
    var showMasking = (0, MdmModuleContext_1.useMdmShowMasking)();
    var safePromise = (0, useSafePromise_1.useSafePromise)();
    var processContent = function (content) {
        var filterRelation = (0, ramda_1.pipe)(mdm_sdk_1.getInOutRelationUri, (0, mdm_sdk_1.isAvailableRelationTypeUri)(metadata));
        return (0, ramda_1.evolve)({
            entityTypes: (0, ramda_1.filter)((0, mdm_sdk_1.isAvailableEntityTypeUri)(metadata)),
            inRelations: (0, ramda_1.filter)(filterRelation),
            outRelations: (0, ramda_1.filter)(filterRelation),
            nextEntry: processContent
        })(content);
    };
    var suggested = config.suggested;
    var options = (0, react_1.useMemo)(function () {
        var sendMasked = showMasking && ((0, mdm_sdk_1.hasRelationMasking)(metadata) || (0, mdm_sdk_1.hasAttributeMasking)(metadata)) && mode === mdm_sdk_1.Mode.Viewing;
        return (0, mdm_sdk_1.addRelationMaskingOptions)({ searchByOv: searchByOv, searchRelationsWithFilter: searchRelationsWithFilter }, sendMasked);
    }, [searchByOv, showMasking, metadata, mode, searchRelationsWithFilter]);
    var filters = (0, react_1.useMemo)(function () {
        var _a;
        return (_a = {},
            _a[searchRelationsWithFilter ? 'relationFilter' : 'filter'] = (0, mdm_sdk_1.addGlobalFilterToQuery)(globalFilter, filter) || undefined,
            _a);
    }, [searchRelationsWithFilter, globalFilter, filter]);
    var modeRef = (0, react_1.useRef)(mode);
    modeRef.current = mode;
    var loadRelations = (0, react_1.useCallback)(function () {
        if (entity === null || entity === void 0 ? void 0 : entity.uri) {
            var processedConfig = processContent(config.content);
            var requestConfig_1 = __assign(__assign(__assign({}, processedConfig), { sortBy: sorting === null || sorting === void 0 ? void 0 : sorting.field, order: sorting === null || sorting === void 0 ? void 0 : sorting.order, returnDates: true, returnObjects: true, activeness: {
                    relation: relationActivityFilter || mdm_sdk_1.ActivityFilter.ALL,
                    entity: activityFilter
                }, max: rowsPerPage, offset: page * rowsPerPage, suggested: buildSuggestedIds(suggested) }), filters);
            var configs_1 = [requestConfig_1].concat((0, ramda_1.ifElse)(ramda_1.identity, (0, ramda_1.pipe)(mdm_sdk_1.wrapInArrayIfNeeded, function (suggested) {
                return suggested.map(function (config, i) { return (__assign(__assign({}, config), { id: requestConfig_1.suggested[i] })); });
            }), (0, ramda_1.always)([]))(suggested));
            var emptyResponsePromise_1 = Promise.resolve([{ total: 0 }]);
            var request = (0, ramda_1.cond)([
                [(0, ramda_1.pipe)((0, ramda_1.prop)('uri'), mdm_sdk_1.isTempUri), function () { return emptyResponsePromise_1; }],
                [
                    (0, ramda_1.always)(!isValidRequestConfig(requestConfig_1)),
                    function () {
                        console.warn('Connections request config has "entityTypes": []. Request is blocked.');
                        return emptyResponsePromise_1;
                    }
                ],
                [
                    mdm_sdk_1.isDataTenantEntity,
                    function (entity) {
                        return (0, mdm_sdk_1.getRelationsForDataTenantEntity)({
                            entityUri: entity.uri,
                            configs: configs_1,
                            customerTenant: tenant,
                            dataTenant: entity.dataTenant,
                            dtssPath: dtssPath,
                            options: options
                        });
                    }
                ],
                [ramda_1.T, function (entity) { return (0, mdm_sdk_1.getRelationsForEntity)(entity.uri, configs_1, options); }]
            ]);
            setIsLoading(true);
            safePromise(request(entity))
                .then(function (result) {
                if (!Array.isArray(result)) {
                    throw Error(JSON.stringify(result));
                }
                var _a = result[0], connections = _a.connections, total = _a.total, dataSorted = _a.dataSorted;
                if (dataSorted === false && showSnackbarMessage) {
                    showSnackbarMessage(ui_i18n_1.default.text('This profile contains a large number of relationships. We have disabled filtering and sorting to help optimize performance.'));
                }
                relationsLoaded({ id: config.id, connections: connections, total: total, mode: modeRef.current });
            })
                .catch(function (e) {
                console.warn('Failed to load relations data', e);
                relationsLoaded({ id: config.id, total: 0, connections: [], mode: modeRef.current });
            })
                .finally(function () {
                setIsLoading(false);
            });
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [
        activityFilter,
        metadata,
        config,
        relationsLoaded,
        dtssPath,
        entity === null || entity === void 0 ? void 0 : entity.uri,
        entity === null || entity === void 0 ? void 0 : entity.dataTenant,
        filter,
        globalFilter,
        page,
        relationActivityFilter,
        rowsPerPage,
        safePromise,
        sorting,
        tenant,
        options,
        lastLoadedTime
    ]);
    var isRequestSentRef = (0, react_1.useRef)(false);
    isRequestSentRef.current = false;
    (0, react_1.useEffect)(function () {
        isRequestSentRef.current = true;
        loadRelations();
    }, [loadRelations]);
    var prevMode = (0, usePrevious_1.usePrevious)(mode);
    (0, react_1.useEffect)(function () {
        if (mode === mdm_sdk_1.Mode.Viewing && !isRequestSentRef.current && prevMode !== mode) {
            isRequestSentRef.current = true;
            loadRelations();
        }
    }, [loadRelations, mode, prevMode]);
    return { isLoading: isLoading, reload: loadRelations };
};
exports.useRelationsLoader = useRelationsLoader;
