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);
};
import { CustomScriptPlatform, RequestAction, isEmptyValue } from '@reltio/mdm-sdk';
import { nanoid } from 'nanoid';
export var isValidCustomScript = function (config) {
    var _a = config || {}, files = _a.files, platform = _a.platform;
    return !isEmptyValue(files) && platform !== CustomScriptPlatform.CLASSIC;
};
export var isURLtoProcess = function (url, processApi) {
    if (processApi === void 0) { processApi = []; }
    return processApi.some(function (request) {
        var regExp = new RegExp("^".concat(request, "$"));
        return request.replace(/\/*$/, '') === url || (request && regExp.test(url));
    });
};
export var getWorkerURL = function (uiPath, tenant) {
    return "".concat(uiPath.replace("".concat(tenant, "/"), ''), "worker_api.js");
};
export var getRequestFakeUrl = function (url, apiPath, reltioPath, tenant) {
    return url.startsWith(apiPath) ? "".concat(reltioPath).concat(url.replace(apiPath, '')) : "".concat(reltioPath, "/api/").concat(tenant).concat(url);
};
export var getResponseFakeUrl = function (url, apiPath, reltioPath) {
    return "".concat(reltioPath).concat(url.replace(apiPath, ''));
};
export var getProcessedTask = function (task, apiPath, reltioPath, tenant) {
    var _a = task.params, url = _a.url, name = _a.name;
    if (!url) {
        return task;
    }
    var isApiAction = name === RequestAction.API;
    var isGlobalUrl = url.startsWith('/') && !url.startsWith(apiPath);
    var newUrl = isGlobalUrl && isApiAction ? "".concat(apiPath, "/api/").concat(tenant).concat(url) : url.replace(reltioPath, apiPath);
    return __assign(__assign({}, task), { params: __assign(__assign({}, task.params), { url: newUrl, validationUrl: url }) });
};
export var getFilesWithArrayBuffer = function (files) {
    var readFilePromises = Array.from(files).map(function (file) {
        return new Promise(function (resolve, reject) {
            var reader = new FileReader();
            reader.onload = function (event) {
                var content = event.target.result;
                var lastModified = file.lastModified, name = file.name, size = file.size, type = file.type;
                resolve({ lastModified: lastModified, name: name, size: size, type: type, content: content });
            };
            reader.onerror = function (error) {
                reject(error);
            };
            reader.readAsArrayBuffer(file);
        });
    });
    return Promise.all(readFilePromises);
};
var processInnerHtml = function (parent, worker, setTooltip) {
    var handlersToReset = [];
    var uiActions = parent.getAttribute('ui-actions');
    var uiTooltip = parent.getAttribute('ui-tooltip');
    var id = parent.getAttribute('id') || parent.getAttribute('name');
    if (uiActions) {
        uiActions.split(',').forEach(function (uiAction) {
            var handler = function (event) {
                var _a;
                var target = event.target;
                var postEventMessage = function (files) {
                    worker.postMessage({
                        action: 'event',
                        type: 'uiAction',
                        data: { type: uiAction, id: id, event: __assign(__assign({}, event), { files: files, target: { value: target.value } }) }
                    });
                };
                if ((_a = target.files) === null || _a === void 0 ? void 0 : _a.length) {
                    getFilesWithArrayBuffer(target.files).then(postEventMessage);
                }
                else {
                    postEventMessage();
                }
            };
            parent.addEventListener(uiAction, handler);
            handlersToReset.push(function () {
                parent.removeEventListener(uiAction, handler);
            });
        });
        parent.removeAttribute('ui-actions');
    }
    if (uiTooltip) {
        setTooltip(uiTooltip);
    }
    parent.childNodes.forEach(function (child) {
        if (child.nodeType === 1) {
            //Node.ELEMENT_NODE
            handlersToReset = handlersToReset.concat(processInnerHtml(child, worker, setTooltip));
        }
    });
    return handlersToReset;
};
export var resetHtml = function (_a) {
    var worker = _a.worker, setTooltip = _a.setTooltip, innerText = _a.innerText, html = _a.html, setListenersToReset = _a.setListenersToReset, setHtml = _a.setHtml;
    var docBlock = document.createElement('div');
    docBlock.innerHTML = html || innerText;
    var handlersToReset = processInnerHtml(docBlock, worker, setTooltip);
    setListenersToReset(handlersToReset);
    setHtml(docBlock);
};
export var setUpRequestInterceptor = function (_a) {
    var apiPath = _a.apiPath, reltioPath = _a.reltioPath, tenant = _a.tenant, processApiRequest = _a.processApiRequest, workerRef = _a.workerRef, setRequestListeners = _a.setRequestListeners;
    return function (_a) {
        var url = _a.url, next = _a.next, resolve = _a.resolve, _b = _a.options, options = _b === void 0 ? {} : _b;
        var fakeURL = getRequestFakeUrl(url, apiPath, reltioPath, tenant);
        var isProcessableUrl = isURLtoProcess(fakeURL, processApiRequest);
        if (isProcessableUrl) {
            var requestId = nanoid();
            setRequestListeners(options, next, requestId, resolve);
            workerRef.current.postMessage({
                action: 'apiRequest',
                id: requestId,
                url: fakeURL,
                method: options.method,
                headers: options.headers,
                data: options.body
            });
        }
        else {
            next(url, options);
        }
    };
};
export var setUpResponseInterceptor = function (_a) {
    var reltioPath = _a.reltioPath, apiPath = _a.apiPath, processApiResponse = _a.processApiResponse, workerRef = _a.workerRef, setResponseListeners = _a.setResponseListeners;
    return function (_a) {
        var url = _a.url, response = _a.response, next = _a.next, options = _a.options, abort = _a.abort;
        var fakeURL = getResponseFakeUrl(url, apiPath, reltioPath);
        var isProcessableUrl = isURLtoProcess(fakeURL, processApiResponse);
        if (isProcessableUrl) {
            var responseId_1 = nanoid();
            response
                .json()
                .then(function (data) {
                setResponseListeners(next, responseId_1);
                workerRef.current.postMessage({
                    action: 'apiResponse',
                    id: responseId_1,
                    url: fakeURL,
                    method: options.method,
                    data: data
                });
            })
                .catch(function (error) {
                abort(error);
            });
        }
        else {
            next(response);
        }
    };
};
