"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StorageContext = exports.useStorage = void 0;
var tslib_1 = require("tslib");
var react_1 = tslib_1.__importStar(require("react"));
var v_eris_1 = require("v-eris");
var notifications_1 = require("../components/Notifications/notifications");
var StorageReducer = function (state, _a) {
    var type = _a[0], data = _a[1], rewrite = _a[2], sort = _a[3];
    if (type == "construct") {
        var table = {};
        var ref = data;
        if (Array.isArray(ref))
            ref = ref[rewrite ? (ref.length > 0 ? (ref.length - 1) : 0) : 0] || {};
        for (var key in ref) {
            var item = ref[key];
            if (item === undefined)
                continue;
            table[key] = item;
        }
        ;
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, table: table, changed: {} });
    }
    else if (type == "change") {
        var changed = tslib_1.__assign({}, state.changed);
        var updated = false;
        if (data.value === undefined && changed[data.key] !== undefined) {
            delete changed[data.key];
            updated = true;
        }
        else if (changed[data.key] !== data.value) {
            changed[data.key] = data.value;
            updated = true;
        }
        ;
        if (!updated)
            return state;
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, changed: changed });
    }
    else if (type == "overwrite") {
        var overwrite = tslib_1.__assign({}, state.overwrite);
        if (data.value === undefined)
            delete overwrite[data.key];
        else
            overwrite[data.key] = data.value;
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, overwrite: overwrite });
    }
    else if (type == "changeMulti") {
        var changed = tslib_1.__assign({}, state.changed);
        var skip = true;
        for (var key in data.values) {
            var value = data.values[key];
            if (value === undefined && changed[key] !== undefined) {
                skip = false;
                delete changed[key];
            }
            else if (value != changed[key] && value != state.table[key]) {
                skip = false;
                changed[key] = value;
            }
            ;
        }
        ;
        if (skip)
            return state;
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, changed: changed });
    }
    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 == "list") {
        var list = [];
        var precomputed = null;
        var table = data.data;
        var length_1 = data.length;
        for (var it in table) {
            var item = table[it];
            var result = { key: item.token };
            for (var key in item) {
                result[key] = item[key];
                if (typeof rewrite[key] == "function") {
                    precomputed = rewrite[key](key, item[key]);
                    if (precomputed) {
                        result[precomputed.key] = precomputed.value;
                    }
                    ;
                }
                else if (rewrite[key]) {
                    result[rewrite[key]] = item[key];
                }
                ;
            }
            ;
            list.push(result);
        }
        ;
        if (sort)
            list = sort(list);
        return tslib_1.__assign(tslib_1.__assign({}, state), { iteration: ++state.iteration, list: list, length: length_1 });
    }
    ;
    return state;
};
var useStorage = function (props) {
    var token = props.token, section = props.section, current = props.current, getFromLast = props.getFromLast, params = props.params, sort = props.sort, where = props.where, offset = props.offset, limit = props.limit, pagination = props.pagination, whereAny = props.whereAny, ignoreList = props.ignoreList, rewrite = props.rewrite, rest = tslib_1.__rest(props, ["token", "section", "current", "getFromLast", "params", "sort", "where", "offset", "limit", "pagination", "whereAny", "ignoreList", "rewrite"]);
    var notifications = (0, react_1.useContext)(notifications_1.NotificationsContext);
    if (!whereAny)
        whereAny = {};
    if (!section)
        section = "";
    if (!params)
        params = {};
    if (!rewrite)
        rewrite = {};
    if (current === undefined)
        current = true;
    if (getFromLast === undefined)
        getFromLast = false;
    var _a = (0, react_1.useReducer)(StorageReducer, {
        list: [],
        length: 0,
        table: {},
        changed: {},
        overwrite: {},
        iteration: 0,
    }), state = _a[0], dispatch = _a[1];
    if (current && !ignoreList && !state.list.find(function (item) { return item.key == token; })) {
        token = state.list[0] ? state.list[0].key : "";
    }
    ;
    var currentPagination = !!pagination;
    var currentOffset = v_eris_1.Common.uint(offset) || 0;
    var currentLimit = (v_eris_1.Common.uint(limit) || 20);
    var list = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./" + section + "/list/"
    }, { where: where, whereAny: whereAny, pagination: currentPagination, offset: currentOffset, limit: currentLimit });
    list.onResponse(function (response) {
        dispatch(["list", response, rewrite, sort]);
    });
    (0, react_1.useEffect)(function () {
        if (ignoreList)
            return;
        list.fetch(tslib_1.__assign(tslib_1.__assign({}, params), { where: where, whereAny: whereAny, pagination: currentPagination, offset: currentOffset, limit: currentLimit }));
    }, [section, offset, limit]);
    (0, v_eris_1.useDelta)(function () {
        if (ignoreList)
            return;
        if ((!where && !whereAny) || (!Object.keys(where).length && !Object.keys(whereAny).length))
            return;
        list.fetch(tslib_1.__assign(tslib_1.__assign({}, params), { where: where, whereAny: whereAny, pagination: currentPagination, offset: currentOffset, limit: currentLimit }));
    }, [section, offset, limit, whereAny.token, where], where);
    var add = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./" + section + "/createEmpty/"
    }, { where: where, whereAny: whereAny });
    var edit = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./" + section + "/edit/"
    }, {});
    edit.onResponse(function (response) {
        get.fetch(tslib_1.__assign(tslib_1.__assign({}, params), { token: token }), {
            ignore: true,
            success: function (response) {
                dispatch(["construct", response.data, getFromLast]);
            }
        });
    });
    var remove = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./" + section + "/remove/"
    }, {});
    var get = (0, v_eris_1.useAsync)({
        method: "POST",
        url: "./" + section + "/get/"
    }, {});
    //	useEffect(() => {
    //
    //		if( !current || ignoreList )
    //			return;
    //
    //		//if( where && !Object.keys( where ).length )
    //		//	return;
    //
    //		list.fetch({ ...params, ...{ where: where, whereAny: whereAny, pagination: currentPagination, offset: currentOffset, limit: currentLimit } });		
    //	}, []);
    (0, react_1.useEffect)(function () {
        if (!token || !current)
            return;
        get.fetch(tslib_1.__assign(tslib_1.__assign({}, params), { token: token }), {
            ignore: true,
            success: function (response) {
                dispatch(["construct", response.data, getFromLast]);
            }
        });
    }, [token, section, current]);
    var change = function (key, value) {
        dispatch(["change", { key: key, value: value }]);
    };
    var overwrite = function (key, value) {
        dispatch(["overwrite", { key: key, value: value }]);
    };
    var changeMulti = function (values) {
        dispatch(["changeMulti", { values: values }]);
    };
    var revert = function (key, value) {
        dispatch(["change", { key: key, value: value }]);
    };
    var save = function (params) {
        if (!params)
            params = { parseKeys: false };
        var saveData = {};
        for (var key in state.table) {
            var item = state.table[key];
            if (item === undefined)
                continue;
            saveData[key] = item;
        }
        ;
        var subArray = [];
        for (var key in state.changed) {
            var item = state.changed[key];
            if (item === null)
                continue;
            if (params.parseKeys) {
                subArray = key.split(/\:/g);
                key = subArray && subArray.length ? subArray[subArray.length - 1] : key;
            }
            ;
            saveData[key] = item;
        }
        ;
        edit.fetch(tslib_1.__assign(tslib_1.__assign({}, saveData), { token: token }), {
            ignore: true,
            success: function () {
                get.fetch({ token: token }, {
                    ignore: true,
                    success: function (getResponse) {
                        if (params.success)
                            params.success(getResponse.data);
                        if (ignoreList) {
                            dispatch(["construct", getResponse.data, getFromLast]);
                            return;
                        }
                        ;
                        list.fetch({ token: token }, {
                            ignore: true,
                            success: function (listResponse) {
                                dispatch(["list", listResponse, rewrite, sort]);
                                dispatch(["construct", getResponse.data, getFromLast]);
                            }
                        });
                    }
                });
            },
            failure: function (e) {
                notifications.alert(e.errors);
                if (params.failure)
                    params.failure(e.errors);
            }
        });
    };
    var getValue = function (key) {
        if (state.overwrite[key] !== undefined) {
            return state.overwrite[key];
        }
        ;
        if (state.changed[key] === null) {
            return (state.table[key] ? state.table[key] : undefined);
        }
        ;
        return state.changed[key] === undefined ? state.table[key] : state.changed[key];
    };
    var isChanged = function (key) {
        return state.changed[key] === undefined ? false : true;
    };
    var isCleared = function (key) {
        return state.changed[key] === null ? true : false;
    };
    var addFn = function (data, callback) {
        add.fetch(tslib_1.__assign(tslib_1.__assign({}, data), { where: where, whereAny: whereAny }), {
            ignore: true,
            success: function (response) {
                if (ignoreList) {
                    if (callback)
                        callback(response);
                    return;
                }
                ;
                list.fetch({ token: token }, {
                    ignore: true,
                    success: function (listResponse) {
                        dispatch(["list", listResponse, rewrite, sort]);
                        if (callback)
                            callback(response);
                    }
                });
            },
            failure: function (e) {
                notifications.alert(e.errors);
            }
        });
    };
    var removeFn = function (data, callback) {
        remove.fetch(data, {
            ignore: true,
            success: function (response) {
                if (ignoreList) {
                    if (callback)
                        callback(response);
                    return;
                }
                ;
                list.fetch({ token: token }, {
                    ignore: true,
                    success: function (listResponse) {
                        dispatch(["list", listResponse, rewrite, sort]);
                        if (callback)
                            callback(response);
                    }
                });
            },
            failure: function (e) {
                notifications.alert(e.errors);
            }
        });
    };
    var getToken = function () {
        return token;
    };
    return {
        state: state,
        dispatch: dispatch,
        table: state.table,
        changed: state.changed,
        list: state.list,
        length: state.length,
        getToken: getToken,
        getValue: getValue,
        requestList: function () { },
        isChanged: isChanged,
        isCleared: isCleared,
        change: change,
        overwrite: overwrite,
        changeMulti: changeMulti,
        revert: revert,
        save: save,
        add: addFn,
        remove: removeFn,
        it: state.iteration,
        iteration: state.iteration,
        async: { get: get, add: add, edit: edit, list: list, remove: remove }
    };
};
exports.useStorage = useStorage;
exports.StorageContext = react_1.default.createContext(tslib_1.__assign({}, exports.useStorage));
//# sourceMappingURL=use.storage.js.map