import { sys } from "cc";
import { FrameworkConf } from "../../framework/config/FrameworkConf";
import { ViewID } from "../../framework/config/LayerConf";
import { Framework } from "../../framework/Framework";
import { EncryptUtil } from "../../framework/storage/EncryptUtil";
import { StringUtil } from "../../framework/util/StringUtil";
import { GameEvent } from "../data/GameEvent";

import { HttpUtil } from "./HttpUtil";
import { NetManager, NetMgr } from "./NetManager";
import { md5 } from "../../framework/storage/Md5";
import { TimeUtil } from "../../framework/util/TimeUtil";

import { AccountData } from "../data/AccountData";

const Macro = {
    cur_uuid: "cur_uuid",                   //当前用户uuid
    cur_token: "cur_token",                 //当前用户token
}

//登录及登录后网络业务逻辑  网络业务逻辑层的NetMgr

export class LoginManager {
    private _key = 'dd2edb87ea9eb7DFa32fd4IO0572ZX76d3a1fab861c1d5qishituan';
    private _iv = '096a4f23f1874640ab5f4bc82c7d3531';
    private _token = "";
    private _server_url = "http://118.178.135.110/sdk/debug/login.php?"
    private _channel: number | string = null;
    private _uuid: number | string = null;
    private _user_out = false;				//是否被挤掉线
    private _class_id = StringUtil.getUUID(32);
    private _login_callback: (state: number) => void = null
    private _gateway_data: object = {};
    private userId: string = '';
    private gatewayData = null;
    private serverOpenId = null;
    private postList = [];
    // public time_gap: number = 0;
    // public time_gap2: number = 0;
    private serverPost: boolean = false;
    private autoOpenBox: boolean = false;
    private timeOut = [];
    private ReLoginUI_open = false;
    private postNum = 0;
    private ws_url = '';
    private we_req = null;
    private _seq = 1
    private _last_seq = 0;
    //重连次数
    private _reconnectNum = 0;
    // 服务器请求状态
    private post_server: object = {};
    constructor() {
    }
    init(){
        if(!NetMgr) {
            let netMgr = NetManager.instance;
            if(!netMgr){
                return
            }
        }
        Framework.event.addEvent("account_auth_userState", (res) => {
            res = JSON.parse(res);
            if (res.state == 2) {
                this._user_out = true;
                // Framework.layer.closeAll();
            }
        }, this, this._class_id);
        Framework.event.addEvent("gate_main_login", (res) => {
            res = JSON.parse(res);
            if (res.state == 0) {
                this._user_out = false;
                this._login_callback && this._login_callback(1);
            } else {
                this._login_callback && this._login_callback(0);
            }
        }, this, this._class_id);

        Framework.event.addEvent(FrameworkConf.Event.NET_CLOSE, (event) => {
            let NetWork = false;
            console.log('长链接握手');
            this._reconnectNum++;
            if(this._reconnectNum > 5) return;
            this.sendPost('user', 'check_connect', (data) => {
                NetWork = true;
                if (this.ws_url) {
                    NetMgr.connect(this.ws_url, () => {
                        NetMgr.send(this.we_req)
                    })
                }
            })
            // setTimeout(() => {

            // }, 2000)

        }, this, this._class_id);
        Framework.event.addEvent(GameEvent.Ws_Hand, (event) => {
            this._reconnectNum = 0;
        }, this, this._class_id)
        
    }

