import { Data } from './../data/Data';
// import { ABNetManager, GTime, INetData, GDispatcher } from "duiba-tc";
import { TwLang } from "../util/TwLang";
import { DataManager } from "./DataManager";
import { NetName } from '../enum/NetName';
import { ABNetManager } from '../../tc/manager/ABNetManager';
import { INetData } from '../../tc/interface/INetData';
import { GTime } from '../../tc/util/GTime';
import { IExposureData } from '../data/common/IExposureData';
import { GDispatcher } from '../../tc/util/GDispatcher';

// import { IExposureData } from '..';

export class NetManager extends ABNetManager {
    private static instance: NetManager;

    public static get ins(): NetManager {
        if(!this.instance) {
            this.instance = new NetManager();
        }
        return this.instance;
    }

    private isInit: boolean;

    constructor() {
        super();
        if(this.isInit) {
            throw Error(TwLang.lang_001);
        }
        this.isInit = true;
    }


    /**
     *  获取规则
     */
    public getRule(callback: Function): void {
        const net: INetData = {
            name: NetName.GAME_RULE,
            uri: '/ngapi/getRule',
            type: 'post',
            dataType: 'html',
            param: {
                id: ''
            },
            callback: callback
        };
        this.send(net);
    }

    //--------------------------------------------插件-----------------------------------------

