/**
 *
 *  Basic
 *  所有页面的共用基础功能
 *  // TODO: 文件名可能需要修改
 *  // TODO: failing ES-Lint
 *  // TODO: Automated Test
 *
 *  dependency:
 *  jQuery (ajax, selector)
 *
 *  @ jason.lu
 * */

import 'whatwg-fetch';

var BasicFunction = new (function () {

    this.Queue = {
        THRESHOLD: 1000,
        IS_LOADED: false,
        nowuse: 0, SVR_URL: "/server/",
        groupsCount: 0, groups: [],
        shouldStop: false,
        backup: ["/server/",
            "http://127.0.0.1:8866/server/",
            "http://south.niimei.com:8866/server/",
            "https://4.niimei.com/server/"],
        list: [], temporary: 0, errorCount: 0
    };

    this.Users = {list: []};
    this.Sectors = {list: []};
    this.AlertClosingTimeout = 0;

    this.loglog = function (a) {
        console.log(a);
    };

    this.logwarn = function (obj) {
        console.warn(obj);
    };

    this.logerror = function (obj) {
        console.warn(obj);
    };

    this.logtrace = function () {
        console.trace();
    };

    this.logverbose = function () {
        // Not Echoing
    };

    this.asserThat = function(cond, why) {
        console.assert(cond, why);
    };


    this.goajax = function (jqObject) {
        return fetch(jqObject.url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                //'x-doiby-authenticate' : 'CISICMIEINAOQPMDPWIDNENU'
            },
            body: jqObject.data
        });
    };

    this.utils_get_param = function (name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if (r != null) return unescape(r[2]);
        return null;
    };

    this.reloadPage = function () {
        location.reload()
    };

    this.get_server_url = function () {
        // AJAX
        this.output = this.goajax({url: this.Queue.SVR_URL + "fcFlow/list", timeout: 1000})
            .then(this.checkStatus)
            .then(this.parseJson)
            .then(this.onReachServer)
            .catch(this.onCheckFail);
        // .then(BasicFunction.onCheckFail);
    };

    this.onReachServer = function (checkResponse) {
        BasicFunction.Queue.IS_LOADED = true;
        BasicFunction.logwarn("Using SERVER : ");
        BasicFunction.logwarn(BasicFunction.Queue.SVR_URL);
        setTimeout(BasicFunction.parse_queue, 50, BasicFunction);
    };

    this.onCheckFail = function (errmsg) {
        if (BasicFunction.Queue.nowuse === BasicFunction.Queue.backup.length - 1) {
            BasicFunction.logwarn("Backup Failed : " + BasicFunction.Queue.backup[BasicFunction.Queue.nowuse]);
            BasicFunction.logwarn(this);
            var out = "";
            BasicFunction.Queue.backup.forEach(function (val, index, arr) {
                out += index + ":[" +val +"] \n";
            });
            BasicFunction.logerror("抱歉， 服务器连接失败! \n 请确认 "+ out +" 其中之一可用");
        } else {
            BasicFunction.loglog(errmsg);
            BasicFunction.Queue.nowuse++;
            BasicFunction.Queue.SVR_URL = BasicFunction.Queue.backup[BasicFunction.Queue.nowuse];
            // AJAX
            BasicFunction.goajax({url: BasicFunction.Queue.SVR_URL + "fcFlow/list", timeout: 1000})
                .then(BasicFunction.checkStatus)
                .then(function (response) {return response.json();} )
                .then(BasicFunction.onReachServer)
                .catch(BasicFunction.onCheckFail);
            //.fail(BasicFunction.onCheckFail).done(BasicFunction.onReachServer);
        }
    };

    this.get_data = function (url, callback, scope) {
        console.log('----------using get_data()-----------');
        BasicFunction.Queue.list.push({url: url, callback: callback, gid: -1, scope: scope});
    this.get_data = function (url, callback, data, scope) {
        BasicFunction.Queue.list.push({url: url, callback: callback, gid: -1, data:data, scope: scope});
    };

    this.new_data_group = function (groupName, callback) {
        var gid = -1;
        BasicFunction.Queue.groups.forEach(function (val) {
            if (val.groupName === groupName) {
                gid = val.gid;
            }
        });
        if (gid === -1) {
            gid = BasicFunction.Queue.groupsCount;
            BasicFunction.Queue.groupsCount++;
            BasicFunction.Queue.groups.push({
                gid: gid, groupName: groupName, callme: callback, counter: 0
            });
        }
        return gid;
    };

    this.group_get_data = function (groupName, url, callback) {
        var gid = -1;
        BasicFunction.Queue.groups.forEach(function (val) {
            if (val.groupName === groupName) {
                gid = val.gid;
            }
        });
        if (gid === -1) {
            BasicFunction.send_alert("Group 方法使用错误！！！")
        }
        BasicFunction.Queue.list.push({url: url, callback: callback, gid: gid});
    };

    this.parse_queue = function () {
        BasicFunction.logverbose("Queue Length : " + BasicFunction.Queue.list.length);

        if (BasicFunction.Queue.temporary > new Date().getTime()) {
            for (let i = 0; i < BasicFunction.Queue.list.length; i++) {
                BasicFunction.Queue.list.pop();
            }
        }

        BasicFunction.Queue.temporary = 0;

        if (BasicFunction.Queue.list.length > 0) {
            let one = BasicFunction.Queue.list.pop();
            if (one.gid === -1) {
                request_data(one.url, one.callback, one.data, one.scope);
            } else {
                g_request_data(one.url, one.callback, one.gid, one.data, one.scope);
            }
        }
        if (BasicFunction.Queue.shouldStop === false) {
            setTimeout(BasicFunction.parse_queue, 50);
        }
    };

    this.parseJSON = function(response) {
        return response.json();
    };

    this.checkStatus = function(response) {
        if (response.status >= 200 && response.status < 300) {
            return response;
        }

        const error = new Error(response.statusText);
        error.response = response;
        throw error;
    };

    function request_data(url, callback, data, scope) {
        BasicFunction.goajax({
            url: BasicFunction.Queue.SVR_URL + url,
            apiName: url,
            data: data,
            sendTime: new Date()
        }).then(BasicFunction.checkStatus)
          .then(BasicFunction.parseJson)
          .then(function(response){return response.json()})
          .then(callback)
          .catch(BasicFunction.on_fail);
    }

    function g_request_data(url, callback, gid) {
        BasicFunction.goajax({
            url: BasicFunction.Queue.SVR_URL + url,
            apiName: url,
            sendTime: new Date(),
            gid: gid,
            callme: callback
        }).then(BasicFunction.checkStatus)
        .then(BasicFunction.parseJson)
        .then(function(response){return response.json()})
        .then(BasicFunction.onReqeustDataReceived)
        .then(callback)
        .catch(BasicFunction.on_fail);
    }

    this.on_gp_success = function(response) {
        var obj = response.json();
        return obj;
    };

    this.onReqeustDataReceived = function(responseJson) {
        console.warn(responseJson);
        var a = responseJson;
        if (!BasicFunction.check_if_authfail(a)) {
            const error = new Error(responseJson.statusText);
            error.response = responseJson;
            throw error;
        }
        if (!BasicFunction.check_if_success(a)) {
            const error = new Error(responseJson.statusText);
            error.response = responseJson;
            throw error;
        }
        return responseJson;
        //     BasicFunction.setCookieWithTimeout("doibyUser", "", -10);
        //     location.href = "sign-in1.html?from=entrance-5&msg=server-redirect-detected";
        //     return;
    };

    this.check_if_authfail = function (errormsg) {
        BasicFunction.logerror(errormsg);
        var a = errormsg;
        if (a == null || typeof a !== "string") {
            return false;
        } else {
            if (a.indexOf("login?from=") > 0 || a.startsWith("<!DOCTYPE html>") || a.indexOf("<!-- SME::LOGINPAGE -->") > 0) {
                return true;
            }
        }
        return false;
    };

    this.check_if_success = function (response) {
        // this == BasicFunction
        BasicFunction.loglog("---------------Check-If-Success----------------");
        var a = response.json();
        var b = response.status;
        if (typeof a === "string") {
            try {
                a = JSON.parse(a);
            } catch (e) {
                BasicFunction.logwarn("=----------   异常   -----------=");
                BasicFunction.logwarn(a);
                BasicFunction.logwarn("=----------------------------=");
                BasicFunction.send_alert("信息失败 : 1 : " + e);
                return;
            }
        } else if (typeof a === "undefined") {
            BasicFunction.logwarn("=----------   异常   -----------=");
            BasicFunction.logwarn(a);
            BasicFunction.logwarn("=------------------------------=");
            BasicFunction.logwarn(b);
            BasicFunction.logwarn("=------------------------------=");
            BasicFunction.send_alert("信息失败 - 2 " );
            return;
        }
        if (a.ret === "10000") {
            return true;
        } else {
            BasicFunction.logtrace();
            BasicFunction.logerror(b);
            BasicFunction.logerror(JSON.stringify(a));
            BasicFunction.send_alert("查询失败 : 请参阅控制台输出! ");
        }

        return false;
    };

    this.on_fail = function (msg) {
        BasicFunction.Queue.errorCount += 1;
        if (BasicFunction.Queue.errorCount >= 10) {
            BasicFunction.Queue.errorCount = 0;
            BasicFunction.Queue.temporary = new Date().getTime() + 30 * 1000;
            BasicFunction.Queue.shouldStop = true;
            BasicFunction.logwarn("-----  Too many failure, temporary stop HTTP ------");
            BasicFunction.send_alert("很抱歉，网络错误数量过多，暂时终止HTTP功能30s");
        }
        BasicFunction.send_alert(" 很抱歉，网络错误，请查看 Console");
        BasicFunction.logwarn("-----   网络请求失败 ---------");
        BasicFunction.logwarn("-----------msg-------------");
        BasicFunction.logwarn(JSON.stringify(msg));
        BasicFunction.logwarn("----------------------------");
    };

    this.first_parse = function (ajax, obj) {
        if (typeof obj === "string") {
            obj = JSON.parse(obj);
        }

        if (typeof obj !== "object") {
            BasicFunction.logwarn(ajax);
            throw "Error ! Parsing JSON failed ." + JSON.stringify(obj);
        }

        if (obj.ret === "10000") {
            return obj.model;
        } else {
            BasicFunction.logwarn(ajax);
            throw "Error ! Server returned error." + JSON.stringify(obj);
        }
    };

    this.send_alert = function (a, b) {


        if (BasicFunction.Queue.shouldStop) return;

        if (BasicFunction.AlertClosingTimeout > 0) {
            clearTimeout(BasicFunction.AlertClosingTimeout);
        }

        BasicFunction.logwarn(a);
        BasicFunction.logwarn(b);

        // alert(a +"\n"+ b);

        BasicFunction.AlertClosingTimeout = setTimeout(function () {
            //$("#mpAlert").hide();
        }, 10000);

    };

    this.getUserName = function (uid) {
        var uname = null;
        BasicFunction.Users.list.forEach(function (val, aid) {
            BasicFunction.loglog(aid);
            if (val.worker.staffId === uid) {
                uname = val.worker.staffName;
            }
        });
        if (uname == null) {
            if (uid !== 0) {
                BasicFunction.get_data("oaStaff/list?staffId=" + uid, BasicFunction.on_username_retn);
                return "[用户:" + uid + "]";
            } else return "[用户:" + uid + "]";
        } else {
            return uname;
        }
    };

    this.on_username_retn = function (obj) {
        var uid = this.url.substring(this.url.indexOf("staffId=") + 8);
        let ruid = parseInt(uid);
        var out = BasicFunction.first_parse(this, obj);
        if (out.list.length > 0) {
            BasicFunction.Users.list.push({
                uid: ruid, worker: out.list[0]
            });
        }
    };

    this.setCookieWithTimeout = function (name, value, liveMinutes) {
        if (liveMinutes === undefined || liveMinutes == null) {
            liveMinutes = 60 * 2;
        }
        if (typeof (liveMinutes) !== 'number') {
            liveMinutes = 60 * 2;//默认120分钟
        }
        var minutes = liveMinutes * 60 * 1000;
        var exp = new Date();
        exp.setTime(exp.getTime() + minutes + 8 * 3600 * 1000);
        //path=/表示全站有效，而不是当前页
        document.cookie = name + "=" + value + ";path=/;expires=" + exp.toUTCString();
    };

    this.setCookie = function (c_name, value, expiredays) {
        var exdate = new Date();
        exdate.setDate(exdate.getDate() + expiredays);
        document.cookie = c_name + "=" + escape(value) +
            ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString())
    };

    this.getCookie = function (c_name) {
        if (document.cookie.length > 0) {
            var c_start = document.cookie.indexOf(c_name + "=");
            if (c_start !== -1) {
                c_start = c_start + c_name.length + 1;
                var c_end = document.cookie.indexOf(";", c_start);
                if (c_end === -1) c_end = document.cookie.length;
                return unescape(document.cookie.substring(c_start, c_end))
            }
        }
        return "";
    };

    /*this.userId = utils_get_param("userId");

    this.getUserId = function() {
         BasicFunction.loglog("Original  USERID : " + userId);
        var use = getCookie("doibyUser");
        if (use == null || use === undefined || use.length <= 0) {
            location.href = "sign-in1.html?from=entrance-1&msg=nologin-mustauth";
            return;
        }
         BasicFunction.loglog("Got UID From COOKIE : " + use);
        try {
            var mm = parseInt(use);
            if (mm > 0) {
                BasicFunction.userId = mm;
            }
        } catch (e) {
            location.href = "sign-in1.html?from=entrance-1&msg=cookie-wrong-format";
            return;
        }

         BasicFunction.loglog("Got UserId Eventually : " + userId);
    };*/

    this.get_server_url();
    //this.on_document_load();

window.BasicFunction = BasicFunction;

export {
    BasicFunction
};