"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);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useAPI = void 0;
var react_1 = require("react");
var mdm_sdk_1 = require("@reltio/mdm-sdk");
var ramda_1 = require("ramda");
var workflow_1 = require("../../features/workflow");
var useHtmlSanitizer_1 = require("../useHtmlSanitizer");
var InterceptHandlersContext_1 = require("../../contexts/InterceptHandlersContext");
var SandboxAPIContext_1 = require("../../contexts/SandboxAPIContext");
var SnackbarContext_1 = require("../../contexts/SnackbarContext");
var MdmModuleContext_1 = require("../../contexts/MdmModuleContext");
var API_1 = require("./API");
var customScript_1 = require("../../helpers/customScript");
var useAPI = function (config) {
    var _a;
    if (config === void 0) { config = {}; }
    var _b = config.action || {}, processApiRequest = _b.processApiRequest, processApiResponse = _b.processApiResponse, platform = _b.platform;
    var _c = (0, react_1.useState)(), html = _c[0], setHtml = _c[1];
    var _d = (0, react_1.useState)([]), listenersToReset = _d[0], setListenersToReset = _d[1];
    var _e = (0, react_1.useState)([]), popupListenersToReset = _e[0], setPopupListenersToReset = _e[1];
    var _f = (0, react_1.useState)(true), visible = _f[0], setVisible = _f[1];
    var _g = (0, react_1.useState)(), popup = _g[0], setPopup = _g[1];
    var _h = (0, react_1.useState)(null), tooltip = _h[0], setTooltip = _h[1];
    var _j = (0, react_1.useState)({}), customStyles = _j[0], setCustomStyles = _j[1];
    var workerRef = (0, react_1.useRef)();
    var entityRef = (0, react_1.useRef)();
    var requestListeners = (0, react_1.useRef)({});
    var responseListeners = (0, react_1.useRef)({});
    var sanitizeHtml = (0, useHtmlSanitizer_1.useHtmlSanitizer)();
    var openSearch = (0, MdmModuleContext_1.useMdmAction)('openSearch');
    var uiPath = (0, MdmModuleContext_1.useMdmUiPath)();
    var tenant = (0, MdmModuleContext_1.useMdmTenant)();
    var workerUrl = (0, customScript_1.getWorkerURL)(uiPath, tenant);
    var showSnackbarMessage = (0, react_1.useContext)(SnackbarContext_1.SnackbarContext);
    var qxApi = (0, react_1.useContext)(SandboxAPIContext_1.SandboxAPIContext);
    var interceptHandlers = (0, react_1.useContext)(InterceptHandlersContext_1.InterceptHandlersContext);
    var workflowCheckPermission = (0, workflow_1.useWorkflowCheckPermission)();
    var metadata = (0, MdmModuleContext_1.useMdmMetadata)();
    var entity = (0, MdmModuleContext_1.useMdmEntity)();
    var apiPath = (0, MdmModuleContext_1.useMdmApiPath)();
    var servicesPath = (0, MdmModuleContext_1.useMdmServicesPath)();
    var reltioPath = (0, MdmModuleContext_1.useMdmReltioPath)();
    var workflowPath = (0, MdmModuleContext_1.useMdmWorkflowPath)();
    var user = (0, MdmModuleContext_1.useMdmUser)();
    var entityUri = (0, MdmModuleContext_1.useMdmEntityUri)();
    var isEditableMode = (0, MdmModuleContext_1.useMdmIsEditableMode)();
    var environment = (0, MdmModuleContext_1.useMdmWorkflowEnvironmentUrl)();
    var searchProviderData = (0, MdmModuleContext_1.useMdmSearchProviderData)();
    var searchQuery = (searchProviderData === null || searchProviderData === void 0 ? void 0 : searchProviderData.type) === 'search' ? (_a = searchProviderData === null || searchProviderData === void 0 ? void 0 : searchProviderData.data) === null || _a === void 0 ? void 0 : _a.query : null;
    var innerText = '';
    var popupText = '';
    var process = function (_a) {
        var task = _a.task, worker = _a.worker;
        if (task) {
            switch (task.action) {
                case mdm_sdk_1.CustomAction.SET_HTML: {
                    var sanitizedHtml = sanitizeHtml(task.params.html);
                    if (task.params.id) {
                        var elem = document.getElementById(task.params.id);
                        if (elem)
                            elem.innerHTML = sanitizedHtml;
                    }
                    else if (innerText !== sanitizedHtml) {
                        innerText = sanitizedHtml;
                        (0, customScript_1.resetHtml)({
                            worker: worker,
                            setTooltip: setTooltip,
                            html: sanitizedHtml,
                            innerText: innerText,
                            setListenersToReset: setListenersToReset,
                            setHtml: setHtml
                        });
                    }
                    break;
                }
                case mdm_sdk_1.CustomAction.SHOW_POPUP: {
                    var sanitizedPopup = sanitizeHtml(task.params);
                    popupText = sanitizedPopup;
                    (0, customScript_1.resetHtml)({
                        worker: worker,
                        setTooltip: setTooltip,
                        html: sanitizedPopup,
                        innerText: popupText,
                        setListenersToReset: setPopupListenersToReset,
                        setHtml: setPopup
                    });
                    break;
                }
                case mdm_sdk_1.CustomAction.HIDE_POPUP: {
                    popupText = '';
                    setPopup(null);
                    break;
                }
                case mdm_sdk_1.CustomAction.SET_VISIBILITY: {
                    if (task.params === 'visible') {
                        setVisible(true);
                        (0, customScript_1.resetHtml)({
                            worker: worker,
                            setTooltip: setTooltip,
                            innerText: innerText,
                            setListenersToReset: setListenersToReset,
                            setHtml: setHtml
                        });
                    }
                    else {
                        setVisible(false);
                    }
                    break;
                }
                case mdm_sdk_1.CustomAction.SET_TOOLTIP: {
                    setTooltip(task.params);
                    break;
                }
                case mdm_sdk_1.CustomAction.SET_HEIGHT: {
                    setCustomStyles(function (prev) { return (__assign(__assign({}, prev), { height: task.params })); });
                    break;
                }
                case mdm_sdk_1.CustomAction.SET_WIDTH: {
                    setCustomStyles(function (prev) { return (__assign(__assign({}, prev), { width: task.params })); });
                    break;
                }
                case mdm_sdk_1.CustomAction.SET_ENABLED: {
                    setCustomStyles(function (prev) {
                        return task.params ? (0, ramda_1.omit)(['pointer-events'], prev) : __assign(__assign({}, prev), { 'pointer-events': 'none' });
                    });
                    break;
                }
                case mdm_sdk_1.CustomAction.LOG: {
                    console.log(task.params); //eslint-disable-line no-console
                    break;
                }
                case mdm_sdk_1.CustomAction.MESSAGE: {
                    showSnackbarMessage(task.params);
                    break;
                }
                case mdm_sdk_1.CustomAction.REQUEST: {
                    var processedTask = (0, customScript_1.getProcessedTask)(task, apiPath, reltioPath, tenant);
                    (0, API_1.processRequest)(__assign({ params: processedTask.params, permissions: config.action.permissions, worker: worker, metadata: metadata, config: config, user: user, servicesPath: servicesPath, apiPath: reltioPath, tenant: tenant, workflowPath: workflowPath, entity: entityRef.current, entityUri: entityUri, environment: environment, query: searchQuery, openSearch: openSearch, workflowCheckPermission: workflowCheckPermission }, qxApi));
                    break;
                }
                case mdm_sdk_1.CustomAction.RETURN_PROCESSED_API_RESPONSE: {
                    var _b = task.params, id = _b.id, data = _b.data;
                    if (responseListeners.current[id]) {
                        responseListeners.current[id].next(data);
                        responseListeners.current = (0, ramda_1.omit)([id], responseListeners.current);
                    }
                    break;
                }
                case mdm_sdk_1.CustomAction.RETURN_PROCESSED_API_REQUEST: {
                    var _c = task.params, id = _c.id, data = _c.data;
                    if (requestListeners.current[id]) {
                        requestListeners.current[id].resolve(data);
                        requestListeners.current = (0, ramda_1.omit)([id], requestListeners.current);
                    }
                    break;
                }
            }
        }
    };
    var setRequestListeners = function (options, next, requestId, resolve) {
        var _a;
        requestListeners.current = __assign(__assign({}, requestListeners.current), (_a = {}, _a[requestId] = { options: options, next: next, id: requestId, resolve: resolve }, _a));
    };
    var setResponseListeners = function (next, responseId) {
        var _a;
        responseListeners.current = __assign(__assign({}, responseListeners.current), (_a = {}, _a[responseId] = { next: next }, _a));
    };
    var requestInterceptor = (0, customScript_1.setUpRequestInterceptor)({
        apiPath: apiPath,
        reltioPath: reltioPath,
        tenant: tenant,
        processApiRequest: processApiRequest,
        workerRef: workerRef,
        setRequestListeners: setRequestListeners
    });
    var responseInterceptor = (0, customScript_1.setUpResponseInterceptor)({
        reltioPath: reltioPath,
        apiPath: apiPath,
        processApiResponse: processApiResponse,
        workerRef: workerRef,
        setResponseListeners: setResponseListeners
    });
    var postEventMessage = function (type, data) {
        var _a;
        (_a = workerRef.current) === null || _a === void 0 ? void 0 : _a.postMessage({ action: 'event', type: type, data: data });
    };
    var pendingInterceptors = (0, react_1.useRef)(false);
    var needDelayedRequestForInterceptors = interceptHandlers &&
        !(0, mdm_sdk_1.isEmptyValue)(config.action) &&
        platform !== mdm_sdk_1.CustomScriptPlatform.CLASSIC &&
        (processApiRequest || processApiResponse);
    if (needDelayedRequestForInterceptors) {
        if (!pendingInterceptors.current && !workerRef.current) {
            interceptHandlers.startInterceptorInit();
            pendingInterceptors.current = true;
        }
    }
    (0, react_1.useEffect)(function () {
        if ((0, customScript_1.isValidCustomScript)(config.action)) {
            workerRef.current = (0, mdm_sdk_1.initializeWebWorker)(workerUrl, process, config);
            if (pendingInterceptors.current) {
                interceptHandlers.finishInterceptorInit();
                pendingInterceptors.current = false;
            }
        }
    }, [config]);
    (0, react_1.useEffect)(function () {
        postEventMessage('updateEntity', entity);
        entityRef.current = entity;
    }, [entity]);
    (0, react_1.useEffect)(function () {
        postEventMessage('editMode', isEditableMode);
    }, [isEditableMode]);
    (0, react_1.useEffect)(function () {
        postEventMessage('changeSearchQuery', searchQuery);
    }, [searchQuery]);
    (0, react_1.useEffect)(function () {
        postEventMessage('changeVisibility', visible);
    }, [visible]);
    (0, react_1.useEffect)(function () { return function () {
        listenersToReset.forEach(function (listener) { return listener(); });
    }; }, [listenersToReset]);
    //we need to have separate handlers in opposite case main window listeners will be removed on the popup appear
    (0, react_1.useEffect)(function () { return function () {
        popupListenersToReset.forEach(function (listener) { return listener(); });
    }; }, [popupListenersToReset, listenersToReset]);
    var onClick = (0, react_1.useCallback)(function () {
        postEventMessage('execute', null);
    }, [config]);
    (0, react_1.useEffect)(function () {
        if (!(0, mdm_sdk_1.isEmptyValue)(interceptHandlers) && (processApiRequest || processApiResponse)) {
            var addInternalRequestInterceptor = interceptHandlers.addInternalRequestInterceptor, addInternalResponseInterceptor = interceptHandlers.addInternalResponseInterceptor, removeInternalRequestInterceptor_1 = interceptHandlers.removeInternalRequestInterceptor, removeInternalResponseInterceptor_1 = interceptHandlers.removeInternalResponseInterceptor;
            addInternalRequestInterceptor(requestInterceptor);
            addInternalResponseInterceptor(responseInterceptor);
            workerRef.current.onerror = function () {
                removeInternalRequestInterceptor_1(requestInterceptor);
                removeInternalResponseInterceptor_1(responseInterceptor);
            };
            return function () {
                removeInternalRequestInterceptor_1(requestInterceptor);
                removeInternalResponseInterceptor_1(responseInterceptor);
            };
        }
    }, [config]);
    return { html: html, visible: visible, tooltip: tooltip, customStyles: customStyles, onClick: onClick, popup: popup };
};
exports.useAPI = useAPI;
