import { __assign, __rest, __spreadArray } from "tslib";
import React, { useState, useEffect, useMemo, useContext, useRef } from "react";
import { Card, Common, Row, Button, useAsync, Input, Select, Number, Toggle, MultiSelect, Editable, VMath, useDelta, usePrevious, Column, Tooltip, Space, Props } from "v-eris";
import { Ranges } from "./types.ranges";
import { ZoomParams } from "./types.zoom";
import { TypeTable } from "./types.table";
import { TypeTheme } from "./types.theme";
import "./types.scss";
import { StorageContext, useStorage } from "../utility/use.storage";
import { ParseWhere } from "./types.appendix";
export var TypeEnum = function (props) {
    var params = props.params, paramsOverride = props.paramsOverride, icon = props.icon, value = props.value, lang = props.lang, inactive = props.inactive, extra = props.extra, settings = props.settings, secure = props.secure, feedback = props.feedback, rest = __rest(props, ["params", "paramsOverride", "icon", "value", "lang", "inactive", "extra", "settings", "secure", "feedback"]);
    if (!params)
        params = {};
    if (!extra)
        extra = {};
    var list = paramsOverride || props.params || [];
    if (!Array.isArray(list))
        list = [];
    useEffect(function () {
        if (!feedback)
            return;
        feedback(value === undefined && list[0] ? (list[0].token || list[0].value || "") : value, list);
    }, [list]);
    var secureList = settings && secure ? settings.getSecureValue(secure) : null;
    if (secureList && secureList.list)
        secureList = secureList.list;
    else
        secureList = null;
    return (React.createElement(Select, __assign({ value: value, inactive: inactive, icon: icon, list: (secureList || list).map(function (item) {
            if (secureList)
                item = list.find(function (f) { return f.value == item; });
            if (item && (item.value || item.token || item.title))
                item = { value: item.token || item.value || "", title: item.title || item.name || "", icon: item.icon };
            else
                item = { value: item || "", title: item || "" };
            item.title = lang.get(item.title);
            return { icon: item.icon || icon, value: item.value, title: item.title };
        }), onChange: props.onChange }, extra)));
};
export var TypeSelectConfiguration = function (props) {
    var routeStorage = useContext(StorageContext);
    var paramsOverride = routeStorage.getValue("configurations") || [];
    return React.createElement(TypeEnum, __assign({}, props, { paramsOverride: paramsOverride }));
};
export var TypeSelectRole = function (props) {
    var routeStorage = useContext(StorageContext);
    var paramsOverride = routeStorage.getValue("roles") || [];
    var configurations = routeStorage.getValue("configurations") || [];
    var params = props.params || {};
    var filter = params.filter;
    var where = useMemo(function () {
        return ParseWhere(filter, props.storage);
    }, [filter, routeStorage.it, props.storage ? props.storage.it : 0]);
    if (where.configuration)
        paramsOverride = paramsOverride.filter(function (f) { return f.configuration == where.configuration; });
    var _loop_1 = function (item) {
        var configuration = configurations.find(function (f) { return f.token == item.configuration; });
        item.title = (configuration ? configuration.name : "default") + "." + item.name;
    };
    for (var _i = 0, paramsOverride_1 = paramsOverride; _i < paramsOverride_1.length; _i++) {
        var item = paramsOverride_1[_i];
        _loop_1(item);
    }
    ;
    return React.createElement(TypeEnum, __assign({}, props, { paramsOverride: paramsOverride }));
};
export var TypeSelectPolicy = function (props) {
    var routeStorage = useContext(StorageContext);
    var paramsOverride = routeStorage.getValue("policy") || [];
    return React.createElement(TypeEnum, __assign({}, props, { paramsOverride: paramsOverride }));
};
export var TypeSelectTableQuery = function (props) {
    var routeStorage = useContext(StorageContext);
    var params = props.params || {};
    var filter = params.filter;
    var route = params.route || "";
    var where = useMemo(function () {
        return ParseWhere(filter, routeStorage);
    }, [route, filter, routeStorage.it]);
    var storage = useStorage({
        where: where,
        section: route,
        current: false
    });
    useDelta(function () {
        if (filter && Object.keys(filter).length && !Object.keys(where).length)
            return;
        storage.async.list.fetch();
    }, [route, where], where);
    var paramsOverride = params.none ? __spreadArray([{ key: "", token: "none", name: "None" }], storage.list || [], true) : storage.list;
    return React.createElement(TypeEnum, __assign({}, props, { paramsOverride: paramsOverride }));
};
export var TypeButton = function (props) {
    var params = props.params, paramsOverride = props.paramsOverride, value = props.value, lang = props.lang, rest = __rest(props, ["params", "paramsOverride", "value", "lang"]);
    if (!params)
        params = {};
    if (!paramsOverride)
        paramsOverride = {};
    return (React.createElement("div", { className: "settings-type-button" },
        React.createElement(Button, { onClick: function (e) {
                if (paramsOverride.onChange)
                    paramsOverride.onChange(e.event, props);
            } }, lang.get(params.title))));
};
export var TypeText = function (props) {
    var params = props.params, value = props.value, lang = props.lang, inactive = props.inactive, rest = __rest(props, ["params", "value", "lang", "inactive"]);
    if (!params)
        params = {};
    var conditions = Array.isArray(params.conditions) ?
        params.conditions.map(function (item) {
            var _a;
            return __assign(__assign({}, item), (_a = {}, _a["desc"] = lang.get(item.desc), _a));
        })
        :
            [];
    return (React.createElement("div", { className: "settings-type-text" },
        React.createElement(Input, __assign({ inactive: inactive }, params, { conditions: conditions, onChange: function (e) { props.onChange({ value: e.value }); } }), value === 0 ? "0" : value)));
};
export var TypeJSON = function (props) {
    var params = props.params, value = props.value, lang = props.lang, inactive = props.inactive, rest = __rest(props, ["params", "value", "lang", "inactive"]);
    if (!params)
        params = {};
    var conditions = Array.isArray(params.conditions) ?
        params.conditions.map(function (item) {
            var _a;
            return __assign(__assign({}, item), (_a = {}, _a["desc"] = lang.get(item.desc), _a));
        })
        :
            [];
    try {
        if (typeof value == "string") {
            //let object = JSON.parse( value );
            //value = JSON.stringify( object, null, 3 );
        }
        else {
            value = JSON.stringify(value, null, 3);
        }
        ;
    }
    catch (e) {
        value = typeof value == "string" ? value : "";
    }
    ;
    if (params.editable) {
        return (React.createElement(Editable, { value: value === 0 ? "0" : value, stretch: params.stretch, conditions: conditions, inactive: inactive, onChange: function (e) { props.onChange({ value: e.target.value }); } }));
    }
    ;
    return (React.createElement("div", { className: Props.className("settings-type-code", { small: params.small }) },
        React.createElement("div", null, value || "")));
};
export var TypeTextarea = function (props) {
    var params = props.params, value = props.value, inactive = props.inactive, lang = props.lang, rest = __rest(props, ["params", "value", "inactive", "lang"]);
    if (!params)
        params = {};
    var conditions = Array.isArray(params.conditions) ?
        params.conditions.map(function (item) {
            var _a;
            return __assign(__assign({}, item), (_a = {}, _a["desc"] = lang.get(item.desc), _a));
        })
        :
            [];
    return (React.createElement(Editable, { value: value === 0 ? "0" : value, inactive: inactive, stretch: params.stretch, conditions: conditions, onChange: function (e) { props.onChange({ value: e.target.value }); } }));
};
export var TypeBool = function (props) {
    var params = props.params, value = props.value, inactive = props.inactive, rest = __rest(props, ["params", "value", "inactive"]);
    return (React.createElement("div", { className: "settings-type-bool" },
        React.createElement(Toggle, { inactive: inactive, value: props.value, onChange: props.onChange })));
};
export var TypeCheckbox = function (props) {
    var params = props.params, value = props.value, inactive = props.inactive, rest = __rest(props, ["params", "value", "inactive"]);
    return (React.createElement("div", { className: "settings-type-checkbox" },
        React.createElement("input", { type: "checkbox", checked: value ? true : false, onClick: function (e) {
                e.stopPropagation();
            }, onChange: function (e) {
                if (!props.onChange)
                    return;
                props.onChange({ value: e.target.checked });
            } })));
};
export var TypeStacking = function (props, jsx) {
    var stack = props.stack, k = props.k, value = props.value, settings = props.settings, pairs = props.pairs, rest = __rest(props, ["stack", "k", "value", "settings", "pairs"]);
    var refValue = settings ? settings.getValue(stack) : undefined;
    var array = [];
    if (Common.type(refValue) == "number") {
        refValue = VMath.clamp(Common.uint(refValue), 0, 999);
        var override = settings.getOverride(k);
        if (!Array.isArray(value) || !override)
            return array;
        for (var n = 0; n < refValue; n++) {
            var newKey = k + ":" + n;
            array.push(jsx(newKey, n < value.length ? value[n] : (override[0].value[0]), n, undefined));
        }
        ;
        return array;
    }
    else if (Common.type(refValue) == "array") {
        var override = settings.getOverride(k);
        if (!Array.isArray(value) || !override)
            return array;
        var refLength = refValue.length;
        for (var n = 0; n < refLength; n++) {
            var newKey = k + ":" + n;
            if (pairs) {
                if ((n + 1) < refValue.length) {
                    array.push(jsx(newKey, n < value.length ? value[n] : (override[0].value[0]), n, [refValue[n], refValue[n + 1]]));
                }
                else {
                    break;
                }
                ;
            }
            else {
                array.push(jsx(newKey, n < value.length ? value[n] : (override[0].value[0]), n, refValue[n]));
            }
            ;
        }
        ;
        return array;
    }
    ;
    return [jsx(k, value, undefined)];
};
export var TypeNumber = function (props) {
    var params = props.params, value = props.value, stack = props.stack, k = props.k, settings = props.settings, inactive = props.inactive, rest = __rest(props, ["params", "value", "stack", "k", "settings", "inactive"]);
    if (!params)
        params = {};
    return TypeStacking(props, function (key, value, index, arrayValue) {
        return React.createElement("div", { key: key, className: "settings-type-number" },
            React.createElement(Number, { inactive: inactive, value: value || 0, min: params.min, max: params.max, step: params.step, onChange: function (e) { props.onChange(e, index); } }));
    });
};
export var TypeFloat = function (props) {
    var params = props.params, value = props.value, stack = props.stack, k = props.k, settings = props.settings, inactive = props.inactive, rest = __rest(props, ["params", "value", "stack", "k", "settings", "inactive"]);
    if (!params)
        params = {};
    return TypeStacking(props, function (key, value, index, arrayValue) {
        return React.createElement("div", { key: key, className: "float input" },
            React.createElement("input", { type: "number", disabled: inactive, value: value || 0, min: params.min, max: params.max, onChange: function (e) { props.onChange({ value: e.target.value }, index); } }));
    });
};
export var TypeRanges = function (props) {
    var params = props.params, value = props.value, stack = props.stack, k = props.k, settings = props.settings, inactive = props.inactive, rest = __rest(props, ["params", "value", "stack", "k", "settings", "inactive"]);
    if (!params)
        params = {};
    return TypeStacking(props, function (key, value, index, arrayValue) {
        return React.createElement(Ranges, __assign({ key: key, inactive: inactive, value: value }, params, { onChange: function (e) { props.onChange(e, index); } }));
    });
};
export var TypeZoom = function (props) {
    var params = props.params, value = props.value, stack = props.stack, k = props.k, settings = props.settings, rest = __rest(props, ["params", "value", "stack", "k", "settings"]);
    if (!params)
        params = {};
    return React.createElement(Column, { className: "settings-type-list" }, TypeStacking(__assign(__assign({}, props), { pairs: true }), function (key, value, index, arrayValue) {
        return React.createElement(ZoomParams, { key: key, value: value || [], range: arrayValue, onChange: function (e) { props.onChange(e, index); } });
    }));
};
export var TypeList = function (props) {
    var params = props.params, value = props.value, lang = props.lang, extra = props.extra, settings = props.settings, secure = props.secure, icon = props.icon, rest = __rest(props, ["params", "value", "lang", "extra", "settings", "secure", "icon"]);
    if (!params)
        params = {};
    if (!extra)
        extra = {};
    var secureList = settings && secure ? settings.getSecureValue(secure) : null;
    if (secureList && secureList.list && Array.isArray(secureList.list))
        secureList = secureList.list;
    else
        secureList = null;
    var paramsList = props.params || [];
    if (secureList)
        paramsList = paramsList.filter(function (item) { return secureList.findIndex(function (f) { return f == item.value; }) > -1; });
    return (React.createElement("div", { className: "settings-type-list" },
        React.createElement(MultiSelect, __assign({ value: extra.hasDefault || extra.sortable || (value && value.list) ? ((value ? value.list : value) || []) : (value || []), defaultValue: extra.hasDefault ? (value ? value.defaultValue : null) : (null), sort: extra.sortable || (value && value.sort) ? (value ? value.sort : null) : (null), prefix: extra.prefix, suggestions: paramsList.map(function (item) {
                if (item && (item.value || item.token || item.title))
                    item = { value: item.token || item.value || "", title: item.title || item.name || "", prefix: item.prefix, icon: item.icon, defaultIgnored: item.defaultIgnored };
                else
                    item = { value: item || "", title: item || "" };
                item.title = lang.get(item.title);
                item.prefix = lang.get(item.prefix);
                return { value: item.value, prefix: item.prefix, icon: icon || item.icon, title: item.title, defaultIgnored: item.defaultIgnored };
            }), onChange: function (event) {
                props.onChange(extra.hasDefault || extra.sortable || (value && value.list) ? { value: { list: event.value, defaultValue: event.defaultValue, sort: event.sort } } : { value: event.value });
            } }, extra))));
};
export var TypeListBinary = function (props) {
    var params = props.params, value = props.value, lang = props.lang, rest = __rest(props, ["params", "value", "lang"]);
    if (!params)
        params = {};
    var val = [];
    value = Common.uint(value);
    for (var _i = 0, _a = props.params; _i < _a.length; _i++) {
        var item = _a[_i];
        if ((value & item.value) != item.value)
            continue;
        val.push(item.value);
    }
    ;
    return (React.createElement("div", { className: "settings-type-list" },
        React.createElement(MultiSelect, { value: val, suggestions: (props.params || []).map(function (item) {
                if (item && (item.value || item.token || item.title))
                    item = { value: item.token || item.value || "", title: item.title || item.name || "" };
                else
                    item = { value: item || "", title: item || "" };
                item.title = lang.get(item.title);
                return { value: item.value, title: item.title };
            }), onChange: function (e) {
                var result = 0;
                for (var _i = 0, _a = e.value; _i < _a.length; _i++) {
                    var item = _a[_i];
                    result |= item;
                }
                ;
                props.onChange(__assign(__assign({}, e), { value: result }));
            } })));
};
export var TypeFile = function (props) {
    var multiple = props.params ? props.params.multiple : undefined;
    var ref = useRef(null);
    var prev = usePrevious(props.value);
    var _a = useState([]), searchData = _a[0], setSearchData = _a[1];
    useEffect(function () {
        if (!ref.current)
            return;
        if (prev && !props.value) {
            ref.current.value = "";
            list.fetch();
        }
        ;
    }, [props.value]);
    var list = useAsync({
        method: "GET",
        url: "./filesystem/search/"
    }, {
        module: props.route,
        field: props.k,
        line: props.token,
        groupBy: 0
    });
    list.onResponse(function (response) {
        if (!response.data || !response.data || !response.data.length)
            return;
        var files = [];
        for (var _i = 0, _a = response.data; _i < _a.length; _i++) {
            var link = _a[_i];
            if (!link.list)
                continue;
            files.push.apply(files, link.list);
        }
        ;
        setSearchData(files);
    });
    useEffect(function () {
        list.fetch();
    }, [props.route, props.k, props.token]);
    return (React.createElement(Tooltip, { className: "type-file-tooltip", content: React.createElement("div", null,
            React.createElement("div", null,
                "Files: ",
                searchData.length),
            React.createElement("div", null, searchData.map(function (file) {
                return (React.createElement(Card, { key: file.token, className: "type-file-tooltip-card" },
                    React.createElement(Row, null,
                        "Name: ",
                        file.name),
                    React.createElement(Row, null,
                        "Type: ",
                        file.mime),
                    React.createElement(Row, null,
                        "Date: ",
                        new Date(Common.float(file.date) * 1000).toUTCString()),
                    React.createElement(Row, null,
                        "User:",
                        React.createElement(Space, null),
                        React.createElement(TypeSelectTableQuery, { inactive: true, lang: props.lang, params: { route: "users", filter: { token: file.user_token } } })),
                    React.createElement(Row, null,
                        "User Configuration:",
                        React.createElement(Space, null),
                        React.createElement(TypeSelectTableQuery, { inactive: true, lang: props.lang, params: { route: "configurations", filter: { token: file.user_configuration } } }))));
            }))) },
        React.createElement("input", { type: "file", ref: ref, multiple: multiple, onChange: function (e) { return props.onChange({ value: e.target.files }); } })));
};
export var TypeNone = function () {
    return React.createElement("span", null);
};
export var Types = {
    enum: React.createElement(TypeEnum, null),
    theme: React.createElement(TypeTheme, null),
    select: React.createElement(TypeEnum, null),
    text: React.createElement(TypeText, null),
    textarea: React.createElement(TypeTextarea, null),
    number: React.createElement(TypeNumber, null),
    float: React.createElement(TypeFloat, null),
    ranges: React.createElement(TypeRanges, null),
    zoom: React.createElement(TypeZoom, null),
    bool: React.createElement(TypeBool, null),
    toggle: React.createElement(TypeBool, null),
    list: React.createElement(TypeList, null),
    listbinary: React.createElement(TypeListBinary, null),
    button: React.createElement(TypeButton, null),
    table: React.createElement(TypeTable, null),
    checkbox: React.createElement(TypeCheckbox, null),
    configuration: React.createElement(TypeSelectConfiguration, null),
    role: React.createElement(TypeSelectRole, null),
    policy: React.createElement(TypeSelectPolicy, null),
    querytable: React.createElement(TypeSelectTableQuery, null),
    json: React.createElement(TypeJSON, null),
    file: React.createElement(TypeFile, null),
    none: React.createElement(TypeNone, null),
};
//# sourceMappingURL=types.js.map