import { showToast, wait, clearWait } from "../module/ctrls";
import { GDispatcher } from "./Main";

//接口枚举，包括需要调用淘宝的api，用是否含有兑吧区分，或者单独区分
export enum TbNetName {

    /**
     * 埋点统计  到时改名字
     * activityId   params  elemType
     */
    trackingReport = "squirrelsAdoptRest2c.trackingReport",
    /**
     * 进入活动调用, 刷新数据不调用该接口
     * activityId  userNick   avatar   follow   inviteId
     */
    getIndex = "babycare.getIndex",


    /**
     * 活动基本信息
     * @param activityId
     * @type {string}
     */
    getActivityBaseInfoById = "babycare.getActivityBaseInfoById",

    /**
     * 获取游戏信息
     * activityId
     */
    getGameInfo = "babycare.getGameInfo",
    /**
     * 消耗道具 ，会返回剩余所有道具数量
     * activityId  	type
     */
    consumerTools = "babycare.consumerTools",
    /**
     * 提交分数
     * activityId  level  score	 stars	isVisitSuccess(是否通关)
     */
    gameOver = "babycare.gameOver",
    /**
     * 领取任务奖励
     * activityId  taskType
     */
    receiveTaskRewards = "babycare.receiveTaskRewards",
    /**
     * 积分兑换道具和体力
     * activityId type credits
     */
    exchange = "babycare.exchange",
    /**
     * 根据等级获取奖品列表
     * activityId  level
     */
    getPrizesByLevel = "babycare.getPrizesByLevel",
    /**
     * 查询用户积分
     * activityId
     */
    queryCredits = "babycare.queryCredits",
    /**
     * 开始闯关，会返回体力值
     * activityId  level
     */
    dojoin = "babycare.dojoin",
    /**
     * 完成任务（浏览商品详情页， 关注店铺）
     * activityId   taskType
     */
    completeTask = "babycare.completeTask",
    /**
     * 任务列表
     * activityId
     */
    getTaskList = "babycare.getTaskList",

    ///////////////////前端调用接口都加个mine

    ////带用户操作，和index.js特殊操作的
    /**
     * 用户授权
     */
    authorize = 'mine.authorize',
    /**
     * 关注店铺
     */
    favorShop = "mine.favorShop",
    /**
     * 获取用户地址及确认
     * prizeId
     */
    getUserAddress = "mine.getUserAddress",
    /**
     * 获取名字
     * type
     */
    getAdoptName = "mine.getAdoptName",

    ///////////////////////////基本都是前端同步方法
    /**
     * 获取参数
     */
    getAppData = "mine.getAppData",
    /**
     * 小程序内跳到其他页面
     * url
     */
    navigateToOutside = "mine.navigateToOutside",
    /**
     * 跳转到小程序的其他页面
     * url
     */
    navigateTo = "mine.navigateTo",
    /**
     * 返回上一页或多页
     * delta，页面数，不传默认1
     */
    navigateBack = "mine.navigateBack",
    /**
     * 分享面板
     * openId
     */
    showSharePanel = "mine.showSharePanel",
    /**
     * 打开详情页
     * itemId
     */
    openDetail = "mine.openDetail",

    /**
     * 自定义埋点
     * logkey
     */
    reportAnalytics = "mine.reportAnalytics"
}

//返回数据类型，到时再调整
// interface dataIn {
//     netName: TbNetName
//     data: any
// }
//返回数据类型
interface dataOut {
    success: boolean,
    data?: any
    code?: string,
    message?: string
}

//记录数据
let dataRecord: {
    [name: string]: any
} = {};

//云函数
let fc;

/**
 * 发送接口
 * @param netName
 * @param parameter
 * @param callback
 * @param hideMsg
 */
