"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useSettings = exports.SettingsParamToKey = exports.SettingsParamToKey3 = exports.SettingGetAllQueries = exports.SettingGetAllParameters = void 0;
var tslib_1 = require("tslib");
var react_1 = require("react");
var v_eris_1 = require("v-eris");
var notifications_1 = require("../components/Notifications/notifications");
var socket_1 = require("./socket");
var channel_1 = require("./channel");
var SettingsGetValue = function (table, changed, key) {
    if (changed[key] === null) { //force inherit
        return table[key] && table[key].override.length > 1 ?
            (table[key].override[table[key].override.length - 2].value)
            :
                (table[key] ? table[key].value : undefined);
    }
    ;
    return changed[key] === undefined ? (table[key] ? table[key].value : undefined) : changed[key];
};
var SettingsGetSecureValue = function (table, changed, key) {
    var _a;
    if (changed[key] === null) { //force inherit
        return table[key] && table[key].override.length > 1 ?
            (table[key].override[table[key].override.length - 2].valueSecure)
            :
                (table[key] ? table[key].valueSecure : undefined);
    }
    ;
    if (changed[key] === undefined)
        return table[key] ? table[key].valueSecure : undefined;
    if (table[key].query) {
        return tslib_1.__assign(tslib_1.__assign({}, table[key].valueSecure), (_a = {}, _a["table"] = changed[key], _a));
    }
    ;
    return changed[key];
};
var SettingsGetExclusionValue = function (table, changed, key) {
    if (changed[key] === null) { //force inherit
        return table[key] && table[key].override.length > 1 ?
            (table[key].override[table[key].override.length - 2].value)
            :
                (table[key] ? table[key].value : undefined);
    }
    ;
    return changed[key] === undefined ? (table[key] ? table[key].value : undefined) : changed[key];
};
var SettingsSetValue = function (it, table, systemData, changed, key, value, keyIndex) {
    var _a, _b;
    if (value === undefined) {
        delete changed[key];
    }
    else if (table[key].stack) {
        if (value === null) {
            changed[key] = value;
        }
        else {
            var refValue = SettingsGetValue(table, changed, table[key].stack);
            var type = v_eris_1.Common.type(refValue);
            if (type == "number") {
                refValue = v_eris_1.VMath.clamp(v_eris_1.Common.uint(refValue), 0, 255);
            }
            else if (type == "array") {
                refValue = refValue.length;
            }
            else {
                refValue = 0;
            }
            ;
            var object = keyIndex === undefined ?
                (changed[key] ? tslib_1.__assign(tslib_1.__assign({}, table[key].value), changed[key]) : tslib_1.__assign({}, table[key].value))
                :
                    (changed[key] ? tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, table[key].value), changed[key]), (_a = {}, _a[v_eris_1.Common.uint(keyIndex)] = value, _a)) : tslib_1.__assign(tslib_1.__assign({}, table[key].value), (_b = {}, _b[v_eris_1.Common.uint(keyIndex)] = value, _b)));
            changed[key] = [];
            for (var n = 0; n < refValue; n++) {
                changed[key].push(object[n] === undefined ? table[key].systemValue : object[n]);
            }
            ;
        }
        ;
    }
    else {
        changed[key] = value;
    }
    ;
    if (table[key].secureCrossRef) {
        var crossRef = table[table[key].secureCrossRef];
        if (crossRef) {
            SettingsCheckValue(crossRef.key, SettingsGetValue(table, changed, crossRef.key), table, systemData, SettingsGetValue(table, changed, key));
        }
        ;
    }
    ;
    if (it > 50)
        return;
    var refs = [];
    for (var k in table) {
        if (table[k].stack != key)
            continue;
        refs.push(table[k].key);
    }
    ;
    for (var _i = 0, refs_1 = refs; _i < refs_1.length; _i++) {
        var refKey = refs_1[_i];
        SettingsSetValue(it + 1, table, systemData, changed, refKey, table[refKey].value, undefined);
    }
    ;
};
var SettingsCheckValueInherit = function (key, value, table, systemData, crossRefValue) {
    if (!systemData.value[key].secure)
        return;
    var secureRef = table[systemData.value[key].secure];
    if (!secureRef) {
        table[key].valueSecure = value;
        return;
    }
    ;
    var ref = [];
    var defaultValue = "";
    if (crossRefValue !== undefined) {
        secureRef = { valueSecure: crossRefValue };
    }
    ;
    //console.log( 444, key, crossRefValue );
    if (Array.isArray(secureRef.valueSecure)) {
        ref = secureRef.valueSecure;
    }
    else if (secureRef.valueSecure && Array.isArray(secureRef.valueSecure.list)) {
        ref = secureRef.valueSecure.list;
        defaultValue = secureRef.valueSecure.defaultValue;
    }
    ;
    var isSubArray = value && Array.isArray(value.list);
    if (Array.isArray(value) || isSubArray) {
        var list = isSubArray ? value.list : value;
        table[key].valueSecure = isSubArray ? { list: [], defaultValue: value.defaultValue, sort: value.sort } : [];
        var _loop_1 = function (item) {
            if (ref.findIndex(function (f) { return f.key ? (f.key == item) : (f == item); }) < 0) {
                return "continue";
            }
            ;
            //			if( ref.indexOf( item ) < 0 ){
            //				//table[ key ].autoCorrected
            //				continue;
            //			};
            if (isSubArray)
                table[key].valueSecure.list.push(item);
            else
                table[key].valueSecure.push(item);
        };
        for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
            var item = list_1[_i];
            _loop_1(item);
        }
        ;
    }
    else {
        if (ref.findIndex(function (f) { return f == value; }) < 0) {
            table[key].valueSecure = defaultValue && ref.findIndex(function (f) { return f == defaultValue; }) > -1 ? defaultValue : ref[0];
            table[key].autoCorrected = value;
        }
        else {
            table[key].autoCorrected = null;
        }
        ;
    }
    ;
};
var SettingsCheckValue = function (key, value, table, systemData, crossRefValue) {
    //table[ key ].valueSecure = value;	
    //return;
    //#Check if arrayValue still exist in system array
    //console.log( 333, key );
    if (systemData.value[key].query) {
        //if( !systemData.value[ key ].secure ){
        table[key].valueSecure = { list: [], table: {}, ref: {} };
        if (!Array.isArray(table[key].query))
            return;
        var secureRef = systemData.value[key].secure && table[systemData.value[key].secure] ? table[systemData.value[key].secure] : null;
        if (secureRef && secureRef.valueSecure)
            secureRef = secureRef.valueSecure.table ? tslib_1.__assign({}, secureRef.valueSecure.table) : tslib_1.__spreadArray([], secureRef.valueSecure.list, true);
        else
            secureRef = null;
        var isArray = secureRef && Array.isArray(secureRef);
        var index = -1;
        for (var _i = 0, _a = table[key].query; _i < _a.length; _i++) {
            var query = _a[_i];
            index++;
            var r = tslib_1.__assign({}, query);
            r.key = r.token;
            var config = {};
            //console.log( key, value, query.token, secureRef );
            if (value[query.token] && typeof value[query.token] == "object") {
                config = tslib_1.__assign({}, value[query.token]);
            }
            else if (table[key].systemValue && typeof table[key].systemValue == "object") {
                config = tslib_1.__assign({}, table[key].systemValue);
            }
            else {
                config = {};
            }
            ;
            if (secureRef) {
                table[key].valueSecure.ref[query.token] = (isArray ? secureRef[index] : secureRef[query.token]);
            }
            ;
            table[key].valueSecure.table[query.token] = config;
            table[key].valueSecure.list.push(r);
        }
        ;
        //};
        return;
    }
    ;
    if (Array.isArray(systemData.value[key].params)) {
        if (Array.isArray(value)) {
            table[key].valueSecure = [];
            var _loop_2 = function (item) {
                if (systemData.value[key].params.findIndex(function (f) { return f.value == item; }) < 0)
                    return "continue";
                table[key].valueSecure.push(item);
            };
            for (var _b = 0, value_1 = value; _b < value_1.length; _b++) {
                var item = value_1[_b];
                _loop_2(item);
            }
            ;
        }
        else if (v_eris_1.Common.type(value) == "object" && value.list) {
            table[key].valueSecure = { list: [], defaultValue: value.defaultValue, sort: value.sort };
            var _loop_3 = function (item) {
                if (systemData.value[key].params.findIndex(function (f) { return f.value == item; }) < 0)
                    return "continue";
                table[key].valueSecure.list.push(item);
            };
            for (var _c = 0, _d = value.list; _c < _d.length; _c++) {
                var item = _d[_c];
                _loop_3(item);
            }
            ;
            if (systemData.value[key].extra && systemData.value[key].extra.hasDefault && table[key].valueSecure.list.findIndex(function (f) { return f == table[key].valueSecure.defaultValue; }) < 0) {
                table[key].valueSecure.defaultValue = table[key].valueSecure.list[0];
                table[key].autoCorrected = value;
            }
            else {
                table[key].autoCorrected = null;
            }
            ;
            SettingsCheckValueInherit(key, value, table, systemData, crossRefValue);
        }
        else {
            if (systemData.value[key].params.findIndex(function (f) { return f.value == value; }) < 0) {
                table[key].valueSecure = systemData.value[key].params[0] ? systemData.value[key].params[0].value : "";
                table[key].autoCorrected = value;
            }
            else {
                table[key].valueSecure = value;
                table[key].autoCorrected = null;
            }
            ;
            SettingsCheckValueInherit(key, value, table, systemData, crossRefValue);
        }
        ;
    }
    else {
        table[key].valueSecure = value;
    }
    ;
};
var SettingsStacking = function (table, defaultData, systemData, key, queries) {
    var value;
    var isSystem = true;
    if (systemData.value[key].bindless) {
        value = systemData.value[key].value;
    }
    else {
        if (defaultData && defaultData.value && defaultData.value[key] !== undefined) {
            isSystem = false;
            value = defaultData.value[key];
        }
        else {
            value = systemData.value[key].value;
        }
        ;
    }
    ;
    table[key] = {
        value: value,
        valueSecure: null,
        key: key,
        stack: systemData.value[key].stack,
        query: queries.table[key] ? queries.table[key] : null,
        secureCrossRef: null,
        bindless: systemData.value[key].bindless,
        overrideToken: "default",
        desc: systemData.value[key].desc,
        title: systemData.value[key].title,
        systemValue: systemData.value[key].value,
        override: [
            {
                token: "default",
                name: "default",
                isSystem: isSystem,
                type: systemData.value[key].type,
                params: systemData.value[key].params,
                value: value,
                valueSecure: null
            }
        ]
    };
    SettingsCheckValue(key, value, table, systemData);
    table[key].override[0].valueSecure = table[key].valueSecure;
    if (systemData.value[key].secure && table[systemData.value[key].secure])
        table[systemData.value[key].secure].secureCrossRef = key;
};
var SettingsExclusionStacking = function (table, defaultData, systemData, key, subKey) {
    var value;
    var isSystem = true;
    if (defaultData && defaultData.exclusion && defaultData.exclusion[key] !== undefined) {
        isSystem = false;
        value = defaultData.exclusion[key];
    }
    else {
        value = systemData.exclusion[key];
    }
    ;
    table[subKey || key] = {
        value: value,
        key: subKey || key,
        overrideToken: "default",
        systemValue: true,
        override: [
            {
                token: "default",
                name: "default",
                isSystem: isSystem,
                value: value
            }
        ]
    };
};
var SettingsInheritance = function (tree, full) {
    var result = {};
    if (!tree)
        tree = {};
    for (var sectionKey in tree) {
        var section = tree[sectionKey];
        for (var _i = 0, section_1 = section; _i < section_1.length; _i++) {
            var inside = section_1[_i];
            if (!inside.list)
                continue;
            for (var _a = 0, _b = inside.list; _a < _b.length; _a++) {
                var parameter = _b[_a];
                var key = (0, exports.SettingsParamToKey)(sectionKey, inside.key, parameter.key);
                result[key] = full ? parameter : parameter.value;
            }
            ;
        }
        ;
    }
    ;
    return result;
};
var SettingsExclusionInheritance = function (tree, full) {
    var result = {};
    if (!tree)
        tree = {};
    for (var sectionKey in tree) {
        var section = tree[sectionKey];
        result[sectionKey] = true;
        for (var _i = 0, section_2 = section; _i < section_2.length; _i++) {
            var inside = section_2[_i];
            if (!inside.list)
                continue;
            result[(0, exports.SettingsParamToKey3)(sectionKey, inside.key)] = true;
            for (var _a = 0, _b = inside.list; _a < _b.length; _a++) {
                var parameter = _b[_a];
                var key = (0, exports.SettingsParamToKey)(sectionKey, inside.key, parameter.key);
                result[key] = true;
            }
            ;
        }
        ;
    }
    ;
    return result;
};
var SettingsReducer = function (state, _a) {
    var type = _a[0], data = _a[1], data2 = _a[2], queries = _a[3], tree = _a[4];
    if (type == "construct") {
        var table = {};
        var exclusionTable = {};
        var array = tslib_1.__spreadArray([], (Array.isArray(data) ? data : []), true);
        var inheritanceStack = [];
        var systemData = { token: "system", name: "system", value: SettingsInheritance(tree, true), exclusion: SettingsExclusionInheritance(tree, true) };
        var defaultData = array[0];
        var self_1 = data2 ? data2 : false;
        var changed = {};
        for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
            var item = array_1[_i];
            inheritanceStack.push({
                type: item.type,
                name: item.name,
                token: item.token,
                inherit: item.inherit,
                description: item.description,
            });
            if (typeof item.value == "string") {
                try {
                    item.value = JSON.parse(item.value);
                }
                catch (e) { }
                ;
            }
            ;
            if (typeof item.exclusion == "string") {
                try {
                    item.exclusion = JSON.parse(item.exclusion);
                }
                catch (e) { }
                ;
            }
            ;
        }
        ;
        //if( !defaultData || !defaultData.value )
        //	defaultData = systemData;
        for (var key in systemData.value) {
            SettingsStacking(table, defaultData, systemData, key, queries);
        }
        ;
        for (var key in systemData.exclusion) {
            SettingsExclusionStacking(exclusionTable, defaultData, systemData, key);
        }
        ;
        var n = 1;
        var length_1 = array.length;
        for (; n < length_1; n++) {
            var settings = array[n];
            var override = array[n].value || {};
            for (var key in systemData.value) {
                if (systemData.value[key].bindless)
                    continue;
                if (override[key] === undefined || override[key] === null) {
                    if (systemData.value[key].secure) {
                        SettingsCheckValue(key, table[key].value, table, systemData);
                    }
                    ;
                    continue;
                }
                ;
                table[key].value = override[key];
                SettingsCheckValue(key, override[key], table, systemData);
                table[key].desc = systemData.value[key].desc,
                    table[key].title = systemData.value[key].title,
                    table[key].overrideToken = settings.token;
                table[key].override.push({
                    token: settings.token,
                    type: systemData.value[key].type,
                    params: systemData.value[key].params,
                    name: settings.name,
                    value: override[key],
                    valueSecure: table[key].valueSecure
                });
            }
            ;
            override = array[n].exclusion || {};
            for (var key in systemData.exclusion) {
                if (override[key] === undefined || override[key] === null)
                    continue;
                exclusionTable[key].value = override[key];
                exclusionTable[key].overrideToken = settings.token;
                exclusionTable[key].override.push({
                    token: settings.token,
                    name: settings.name,
                    value: override[key]
                });
            }
            ;
        }
        ;
        for (var key in systemData.value) {
            //bindless
            if (systemData.value[key].bindless) {
                changed[key] = state.changed[key];
            }
            ;
            //^
            if (!systemData.value[key].stack)
                continue;
            if (!table[key].override[0].isSystem)
                continue;
            var array_2 = [];
            var refValue = SettingsGetValue(table, state.changed, systemData.value[key].stack);
            var type_1 = v_eris_1.Common.type(refValue);
            if (type_1 == "number") {
                refValue = v_eris_1.VMath.clamp(v_eris_1.Common.uint(refValue), 0, 999);
                for (var n_1 = 0; n_1 < refValue; n_1++) {
                    array_2.push(table[key].systemValue);
                }
                ;
            }
            else if (type_1 == "array") {
                var refLength = refValue.length;
                for (var n_2 = 0; n_2 < refLength; n_2++) {
                    array_2.push(table[key].systemValue);
                }
                ;
            }
            ;
            table[key].override[0].value = array_2;
            if (table[key].override.length > 1)
                continue;
            table[key].value = array_2;
        }
        ;
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, table: table, systemData: systemData, exclusionTable: exclusionTable, inheritanceStack: inheritanceStack, self: self_1, changed: changed, reconstructData: {
                data: data, data2: data2, queries: queries
            }, exclusionChanged: {} });
    }
    else if (type == "change") {
        var changed = tslib_1.__assign({}, state.changed);
        SettingsSetValue(0, state.table, state.systemData, changed, data.key, data.value, data.keyIndex);
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, changed: changed });
    }
    else if (type == "changeExclusion") {
        var exclusionChanged = tslib_1.__assign({}, state.exclusionChanged);
        if (data.value === undefined) {
            delete exclusionChanged[data.key];
        }
        else {
            exclusionChanged[data.key] = data.value;
        }
        ;
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, exclusionChanged: exclusionChanged });
    }
    else if (type == "revert") {
        var changed = tslib_1.__assign({}, state.changed);
        delete changed[data.key];
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, changed: changed });
    }
    else if (type == "revertExclusion") {
        var exclusionChanged = tslib_1.__assign({}, state.exclusionChanged);
        delete exclusionChanged[data.key];
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, exclusionChanged: exclusionChanged });
    }
    ;
    return state;
};
var SettingGetAllParameters = function (tree) {
    var list = [];
    for (var sectionKey in tree) {
        var section = tree[sectionKey];
        for (var _i = 0, section_3 = section; _i < section_3.length; _i++) {
            var inside = section_3[_i];
            if (!inside.list)
                continue;
            for (var _a = 0, _b = inside.list; _a < _b.length; _a++) {
                var parameter = _b[_a];
                var key = (0, exports.SettingsParamToKey)(sectionKey, inside.key, parameter.key);
                list.push(tslib_1.__assign(tslib_1.__assign({}, parameter), { key: key }));
            }
            ;
        }
        ;
    }
    ;
    return list;
};
exports.SettingGetAllParameters = SettingGetAllParameters;
var SettingGetAllQueries = function (tree) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
    var params, table, tableKeys, _i, params_1, parameter, _loop_4, _a, _b, _c, _d, route;
    return tslib_1.__generator(this, function (_e) {
        switch (_e.label) {
            case 0:
                params = (0, exports.SettingGetAllParameters)(tree);
                table = {};
                tableKeys = {};
                for (_i = 0, params_1 = params; _i < params_1.length; _i++) {
                    parameter = params_1[_i];
                    if (!parameter.query)
                        continue;
                    if (!table[parameter.query.route])
                        table[parameter.query.route] = [];
                    table[parameter.query.route].push({ key: parameter.key, data: null });
                }
                ;
                _loop_4 = function (route) {
                    var cfg;
                    return tslib_1.__generator(this, function (_f) {
                        switch (_f.label) {
                            case 0:
                                cfg = {
                                    method: "POST",
                                    url: route + "/list/",
                                    data: null
                                };
                                return [4 /*yield*/, v_eris_1.Request.fetch(cfg)
                                        .then(function (response) {
                                        return response.data;
                                    }).then(function (response) {
                                        for (var _i = 0, _a = table[route]; _i < _a.length; _i++) {
                                            var item = _a[_i];
                                            tableKeys[item.key] = response.data;
                                            item.data = response.data;
                                        }
                                        ;
                                    }).catch(function () { })];
                            case 1:
                                _f.sent();
                                return [2 /*return*/];
                        }
                    });
                };
                _a = table;
                _b = [];
                for (_c in _a)
                    _b.push(_c);
                _d = 0;
                _e.label = 1;
            case 1:
                if (!(_d < _b.length)) return [3 /*break*/, 4];
                _c = _b[_d];
                if (!(_c in _a)) return [3 /*break*/, 3];
                route = _c;
                return [5 /*yield**/, _loop_4(route)];
            case 2:
                _e.sent();
                _e.label = 3;
            case 3:
                _d++;
                return [3 /*break*/, 1];
            case 4:
                ;
                return [2 /*return*/, { queries: table, table: tableKeys }];
        }
    });
}); };
exports.SettingGetAllQueries = SettingGetAllQueries;
var SettingsParamToKey3 = function (sectionItem, partitionKey) {
    //return (sectionKey || "") + ":" + (sectionItem || "") + ":" + partitionKey;
    return (sectionItem || "") + "::" + partitionKey;
};
exports.SettingsParamToKey3 = SettingsParamToKey3;
var SettingsParamToKey = function (sectionItem, partitionKey, itemKey) {
    //return (sectionKey || "") + ":" + (sectionItem || "") + ":" + partitionKey + ":" + itemKey;
    return (sectionItem || "") + "::" + partitionKey + "::" + itemKey;
};
exports.SettingsParamToKey = SettingsParamToKey;
var useSettings = function (props) {
    var token = props.token, connectionless = props.connectionless, access = props.access, replicate = props.replicate, onEvents = props.onEvents, user = props.user, rest = tslib_1.__rest(props, ["token", "connectionless", "access", "replicate", "onEvents", "user"]);
    var constructTable = props.table;
    var _a = (0, react_1.useReducer)(SettingsReducer, {
        table: {},
        systemData: {},
        changed: {},
        inheritanceStack: [],
        exclusionTable: {},
        exclusionChanged: {},
        iteration: 0,
        self: true,
        reconstructData: {
            data: [], data2: false, queries: null
        },
        inherit: [
            { token: "system", name: "system", value: SettingsInheritance(constructTable) }
        ]
    }), state = _a[0], dispatch = _a[1];
    if (!onEvents)
        onEvents = function (event) { };
    var notifications = (0, react_1.useContext)(notifications_1.NotificationsContext);
    var asyncSaveRef = (0, react_1.useRef)(0);
    var asyncSaveRefTimer = (0, react_1.useRef)(null);
    var connection = (0, react_1.useRef)(null);
    var reconstructData = (0, react_1.useRef)(state.reconstructData);
    var changedData = (0, react_1.useRef)(state.changed);
    var liveUpdates = (0, react_1.useRef)(false);
    var tokenSplit = (token || "").split(/\:/g);
    var tokenParsed = (tokenSplit.length > 1 ? tokenSplit[tokenSplit.length - 1] : tokenSplit[0]) || "";
    if (tokenParsed == "self" && state.self && typeof state.self == "string") {
        tokenParsed = state.self;
    }
    ;
    reconstructData.current = state.reconstructData;
    changedData.current = state.changed;
    liveUpdates.current = SettingsGetSecureValue(state.table, state.changed, "General::Others::LiveUpdates") !== false;
    (0, react_1.useEffect)(function () {
        if (connectionless || !user)
            return function () { };
        if (connection.current && connection.current.__user != user) {
            channel_1.Channels.leaveAll();
            connection.current.destroy();
            connection.current.__user = "";
            connection.current = null;
        }
        ;
        if (!connection.current) {
            var socket = new socket_1.Socket();
            socket.connect(location.host + "/ws", window.location.protocol == "https:");
            socket.__user = user;
            channel_1.Channels.attach(socket);
            connection.current = socket;
        }
        ;
        channel_1.Channels.on("events", function (channel, action, value) {
            //console.log( channel.token, action, value );
            var prevented = false;
            var event = onEvents({
                channel: channel,
                action: action,
                value: value,
                refresh: function () {
                    return refresh();
                },
                reconstruct: function () {
                    return reconstruct(channel.token, value.value, value.exclusion, value.merge);
                },
                preventDefault: function () {
                    prevented = true;
                }
            });
            if (prevented)
                return;
            if (action == "config") {
                if (value.value == "refresh")
                    refresh();
                else
                    reconstruct(channel.token, value.value, value.exclusion, value.merge);
            }
            else if (action == "refresh") {
                //refresh();
            }
            ;
        });
        return function () {
            //connection.close();
        };
    }, [token, access, connectionless, user]);
    (0, react_1.useEffect)(function () {
        if (!asyncSaveRef.current)
            return;
        clearTimeout(asyncSaveRefTimer.current);
        asyncSaveRefTimer.current = setTimeout(function () {
            var s = asyncSaveRef.current;
            asyncSaveRef.current = 0;
            save(s > 1 ? true : false);
        }, 100);
    }, [state.changed]);
    var list = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./configurations/list/"
    }, {});
    var add = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./configurations/createEmpty/"
    }, {});
    var edit = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./configurations/commit/"
    }, {});
    edit.onResponse(function (response) {
        get.fetch({ token: token }, {
            ignore: true,
            success: function (response) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
                var queries;
                return tslib_1.__generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, (0, exports.SettingGetAllQueries)(constructTable)];
                        case 1:
                            queries = _a.sent();
                            dispatch(["construct", response.data, response.self, queries, constructTable]);
                            return [2 /*return*/];
                    }
                });
            }); },
            failure: function (e) {
                notifications.alert(e.errors);
            }
        });
    });
    var remove = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./configurations/remove/"
    }, {});
    var get = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./configurations/fetch/"
    }, {});
    (0, react_1.useEffect)(function () {
        if (!token || (access !== undefined && access < 1))
            return;
        get.fetch({ token: token }, {
            ignore: true,
            success: function (response) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
                var queries;
                return tslib_1.__generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, (0, exports.SettingGetAllQueries)(constructTable)];
                        case 1:
                            queries = _a.sent();
                            dispatch(["construct", response.data, response.self, queries, constructTable]);
                            return [2 /*return*/];
                    }
                });
            }); }
        });
    }, [token, access]);
    var reconstruct = function (token, value, exclusion, merge) {
        if (!reconstructData.current)
            return;
        var data = tslib_1.__spreadArray([], reconstructData.current.data, true);
        var t = (token || "").split(/\:/g);
        var tp = (t.length > 1 ? t[t.length - 1] : t[0]) || "";
        var type = (t.length > 1 ? t[0] : "") || "";
        try {
            value = typeof value == "string" ? JSON.parse(value) : value;
        }
        catch (e) { }
        ;
        try {
            exclusion = typeof exclusion == "string" ? JSON.parse(exclusion) : exclusion;
        }
        catch (e) { }
        ;
        for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
            var item = data_1[_i];
            var line = null;
            if (token == "users") {
                line = item.type == "users" ? item : null;
            }
            else if (type == item.type && tp == item.token) {
                line = item;
            }
            ;
            if (!line)
                continue;
            if (merge)
                line.value = tslib_1.__assign(tslib_1.__assign({}, line.value), value);
            else
                line.value = tslib_1.__assign({}, value);
            if (merge)
                line.exclusion = tslib_1.__assign(tslib_1.__assign({}, line.exclusion), exclusion);
            else
                line.exclusion = tslib_1.__assign({}, exclusion);
        }
        ;
        var queries = {
            queries: {},
            table: {},
        };
        try {
            queries.queries = reconstructData.current.queries && reconstructData.current.queries.queries ? tslib_1.__assign({}, reconstructData.current.queries.queries) : {};
            queries.table = reconstructData.current.queries && reconstructData.current.queries.table ? tslib_1.__assign({}, reconstructData.current.queries.table) : {};
        }
        catch (e) { }
        ;
        dispatch([
            "construct",
            data,
            reconstructData.current.data2,
            queries,
            constructTable
        ]);
    };
    var change = function (key, value, keyIndex) {
        dispatch(["change", { key: key, value: value, keyIndex: keyIndex }]);
    };
    var revert = function (key, value) {
        dispatch(["change", { key: key, value: value }]);
    };
    var changeExclusion = function (key, value, keyIndex) {
        dispatch(["changeExclusion", { key: key, value: value, keyIndex: keyIndex }]);
    };
    var revertExclusion = function (key, value) {
        dispatch(["revertExclusion", { key: key, value: value }]);
    };
    var save = function (silent, callback) {
        var saveData = {};
        var saveExclusionData = {};
        if (!silent) {
            for (var key in state.table) {
                var item = state.table[key];
                if (state.systemData.value[key].bindless)
                    continue;
                if (item.overrideToken != tokenParsed)
                    continue;
                saveData[key] = item.value;
            }
            ;
        }
        ;
        for (var key in state.changed) {
            var item = state.changed[key];
            if (item === null) {
                delete saveData[key];
                continue;
            }
            ;
            if (state.systemData.value[key].bindless)
                continue;
            saveData[key] = item;
        }
        ;
        if (!silent) {
            for (var key in state.exclusionTable) {
                var item = state.exclusionTable[key];
                if (item.overrideToken != tokenParsed)
                    continue;
                saveExclusionData[key] = item.value;
            }
            ;
        }
        ;
        for (var key in state.exclusionChanged) {
            var item = state.exclusionChanged[key];
            if (item === null) {
                delete saveExclusionData[key];
                continue;
            }
            ;
            saveExclusionData[key] = item;
        }
        ;
        var result = "";
        var resultExclusion = "";
        try {
            result = JSON.stringify(saveData);
            resultExclusion = JSON.stringify(saveExclusionData);
        }
        catch (e) { }
        ;
        //console.log( saveData, state );
        //return;
        edit.fetch({ token: token, value: result, exclusion: resultExclusion, silent: silent }, {
            ignore: true,
            success: function () {
                if (silent) {
                    if (callback)
                        callback();
                    return;
                }
                ;
                get.fetch({ token: token }, {
                    ignore: true,
                    success: function (response) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
                        var queries, _i, replicate_1, item;
                        return tslib_1.__generator(this, function (_a) {
                            switch (_a.label) {
                                case 0: return [4 /*yield*/, (0, exports.SettingGetAllQueries)(constructTable)];
                                case 1:
                                    queries = _a.sent();
                                    dispatch(["construct", response.data, response.self, queries, constructTable]);
                                    if (callback)
                                        callback();
                                    if (!Array.isArray(replicate))
                                        return [2 /*return*/];
                                    for (_i = 0, replicate_1 = replicate; _i < replicate_1.length; _i++) {
                                        item = replicate_1[_i];
                                        item.dispatch(["construct", response.data, response.self, queries, constructTable]);
                                    }
                                    ;
                                    return [2 /*return*/];
                            }
                        });
                    }); }
                });
            },
            failure: function (e) {
                notifications.alert(e.errors);
            }
        });
    };
    var checkValue = function (key) {
        SettingsCheckValue(key, SettingsGetValue(state.table, state.changed, key), state.table, state.systemData);
    };
    var getValue = function (key) {
        return SettingsGetValue(state.table, state.changed, key);
    };
    var getSecureValue = function (key) {
        return SettingsGetSecureValue(state.table, state.changed, key);
    };
    var getExclusionValue = function (key) {
        return SettingsGetExclusionValue(state.exclusionTable, state.exclusionChanged, key);
    };
    var getDesc = function (key) {
        return state.table[key] ? state.table[key].desc : "";
    };
    var getTitle = function (key) {
        return state.table[key] ? state.table[key].title : "";
    };
    var getSystemData = function (key) {
        return state.systemData && state.systemData.value ? state.systemData.value[key] : undefined;
    };
    var isChanged = function (key) {
        return state.changed[key] === undefined ? false : true;
    };
    var isExclusionChanged = function (key) {
        return state.exclusionChanged[key] === undefined ? false : true;
    };
    var isCleared = function (key) {
        return state.changed[key] === null ? true : false;
    };
    var isExclusionCleared = function (key) {
        return state.exclusionChanged[key] === null ? true : false;
    };
    var getOverride = function (key) {
        return state.table[key] ? state.table[key].override : [];
    };
    var getExclusionOverride = function (key) {
        return state.exclusionTable[key] ? state.exclusionTable[key].override : [];
    };
    var isOverride = function (key) {
        if (key == "default")
            return false;
        var list = getOverride(key);
        if (!list.length)
            return false;
        return list[list.length - 1].token == tokenParsed;
    };
    var isExclusionOverride = function (key) {
        if (key == "default")
            return false;
        var list = getExclusionOverride(key);
        if (!list.length)
            return false;
        return list[list.length - 1].token == tokenParsed;
    };
    var isInherit = function (key) {
        if (state.changed[key] === null) { //force inherit
            return state.table[key] && state.table[key].override.length > 1 ?
                (state.table[key].override[state.table[key].override.length - 2].value)
                :
                    (state.table[key] ? state.table[key].value : undefined);
        }
        ;
        if (key == "default")
            return false;
        var list = getOverride(key);
        if (!list.length)
            return false;
        return list[list.length - 1].token != tokenParsed;
    };
    var isExclusionInherit = function (key) {
        if (state.changedExclusion[key] === null) { //force inherit
            return state.exclusionTable[key] && state.exclusionTable[key].override.length > 1 ?
                (state.exclusionTable[key].override[state.exclusionTable[key].override.length - 2].value)
                :
                    (state.exclusionTable[key] !== undefined ? state.exclusionTable[key] : undefined);
        }
        ;
        if (key == "default")
            return false;
        var list = getExclusionOverride(key);
        if (!list.length)
            return false;
        return list[list.length - 1].token != tokenParsed;
    };
    var clearOverride = function (key) {
        //dispatch([ "clearOverride", { key: key, token: token } ]);
        dispatch(["change", { key: key, value: null }]);
    };
    var clearExclusionOverride = function (key) {
        //dispatch([ "clearOverride", { key: key, token: token } ]);
        dispatch(["changeExclusion", { key: key, value: null }]);
    };
    var keyExist = function (key) {
        return state.table.hasOwnProperty(key);
    };
    var isSelf = function (key) {
        return state.self ? true : false;
    };
    var autoCorrected = function (key) {
        return state.table[key] ? state.table[key].autoCorrected : null;
    };
    var setValueAsync = function (key, value, silent) {
        if (!keyExist(key))
            return;
        asyncSaveRef.current = silent ? 2 : 1;
        change(key, value);
    };
    var refresh = function () {
        if (!token || (access !== undefined && access < 1))
            return;
        get.fetch({ token: token }, {
            ignore: true,
            success: function (response) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
                var queries;
                return tslib_1.__generator(this, function (_a) {
                    switch (_a.label) {
                        case 0: return [4 /*yield*/, (0, exports.SettingGetAllQueries)(constructTable)];
                        case 1:
                            queries = _a.sent();
                            dispatch(["construct", response.data, response.self, queries, constructTable]);
                            return [2 /*return*/];
                    }
                });
            }); }
        });
    };
    return {
        state: state,
        dispatch: dispatch,
        table: state.table,
        exclusionTable: state.exclusionTable,
        checkValue: checkValue,
        getValue: getValue,
        getSecureValue: getSecureValue,
        getExclusionValue: getExclusionValue,
        getTitle: getTitle,
        getSystemData: getSystemData,
        getDesc: getDesc,
        getOverride: getOverride,
        getExclusionOverride: getExclusionOverride,
        isChanged: isChanged,
        isExclusionChanged: isExclusionChanged,
        isOverride: isOverride,
        isExclusionOverride: isExclusionOverride,
        isInherit: isInherit,
        isExclusionInherit: isExclusionInherit,
        isCleared: isCleared,
        isExclusionCleared: isExclusionCleared,
        autoCorrected: autoCorrected,
        keyExist: keyExist,
        setValueAsync: setValueAsync,
        change: change,
        changeExclusion: changeExclusion,
        revert: revert,
        revertExclusion: revertExclusion,
        refresh: refresh,
        clearOverride: clearOverride,
        clearExclusionOverride: clearExclusionOverride,
        save: save,
        isSelf: isSelf,
        it: state.iteration,
        iteration: state.iteration,
        inheritanceStack: state.inheritanceStack,
        async: { get: get, add: add, edit: edit, list: list, remove: remove }
    };
};
exports.useSettings = useSettings;
//# sourceMappingURL=use.settings.js.map