    /**
     * 插件抽奖
     * @param {number} activityId 插件ID
     */
    public doJoinPlugDraw(callback: Function, activityId: number, deductCredits?: boolean): void {
        const net: INetData = {
            name: NetName.PLUG_DO_JOIN,
            uri: '/activityPlugDrawInfo/doJoinPlugdraw',
            type: 'post',
            dataType: 'json',
            param: {
                activityId: activityId,
                deductCredits: deductCredits ? deductCredits : false
            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * 查询插件抽奖订单
     * @param {number} orderId 订单ID
     * @param {number} prizeLevel 开奖等级，暂未开放
     */
    public getPlugOrderStatus(callback: Function, orderId: number, pollingCheck: Function, pollingCount = 5, prizeLevel?: number): void {
        const net: INetData = {
            name: NetName.PLUG_ORDER_STATUS,
            uri: '/plugin/getOrderStatus',
            type: 'get',
            dataType: 'json',
            param: {
                orderId: orderId
            },
            callback: callback,
            pollingCheck: pollingCheck,
            pollingCount: pollingCount
        };
        this.send(net);
    }

    /**
     * 获取token
     * @param net
     */
    public getToken(net: INetData): void {
        if(window['getDuibaToken']) {
            window['getDuibaToken']((tokenObj: any) => {
                net.param.token = tokenObj.token;
                this.send(net);
            }, (key: string, messageObj: any) => {
                this.onError(net);
            });
        } else {
            this.send(net);
        }
    }

    /**
     * 查询我的奖品记录
     * @param callback
     * @param {number} page 当前页数
     */
    public getRecord(callback: Function, page: number): void {
        const net: INetData = {
            name: NetName.GET_RECORD,
            uri: (window['recordUrl'] ? window['recordUrl'] : '') + '/Crecord/getRecord',
            type: 'get',
            dataType: 'json',
            param: {
                page: page
            },
            callback: callback
        };

        let gTime: string = '?_=' + GTime.getTimestamp();
        let realUrl: string = net.uri;
        if(realUrl.indexOf('?') != -1) {
            gTime = '&_=' + GTime.getTimestamp();
        }

        //url加参数等特殊需求（例如再玩一次需要在dostart接口的url上加埋点）
        if(net.addUrl) {
            realUrl += net.addUrl;
        }

        window['$'].ajax({
            type: net.type,
            // url: realUrl + gTime,
            url: realUrl,
            dataType: net.dataType,
            data: net.param,
            async: true,
            xhrFields: {
                withCredentials: true
            },
            crossDomain: true,
            cache: false,
            success: (result) => {
                this.onResponse(net, result);
            },
            error: (message) => {
                this.onError(net);
            }
        });
    }

    /**
     * 推啊曝光埋点(福袋)
     * @param {IExposureData} exposure
     */
    public spmshow(exposure: IExposureData): void {
        const domain = (exposure.domain ? exposure.domain : '') + '/engine/';
        const net: INetData = {
            name: 'spmshow',
            uri: domain + 'spmshow',
            type: 'get',
            dataType: 'jsonp',
            param: exposure,
            callback: null,
            hideMsg: true
        };
        this.send(net);
    }

    /**
     * 推啊点击埋点(福袋)
     * @param {IExposureData} exposure
     */
    public spmclick(exposure: IExposureData): void {
        const domain = (exposure.domain ? exposure.domain : '') + '/engine/';
        const net: INetData = {
            name: 'spmclick',
            uri: domain + 'spmclick',
            type: 'get',
            dataType: 'jsonp',
            param: exposure,
            callback: null,
            hideMsg: true
        };
        this.send(net);
    }

    /**
     * 兑吧点击埋点
     * @param {IExposureData} exposure
     */
    public clickLog(exposure: IExposureData): void {
        const net: INetData = {
            name: 'clickLog',
            uri: '/log/click',
            type: 'get',
            dataType: 'jsonp',
            param: exposure,
            callback: null,
            hideMsg: true
        };
        this.send(net);
    }

    /**
     * 兑吧曝光埋点
     * @param {IExposureData} exposure
     */
    public showLog(exposure: IExposureData): void {
        const net: INetData = {
            name: 'showLog',
            uri: exposure.domain + '/exposure/standard',
            type: 'get',
            dataType: 'jsonp',
            param: exposure,
            callback: null,
            hideMsg: true
        };
        this.send(net);
    }

    /**
     * 消息响应
     * @param net
     * @param result 结果
     */
    protected onResponse(net: INetData, result: any): void {
        //数据处理
        const data: Data = DataManager.ins.updateData(net.name, result, net.param);
        if(net.pollingCheck) {
            console.log('result=====', result);
            console.log('data=====', data);
        }
        //接口成功
        if(net.pollingCount && net.pollingCheck(data)) {
            net.pollingCount -= 1;
            //轮询接口特殊处理
            setTimeout(() => {
                this.send(net);
            }, 500);
        } else if(net.callback) {
            if(net.pollingCheck && !net.pollingCount && net.pollingCheck(data)) {
                net.callback('pollingFaild');
            } else {
                net.callback(data.success, data || result);
            }

        }
        if(!net.hideMsg) {
            GDispatcher.dispatchEvent(ABNetManager.ERROR, net, result.message || result.desc || result.msg);
        }
    }

    /**
     * 通讯底层错误
     * @param net
     * @param message
     */
    protected onError(net: INetData): void {
        if(net.callback) {
            net.callback(false);
        }

        if(!net.hideMsg) {
            GDispatcher.dispatchEvent(ABNetManager.ERROR, net);
        }
    }

    /**
     * 生成签名
     * @param {number} ticketId
     * @param {number} score
     * @param {any} gameData
     * @param {string} submitToken
     * @returns {string} 签名
     */
    private createSgin(ticketId: number, score: number, gameData: any, submitToken: string): string {
        return window['duiba_md5'](ticketId + '' + score + '' + gameData + '' + submitToken);
    }

    /**
     * 生成签名 街头篮球定制
     * @param {number} startId
     * @param {number} score
     * @returns {string} 签名
     */
    private createSgin1(startId: string, score: string): string {
        return window['duiba_md5'](startId + '' + score + 'dui88');
    }

    //--------------------------------------------------新宿汰----------------------------------------------------
    /**
     * 获取domain
     */
    public getDomain(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_DOMAIN,
            uri: '/projectx/getDomain.query',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 获取券码券详情
     */
    public getCouponInfo(callback: Function, projectOrderNo: string): void {
        const net: INetData = {
            name: NetName.GET_COUPON_INFO,
            uri: '/aaw/projectx/getCouponInfo',
            type: 'get',
            dataType: 'json',
            param: {projectOrderNo: projectOrderNo},
            callback: callback
        };
        this.send(net);
    }

    /**
     * 获取用户相关数据
     */
    public getProjectUserInfo(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_PROJECT_USER_INFO,
            uri: '/ctool/getProjectUserInfo',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 用户数据红枫树
     */
    public consumerData(callback: Function): void {
        const net: INetData = {
            name: NetName.CONSUMER_DATA,
            uri: window['CFG'].projectId + '/join_1/consumerData.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 签到数据
     * @param callback
     */
    public getInfo(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_INFO,
            uri: window['CFG'].projectId + '/join_1/data.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * GET 游戏基本信息
     * @param callback
     */
    public baseInfo(callback: Function): void {
        const net: INetData = {
            name: NetName.BASE_INFO,
            uri: window['CFG'].projectId + '/game/baseInfo.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * GET 游戏基本信息
     * @param callback
     */
    public freeStart(callback: Function): void {
        const net: INetData = {
            name: NetName.FREE_START,
            uri: window['CFG'].projectId + '/game/freeStart.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 获取21财经参与次数
     * @param callback
     */
    public getCoopTimes(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_COOP_TIEMS,
            uri: window['CFG'].projectId + '/coop/join.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 获取微信二次分享参数
     * @param callback
     */
    public getWechatInfo(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_WECHAT_INFO,
            uri: '/wechatShare/getShareInfo/v2',
            type: 'get',
            dataType: 'json',
            param: {url: window.location.href},
            callback: callback
        };
        this.send(net);

        // if (data.success) {
        //     window.wx &&
        //       wx.config({
        //         debug: false,
        //         appId: data.wxappid,
        //         timestamp: data.wxtimestamp,
        //         nonceStr: data.wxnonceStr,
        //         signature: data.wxsignature,
        //         jsApiList: ['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'chooseImage']
        //       });
        //     wx.ready(function () {
        //       invokeWX();
        //     });
        //   }
    }

    /**
     * 签到
     * @param callback
     */
    public sign(callback: Function): void {
        const net: INetData = {
            name: NetName.SIGN,
            uri: window['CFG'].projectId + '/join_1/join.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 抽奖--苏州银行姑苏
     * @param callback
     */
    public getPrize(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_PRIZE,
            uri: window['CFG'].projectId + '/join_1/join.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 获取奖品详情
     * @param callback
     * @param prizeId
     */
    public getPrizeDetail(callback: Function, prizeId: string): void {
        const net: INetData = {
            name: NetName.GET_PRIZE_DETAIL,
            uri: window['CFG'].projectId + '/prize.query',
            type: 'get',
            dataType: 'json',
            param: {ids: prizeId},
            callback: callback
        };
        this.send(net);
    }

    /**
     * 分享成功
     * @param callback
     */
    public shareData(callback: Function): void {
        const net: INetData = {
            name: NetName.SHARE,
            uri: window['CFG'].projectId + '/join_1/share.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 获取任务状态数据
     */
    public getTaskData(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_TASK_DATA,
            uri: window['CFG'].projectId + '/join_3/data.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 获取商品数据
     */
    public getProjectData(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_PROJECT_DATA,
            uri: window['CFG'].projectId + '/join_4/data.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 领取任务奖励
     * @param callback
     */
    public getMoneyData(callback: Function, taskCode: string): void {
        const net: INetData = {
            name: NetName.GET_MONEY_DATA,
            uri: window['CFG'].projectId + '/join_3/join.do',
            type: 'post',
            dataType: 'json',
            param: {
                taskCode: taskCode
            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * 兑换奖品奖励
     * @param callback
     */
    public exchangeProject(callback: Function, prizeId: string): void {
        const net: INetData = {
            name: NetName.EXCHANGE_PROJECT,
            uri: window['CFG'].projectId + '/join_4/join.do',
            type: 'post',
            dataType: 'json',
            param: {
                prizeId: prizeId
            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * [扣积分]预扣积分
     * @param callback
     */
    public creditsCost(callback: Function, credits: string): void {
        const net: INetData = {
            name: NetName.CREDITS_COST,
            uri: window['CFG'].projectId + '/credits/creditsCost.do',
            type: 'post',
            dataType: 'json',
            param: {
                toPlaywayId: 'game',
                toActionId: 'creditsStart',
                credits: credits

            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * [扣积分]查询扣积分状态
     */
    public queryStatus(callback: Function, ticketNum: string): void {
        const net: INetData = {
            name: NetName.QUERY_STATUS,
            uri: window['CFG'].projectId + '/credits/queryStatus.do',
            type: 'get',
            dataType: 'json',
            param: {
                ticketNum: ticketNum
            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * 使用积分开始游戏
     * @param callback
     */
    public creditsStart(callback: Function, creditsTicket: string): void {
        const net: INetData = {
            name: NetName.CREDITS_START,
            uri: window['CFG'].projectId + '/game/creditsStart.do',
            type: 'post',
            dataType: 'json',
            param: {
                creditsTicket: creditsTicket
            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * 提交分数接口
     * @param callback
     */
    public submit(callback: Function, token: string, score: string, startId: string, number: number): void {
        const net: INetData = {
            name: NetName.SUBMIT,
            uri: window['CFG'].projectId + '/game/submit.do',
            type: 'post',
            dataType: 'json',
            param: {
                token: token,
                score: score,
                startId: startId,
                number: number,
                encryption: this.createSgin1(startId, score)
            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * 查询本轮和上轮的排行榜期次 以及 当前用户排行信息
     */
    public RankingTypeInfo(callback: Function): void {
        const net: INetData = {
            name: NetName.RANKING_TYPE_INFO,
            uri: window['CFG'].projectId + '/game/RankingTypeInfo.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 查询排行榜
     */
    public getRanking(callback: Function, type: String, topN: number, nickname: string): void {
        const net: INetData = {
            name: NetName.GET_RANKING,
            uri: window['CFG'].projectId + '/getRanking.query',
            type: 'get',
            dataType: 'json',
            param: {
                type: type,
                topN: topN,
                nickname: nickname
            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * 查询本期次奖品列表
     */
    public prizelist(callback: Function): void {
        const net: INetData = {
            name: NetName.PRIZE_LIST,
            uri: window['CFG'].projectId + '/ranking/prizelist.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 查询用户上期排行是否中奖
     */
    public winInfo(callback: Function): void {
        const net: INetData = {
            name: NetName.WIN_INFO,
            uri: window['CFG'].projectId + '/ranking/winInfo.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 排行榜领取上期次奖品
     */
    public recievePrize(callback: Function): void {
        const net: INetData = {
            name: NetName.RECIEVE_PRIZE,
            uri: window['CFG'].projectId + 'record/recievePrize.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 查询用户上期排行是否中奖
     */
    public share(callback: Function): void {
        const net: INetData = {
            name: NetName.SHARE,
            uri: window['CFG'].projectId + '/record/share.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 首页接口
     */
    public mainIndex(callback:Function):void{
        const net: INetData = {
            name: NetName.INDEX,
            uri: window['CFG'].projectId + '/accelerator/index.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    public projectxRule(callback: Function): void {
        const net: INetData = {
            name: NetName.PROJECTX_RULE,
            uri: window['CFG'].projectId + '/projectRule.query',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    ///////////////////// 中国蓝TV /////////////////////
    /**
     * 获得任务列表
     * @param {Function} callback
     */
    public getTaskList(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_TASK_LIST,
            uri: window['CFG'].projectId + '/sign/taskList.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 首页接口
     */
    public heartbeat(callback:Function):void{
        const net: INetData = {
            name: NetName.HEART_BEAT,
            uri: window['CFG'].projectId + '/accelerator/heartbeat.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 打气接口中国蓝
     */
    public cheerup(callback:Function):void{
        const net: INetData = {
            name: NetName.CHEER_UP,
            uri: window['CFG'].projectId + '/cheerup/join.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }
    
    /** 
     * 兑换加速卡
     * @param {Function} callback
     */
    public exchangeSpeed(callback: Function): void {
        const net: INetData = {
            name: NetName.EXCHANGE_SPEED,
            uri: window['CFG'].projectId + '/accelerator/join.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }


    /**
     * 使用加速卡
     * @param {Function} callback
     */
    public useSpeed(callback: Function): void {
        const net: INetData = {
            name: NetName.USE_SPEED,
            uri: window['CFG'].projectId + '/accelerator/use.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }


    public doSign(callback: Function): void {
        const net: INetData = {
            name: NetName.DO_SIGN,
            uri: window['CFG'].projectId + '/sign/join.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    public doShare(callback: Function): void {
        const net: INetData = {
            name: NetName.DO_SHARE,
            uri: window['CFG'].projectId + '/share/join.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    public doFree(callback: Function): void {
        const net: INetData = {
            name: NetName.DO_FREE,
            uri: window['CFG'].projectId + '/luckybag/join.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    public doMoney(callback: Function): void {
        const net: INetData = {
            name: NetName.DO_MONEY,
            uri: window['CFG'].projectId + '/charge/join.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 记录新手引导
     * @param {Function} callback
     * @param step
     */
    public noviceGuide(callback: Function, step): void {
        const net: INetData = {
            name: NetName.NOVICE_GUIDE,
            uri: window['CFG'].projectId + '/accelerator/noviceGuide.do',
            type: 'post',
            dataType: 'json',
            param: {
                step: step
            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * 获取分享码
     * @param {Function} callback
     */
    public inviteCode(callback: Function): void {
        const net: INetData = {
            name: NetName.INVITE_CODE,
            uri: window['CFG'].projectId + '/assist/createItem.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 助力
     * @param {Function} callback
     */
    public doAssist(callback: Function): void {
        const net: INetData = {
            name: NetName.DO_ASSIST,
            uri: window['CFG'].projectId + '/assist/doAssist.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 邀请助力记录
     * @param {Function} callback
     */
    public inviteList(callback: Function, assistItemId): void {
        const net: INetData = {
            name: NetName.USE_SPEED,
            uri: window['CFG'].projectId + '/assist/assistList.do',
            type: 'post',
            dataType: 'json',
            param: {
                assistItemId: assistItemId
            },
            callback: callback
        };
        this.send(net);
    }

    //-------------口红机----------------
    /**
     * 口红机中信银行
     * @param {Function} callback
     */
    public getHomeInfo(callback: Function): void {
        const net: INetData = {
            name: NetName.GET_HOME_INFO,
            uri: window['CFG'].projectId + '/join/getHomeInfo.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }


    /**
     * 参加游戏
     * @param {Function} callback
     */
    public doJoin(callback: Function): void {
        const net: INetData = {
            name: NetName.DO_JOIN,
            uri: window['CFG'].projectId + '/join/join.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }


    /**
     * 抽奖
     * @param {Function} callback
     */
    public drawJoin(timestamp:string, token:string,callback: Function): void {
        const net: INetData = {
            name: NetName.DRAW_JOIN,
            uri: window['CFG'].projectId + '/draw/join.do',
            type: 'post',
            dataType: 'json',
            param: {
                timestamp:timestamp,
                token:token
            },
            callback: callback
        };
        this.send(net);
    }

    /**
     * 分享加次数
     * @param {Function} callback
     */
    public shareAction(callback: Function): void {
        const net: INetData = {
            name: NetName.SHARE_ACTION,
            uri: window['CFG'].projectId + '/join/shareAction.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

    /**
     * 失败记录提交
     * @param {Function} callback
     */
    public failRecord(callback: Function): void {
        const net: INetData = {
            name: NetName.FAIL_RECORD,
            uri: window['CFG'].projectId + '/join/failRecord.do',
            type: 'post',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }

}