import { NetUtils } from "./NetUtils";

const projectId = NetUtils.getProjectId();
export default class Net {
    public static cache: object = {};

    /**
     * 
     * @param uri URL
     * @param param 参数
     * @param onSuccess 返回成功时的回调
     * @param onFail 返回失败是的回调 | 是否使用默认失败回调函数
     * @param pollingCheck 每次轮询回调
     * @param pollingCount 轮询最大次数
     */
    public static sendGet(uri: string, param: any, onSuccess: (res: any) => void, onFail?: ((res: any) => any) | boolean, pollingCheck?: (res: any) => boolean, pollingCount?: number) {
        this.mSend({
            type: "get",
            uri: uri,
            param: param,
            onSuccess: onSuccess,
            onFail: onFail,
            pollingCheck: pollingCheck,
            pollingCount: pollingCount
        });
    }

    /**
     * 
     * @param uri URL
     * @param param 参数
     * @param onSuccess 返回成功时的回调
     * @param onFail 返回失败是的回调 | 是否使用默认失败回调函数
     * @param pollingCheck 每次轮询回调
     * @param pollingCount 轮询最大次数
     */
    public static sendPost(uri: string, param: any, onSuccess: (res: any) => void, onFail?: ((res: any) => any) | boolean, pollingCheck?: (res: any) => boolean, pollingCount?: number) {
        this.mSend({
            type: "post",
            uri: uri,
            param: param,
            onSuccess: onSuccess,
            onFail: onFail,
            pollingCheck: pollingCheck,
            pollingCount: pollingCount
        });
    }

    private static mSend(net: INetData) {
        window['$'].ajax({
            type: net.type,
            url: net.uri,
            dataType: 'json',
            data: net.param,
            async: true,
            success: (result: any) => {
                Net.onResponse(net, result);
            },
            error: (message: any) => {
                Net.onError(net, message);
            }
        });

        console.log("requset", net.uri, net.param);
    }

    private static onResponse(net: INetData, result: any): void {
        //数据处理
        if (net.pollingCheck) {
            console.log('polling:', result);
        }
        if (net.pollingCount && net.pollingCheck(result)) { //轮询
            net.pollingCount -= 1;
            //轮询接口特殊处理
            setTimeout(() => {
                Net.mSend(net);
            }, 500);
        } else { //接口成功或失败
            if (net.pollingCheck && !net.pollingCount && net.pollingCheck(result)) {
                Net.onError(net, result);
            } else {
                net.onSuccess(result);
            }

        }
    }

    private static onError(net: INetData, res: any) {
        console.warn("response", net.uri, res);

        let errorMsg = res && ((res["desc"] || res["message"]) || ((res["code"] && "network error:" + res["code"]) || "network error")) || "network error";
        if (typeof net.onFail == "function") {
            if (!net.onFail(res)) { //若客户没有处理错误码，怎么默认显示错误消息或描述文字的弹窗
                console.error(errorMsg);
            }
        } else {
            if (typeof net.onFail == "boolean" && net.onFail == true) {
                Net.defaultOnFail && Net.defaultOnFail(res);
            }
            console.error(errorMsg);
        }
    }

    public static defaultOnFail: (res: any) => void = () => {
        //TODO:默认网络异常处理
        console.error("defaultOnFail");
    }

    public static urlReplace() {
        for (let i of Object.keys(Net.Url)) {
            for (let j of Object.keys(Net.urlReplaceConfig)) {
                Net.Url[i] = Net.Url[i].replace(new RegExp(j, "g"), Net.urlReplaceConfig[j]);
            }
        }
    }

    private static urlReplaceConfig = {
        "{projectId}": getProjectId
    }

    public static readonly Url = {
        signData: "/projectx/{projectId}/join_1/data.do",
        signIn: "/projectx/{projectId}/join_1/join.do",
        queryProps: "/projectx/{projectId}/scoring_1/spData.do",
        start: "/projectx/{projectId}/scoring_1/start.do",
        finalSubmit: "/projectx/{projectId}/gameStartRpwScoring/submit.do",
        revive: "/projectx/{projectId}/scoring_1/revive.do",
        constantSubmit: "/projectx/{projectId}/gameStartRpwScoring/push.do",
        rankList: "/projectx/{projectId}/join_2/data.do",
        queryRankListData: "/projectx/{projectId}/getRanking.query",
        queryNickname: "/projectx/{projectId}/join_3/userInfoList.do",
        visit: "/projectx/{projectId}/scoring_1/visit.do",
        share: "/projectx/{projectId}/join_2/join.do"
    }
}

interface INetData {
    type: string,
    uri: string,
    param: any,
    onSuccess: (res: any) => void,
    onFail?: ((res: any) => any) | boolean,
    pollingCheck?: (res: any) => boolean,
    pollingCount?: number
}

function getProjectId() {
    return engine.env.projectID;
}