export function sendTbNet(
    netName: TbNetName,
    parameter?: any,
    callback?: (success: boolean, res?: dataOut) => void,
    hideMsg: boolean = false
): Promise<dataOut> {
    return new Promise((resolve, reject) => {
        //网络超时
        let waitObj;
        //@ts-ignore 本地开发，直接取数据
        if (!my) {
            var url = "../../mock/miniTb/" + netName + ".json";
            fetchAsync(url)
                .then((data) => {
                    //清除超时
                    // clearWait(waitObj)
                    //记录数据
                    dataRecord[netName] = data;
                    //统一错误信息提示
                    if (!hideMsg && !data.success) showToast(data.message || "网络异常")
                    //回调
                    callback && callback(data.success, data);
                    resolve(data)
                    console.log(
                        `\n%c[ mock ]\n`
                        + `NAME  : ${netName} \n`
                        + `STATE : %o \n`
                        + `PARAM : %o \n`
                        + `%cDATA  : %o \n`
                        , `${data.success ? 'color:green' : 'color:red'}`
                        , data.success
                        , parameter
                        , `${data.success ? 'color:green' : 'color:red'}`
                        , data
                    );
                }, () => {
                })
            return
        }


        let fun = function (e: { type: string, data: dataOut }) {
            //清除超时记录
            clearWait(waitObj)
            //移除事件
            GDispatcher.removeEventListener(netName, fun);

            var d = e.data;
            //记录数据
            dataRecord[netName] = d;
            //统一错误信息提示，d.data为了区分网络超时
            if (!hideMsg && !d.success) showToast(d.message || "网络超时")
            //执行回调
            callback && callback(d.success, d);
            resolve(d)
            console.log(
                `\n%c[ request ]\n`
                + `NAME  : ${netName} \n`
                + `STATE : %o \n`
                + `PARAM : %o \n`
                + `%cDATA  : %o \n`
                , `${d.success ? 'color:green' : 'color:red'}`
                , d.success
                , parameter
                , `${d.success ? 'color:green' : 'color:red'}`
                , d
            );
        }
        //添加事件接收接口返回信息
        GDispatcher.addEventListener(netName, fun);

        //网络超时
        waitObj = wait(() => {
            //是用户操作，不设置超时
            if (netName != TbNetName.favorShop &&//关注店铺用户操作
                netName != TbNetName.getUserAddress && // 获取地址
                netName != TbNetName.authorize && // 授权
                netName != TbNetName.getAdoptName && //领养名字获取
                netName != TbNetName.trackingReport &&  //埋点接口也不考虑超时
                netName != TbNetName.reportAnalytics   //淘宝自定义埋点也不考虑超时
            ) {
                fun({ type: netName, data: { success: false } })
            }
        }, 10000)

        //用事件方式吧，派发事件发接口,,,,注意很多独有的事件名别重了，onHide,onShow,onMessage等  放到最后，因为有同步的情况
        GDispatcher.dispatchEvent({ type: "onMessage" }, { netName, parameter })
    })
    //@ts-ignore
    // if (!fc) fc = getApp().cloud.function;
    // //第一个参数视项目而定
    // fc.invoke("becheery", parameter, netName)
    //     .then((res: dataOut) => {
    //         clearWait(waitObj);
    //         //记录数据
    //         dataRecord[netName] = res;
    //         // console.log("返回数据" + JSON.stringify(res));
    //         //统一错误信息提示
    //         if (!hideMsg && !res.success) showToast(codeMsg[res.code] || res.message || "网络异常")
    //         //回调
    //         callback(res.success, res);
    //     })
}

/**
 * 获取数据
 * @param netName
 */
export function getTbData(netName: TbNetName): dataOut {
    return dataRecord[netName] || null;
}

//销毁数据
export function destroyNetData() {
    dataRecord = {}
}

//webview里调用无效，用postMessage去调
// export const navigateToOutside = (url) => {
//     my.call("navigateToOutside", {
//         url
//     }, (res) => {
//         // my.alert({ content: "success - " + JSON.stringify(res)})
//     });
// }

async function fetchAsync(url: string) {
    // await response of fetch call
    let response = await fetch(url);
    // only proceed once promise is resolved
    let data = await response.json();
    // only proceed once second promise is resolved
    return data;
}


// const { cloud } = window["getApp"]();
// const { function: fc } = cloud;
// fc.invoke("duiba.sign.doJoin", { signActivityId: 1 })
//     .then(res => {
//         console.log(res);
//     })

/**
 * 错误码列表，字段不设枚举了
 */
const codeMsg = {
    "210001": "服务器异常",
    "210002": "用户不存在",
    "210003": "邀请已达上限",
    "210004": "无法邀请自己",
    "210006": "该活动ID无效",
    "210009": "该活动暂未开始",
    "210010": "该分享ID不存在",
    "210012": "该用户暂未获奖",
    "210013": "领取失败",
    "210015": "该活动已删除",
    "210016": "该活动已经结束",
    "210017": "该奖品已达领取上线",
    "210018": "请先分享好友",
    "210019": "暂有奖品未领取",
    "210020": "暂有奖品未完成",
    "210021": "请先玩一局游戏",
    "210022": "请先选择奖品",
    "210023": "领取失败，库存不足",
    "210024": "请先成为会员",
    "210025": "奖品已经过期",
    "210026": "不能重复助力",
    "210028": "请至我的奖品页重新领取",//重新领取
}