    check(code: string, callback: Function) {
        let sign = "";
        if (sys.platform == sys.Platform.WECHAT_GAME) {
            sign = "wechat"
        } else if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
            sign = "tiktok"
        }
        let url = "http://124.70.72.166:9526/auth/" + sign;
        let data = { code: code };
        HttpUtil.post(url, (state: boolean, resp: any | null) => {
            if (state && resp) {
                let msg = JSON.parse(EncryptUtil.aesDecrypt(resp.d, this._key, this._iv));
                callback && callback(msg.openid);
                return;
            }
            callback && callback(null);
        }, EncryptUtil.aesEncrypt(JSON.stringify(data), this._key, this._iv));
    }
    get user_id() {
        return StringUtil.format("[{0}_{1}]", this._channel, this._uuid);
    }
    /**
     * 获取服务器列表
     * @param data 透传参数
     * @param callback 回调函数:返回获取数据
     * */
    getServerList(callback, data) {
        if (data) {
            this.userId = data.uid;
            this._server_url = data.url
            this._token = data.token
        }
        let sign = 'name=' + this.userId
        if (sys.platform == sys.Platform.WECHAT_GAME) {
            sign = "wechat"
        } else if (sys.platform == sys.Platform.BYTEDANCE_MINI_GAME) {
            sign = "tiktok"
        }
        let url = `${this._server_url}?uid=${this.userId}`;
        HttpUtil.post(url, (state: boolean, resp: any | null) => {
            if (state && resp) {
                console.log('获取服务器列表返回');
                console.log(resp);
                callback && callback(resp);
                return;
            }
            callback && callback(null);
        }, null);
    }
    /**
     * 请求gateway
     * @param data 请求参数 {openid,openkey,sid}
     * @param gateway_url 请求服务器路径
     * */
    getGateway(data, gateway_url, OpenUIBack) {
        this.serverOpenId = data.openid
        let url = gateway_url + `s${data.sid}?act=login&openid=${this.serverOpenId}&openkey=${data.openkey}&user=` + this.userId
        // let gateway_url = 
        // let data = {
        //     openid: xxx,    //上面获取到的openid
        //     openkey: xx,    //上面获取到的openkey
        //     sid: xx,        // 选择的服务器列表信息中的id
        // }
        HttpUtil.get(url, (code: number, resp: any | null) => {
            if (code == 1 && resp) {
                console.log('请求gateway返回');
                console.log(resp);
                this.gatewayData = resp.data;
                this._server_url = this.gatewayData.game_server;
                this.login(resp.data, OpenUIBack)

                // callback && callback(msg.openid);
                return;
            }
        });
    }
    // 登录
    login(backdata, OpenUIBack) {
        this._seq = 1
        this._last_seq = 0
        let args = { "headpic": "", "system": "Fucking windows", "platform": "", "device": "PC", "name": this.userId, "lang": "cn" }
        let self = this

        this.sendPost('user', 'login', (data) => {
            console.log('登录返回数据', data)

            Framework.unionManager.dealLoginData(data)

            let min = Number(self._server_url.indexOf('//'))
            let max = self._server_url.lastIndexOf(':')
            let server = self._server_url.substring(min, max)
            let ws_url = `ws:${server}:${data.wss_port}`
            // let ws_url = 'ws://172.31.244.30:61114'
            // ws://42.192.10.28:4003
            self.ws_url = ws_url;
            let req = {
                mod: 'user',
                act: 'handshake',
                args: {
                    'auth_key': backdata.auth_key,
                    'auth_time': backdata.auth_time,
                    'openid': self.serverOpenId,
                },
                uid: backdata.uid,
            }
            self.we_req = req
            NetMgr.connect(self.ws_url, () => {
                NetMgr.send(self.we_req)
                OpenUIBack()
            })
        }, args)
    }
    sendPost(mod, act, backFun, argsObj?,errorFun?) {

        if (this._seq != this._last_seq + 1) {
            console.error(`sendPost seq error: seq ${this._seq},last_seq${this._last_seq}`)
        }
        if (!this.post_server[mod + act]) {
            this.post_server[mod + act] = 0
        } else {
            if (this.post_server[mod + act] == 0) {
                return;
            } else {
                this.post_server[mod + act] = 0;
            }
        }
        let args = {}
        if (argsObj) {
            args = argsObj
        }
        let postData = {
            mod: mod,
            act: act,
            back: backFun,
            args: args,
            errorFun: errorFun
        }
        this.postList.push(postData)

        if (!this.serverPost) {
            if (this.postList.length == 1) {
                this.shiftPostList()
            }
        }
    }
    shiftPostList() {
        this.serverPost = true;
        let postData = this.postList.shift()
        let nextPostTask = () => {
            if (this.postList.length > 0) {
                this.shiftPostList()
            } else {
                this.serverPost = false
            }
        }
        this.PostRequest(postData, nextPostTask)
    }
    // Post请求
    PostRequest(postData, nextPostTask?) {

        let nowNum = this.postNum + 1;
        if (!this.timeOut[nowNum]) {
            this.timeOut[nowNum] = true;
            setTimeout(() => {
                if (this.timeOut[nowNum]) {
                    this.ReLoginUI_open = true;
                    Framework.layer.open(ViewID.MaskUI)
                }
            }, 1000)
        }
        let nowtime = TimeUtil.getTimeStamp()
        let authSig = md5(this._key + `|||${this.gatewayData.uid}---` + nowtime).substring(0, 10)
        let data = `act=${postData.act}&mod=${postData.mod}&seq=${this._seq}&uid=${this.gatewayData.uid}&openid=${this.serverOpenId}`;
        data += `&auth_key=${this.gatewayData.auth_key}&auth_time=${this.gatewayData.auth_time}`
        data += `&last_seq=0&args=${JSON.stringify(postData.args)}`
        data += `&stime=${nowtime}&sig=${authSig}`

        let self = this
        HttpUtil.post(this._server_url, (state: boolean, resp: any | null) => {
            self.post_server[postData.mod + postData.act] = 1;
            self.timeOut[nowNum] = false;
            if (self.ReLoginUI_open) {
                self.ReLoginUI_open = false
                console.log('关闭转圈');
                Framework.layer.close(ViewID.MaskUI)
            }
            self.postNum++
            if (state && resp) {
                console.log(resp);
                if (resp.code == 1 && resp.desc == 'lock') {
                    // Framework.layer.open(ViewID.Restart, null, '网络异常,请重新登录');
                    return;
                }
                self._last_seq = Number(resp.last_seq)
                if (self._seq != self._last_seq) {
                    console.error(`server seq error: this.seq ${self._seq},last_seq ${self._last_seq}`)
                }
                self._seq++

                AccountData.serverTime = resp.serverTime;

                if (resp.code == 0) {
                    if (Object.keys(resp.data).length > 0) {
                        postData.back(resp.data)
                    } else {
                        postData.back()
                    }

                    nextPostTask && nextPostTask();
                } else {
                    if (postData.act == 'auto_open') {
                        
                        self.autoOpenBox = false;
                    }
                    if(postData.errorFun){
                        postData.errorFun(resp.code, resp.desc);
                    }
                    else{
                        self.errorCode(resp.code, resp.desc, () => {
                            // nextPostTask && nextPostTask();
                        })
                    }
                    nextPostTask && nextPostTask();
                }
            } else {
                nextPostTask && nextPostTask();
            }
            return;
        }, data);
    }

    errorCode(code, desc, next) {
        switch (code) {
            case 1:
                // 异地登录
                Framework.tips.setTips(desc)
                next()
                return;
            case 4:
                // 异地登录
                // Framework.layer.open(ViewID.Restart, null, '您的账号已在其他设备登录');
                Framework.tips.setTips('Remote login')
                return;
            case 2:
                // 服务器重启/网络断开(3是客户端自己调用写进来的)
                // Framework.layer.open(ViewID.Restart, null, '网络异常,请重新登录');
                return;
            case 3:
                // Framework.layer.open(ViewID.Restart, null, '网络异常,请重新登录');
                return;
            case 5:
                // Framework.layer.open(ViewID.Restart, null, '游戏跨天,为保证数据同步,请重新登录');
                return;
            case 10000:
                // Framework.layer.open(ViewID.Restart, null, '长时间未操作,请重新登录');
                return;
            case 10001:
                next()
                return;
            case 20000:
                // Framework.layer.open(ViewID.Restart, null, '数据异常,请重新登录');
                next()
                return;
            case 50000:
                next()
                // -- 加速器外挂/服务器lock报错,不提示任何信息
                return;
            case 300:
                Framework.tips.setTips('矿工已死亡')
                return;
            case 301:
                Framework.tips.setTips('操作不一致')
                return;
            case 302:
                Framework.tips.setTips('矿工无体力')
                return;
            case 303:
                Framework.tips.setTips('没有挖目标')
                return;
            case 304:
                Framework.tips.setTips('挖目标错误')
                return;
            case 305:
                Framework.tips.setTips('决策事件待处理')
                return;
            case 306:
                Framework.tips.setTips('炸弹不足')
                return;
            default:
                break;
        }
        //Framework.tips.setTips((ErrorcodeConf.data[code]) ? ErrorcodeConf.data[code].DescCn : desc);
    }
   
}

export let LoginMgr: LoginManager = new LoginManager;