import { showToast } from "../../module/ctrls";
import { GDispatcher } from "../index";

//接口枚举，包括需要调用淘宝的api，用是否含有兑吧区分，或者单独区分
export enum TbNetName {
    /**
     * 埋点统计
     * activityId  type
     */
    addData = "surge.addStat",

    /**
     * 活动基本信息
     * activityId
     */
    getActivityBaseInfoById = "feileJump.getActivityBaseInfoById",

    getGameInfo = "feileJump.getGameInfo",

    startGame = "feileJump.startGame",

    doHelp = "feileJump.doHelp",

    getVipInfo = "feileJump.getVipInfo",

    submitGame = "feileJump.submitGame",

    continueGame = "feileJump.continueGame",

    getRankList = "feileJump.getRankList",

    getPrizeList = "feileJump.getPrizeList",

    getRankRewards = "feileJump.getRankRewards",

    getMyRankPrize = "feileJump.getMyRankPrize",

    receiveEnamePrize = "feileJump.receiveEnamePrize",

    openMember = "mine.openMember",

    openTask = "mine.openTask",

    ///////////////////前端调用接口都加个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",
    /**
     * 打开音频
     * isOn
     */
    openMusic = "mine.openMusic",
}

//返回数据类型
interface dataOut {
    success: boolean,
    data?: any
    code?: string,
    message?: string
}

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

/**
 * 发送接口
 * @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 (__ENV__ == "development") {
            const netInfo = netName.split(".");
	        const url = `../../mock/miniTb/${netInfo[0]}/${netInfo[1]}.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
                    );
                }, () => {
                    resolve({ success: false, data: null });
                })
            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);
        //用事件方式吧，派发事件发接口,,,,注意很多独有的事件名别重了，onHide,onShow,onMessage等  放到最后，因为有同步的情况
        GDispatcher.dispatchEvent({ type: "onMessage" }, { netName, parameter })
    })
}


export function addData(type) {
    sendTbNet(
        TbNetName.addData,
        { type },
        null,
        true,
    );
}

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

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

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;
}

/**
 * 曝光埋点枚举
 * 自定义，注意淘宝控制台也需要相应配置
 */
export enum LogTbEnum {
    AD = "ad",
    TASK_ICON = 'taskIcon',
    FOLLOW_SHOP = 'followShop',
    INVITE_FRIEND = 'inviteFriend',
    BROWSE_PRODUCT = 'browseProduct',
    COLLECTION_PRODUCT = 'collectionProduct',
    BUY_PRODUCT = 'buyProduct',
    IMPROVE_INFORMATION = 'improveInformation',
    SECRET_ORDER = 'secretOrder',
    SIGN_ICON = 'signIcon',
    BAG_ICON = 'bagIcon',
}

/**
 * 淘宝小程序点击埋点，自定义字段，
 * @param elemType
 */
export function clickLogTb(elemType: LogTbEnum) {
    //TODO确定参数
    sendTbNet(TbNetName.addData, { params: { elemType }, type: "click" }, () => {
    }, true)
    //淘宝自定义埋点
    sendTbNet(TbNetName.reportAnalytics, { logkey: elemType }, () => {
    }, true)
}

//上面的可以也可以搞曝光的，反正都是手动
// export function showLog(elemType: string) {
//     sendTbNet(TbNetName.trackingReport, { params: { elemType }, type: "exposure" }, () => { }, true)
//     //淘宝自定义埋点
//     sendTbNet(TbNetName.reportAnalytics, { logkey: elemType }, () => { }, true)
// }

/**
 * 询问安卓淘宝加载权限,
 * @param tryCloudUrl
 */
export async function checkTbDownloadPermission(tryCloudUrl: string) {
    var tbMy;
    try {//判断my是否有声明，万一引擎里去掉了my的声明，其他地方就要改成try的方式,或者用getEnv判断
        //@ts-ignore
        tbMy = my;
    } catch (err) {
    }
    if (!tbMy) return;
    //@ts-ignore
    const { cloud } = getApp();
    //测试地址//到时云存储传一个小json，，改路径
    var url = tryCloudUrl//"cloud://B4F0300E5148F478B506DEDC26EA4C6C//butterfly0.svga";
    //获取临时地址
    var urls = await cloud.file.getTempFileURL({ fileId: [url] })
    url = urls[0].url.replace('-internal', '');
    tbMy.downloadFile({
        url: url,
        success(res) {
            var i = res.apFilePath;
            tbMy.getFileSystemManager().readFile({
                filePath: i,
                // encoding: "utf8",
                success: function (r) {
                },
                fail: function (res) {
                }
            })
        },
        fail(res) {
        },
    });
}

/**
 * 获取淘宝服务器时间，获取失败会直接用Date.now()
 * @returns {number} 服务器时间戳
 */
export const getTbServerTime = (): Promise<number> => {
    return new Promise((resolve, reject) => {
        if (FYGE.getEnv() == "tb") {
            // @ts-ignore
            my.getServerTime({
                success: (res) => {
                    resolve(+res.time);
                },
                fail: err => {
                    resolve(Date.now());//失败就返回当前时间
                }
            });
        } else {
            resolve(Date.now());
        }
    });
};


//淘宝奖品类型，可能会变
export enum TBPRIZE_TYPE {
    ENAME = 1,
    CREDITS = 2,
    OBJECT = 3,
    THANKS = 5
}

