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

    //--------------------------------------------------新宿汰----------------------------------------------------
    /**
     * 获取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 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 getSignData(callback:Function):void{
        const net: INetData = {
            name: NetName.SIGN_DATA,
            uri: window['CFG'].projectId + '/join_1/data.do',
            type: 'get',
            dataType: 'json',
            param: null,
            callback: callback
        };
        this.send(net);
    }
    
    /**
     * 签到
     * @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 shareData(callback:Function):void{
        const net: INetData = {
            name: NetName.SHARE,
            uri: window['CFG'].projectId + '/join_2/join.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);
    }

}