;
(function () {
    //初始化Promise方法
    var ua = navigator.userAgent;
    var p_ios = ua.match(/(iPhone\sOS)\s([\d_]+)/);
    var p_adr = ua.match(/(Android)\s+([\d.]+)/);
    var isIOS = p_ios ? true : false;
    var isAdr = !isIOS && p_adr ? true : false;
    var isQQVideo = /(QQLiveBrowser)/i.test(ua) || /(QQLiveBroadcast)/i.test(ua);
    var isLiveApp = /(QQLiveBroadcast)/i.test(ua);
    var authToken = {
        "data": "123456",
        "token": "FE3D6EE5233D64C4709A733DCF9C89BA"
    };
    if (typeof (bridge) == "undefined") {
        var bridge = null;
    }
    //默认的Promise模型，防止出错
    var Deferred = function () {
        return {
            reject: function () {
                return this;
            },
            resolve: function () {
                return this;
            },
            done: function () {
                return this;
            },
            fail: function () {}
        };
    };
    if ($ && $.Deferred) {
        //Zepto和jquery的Promise
        Deferred = function () {
            return $.Deferred();
        };
    } else if (window.txmv && txmv.base && txmv.base.Deferred) {
        //腾讯视频基础库的Promise
        Deferred = function () {
            return new txmv.base.Deferred();
        };
    }

    function parseJSON(str_json) {
        var json_msg = null;
        try {
            json_msg = JSON.parse(str_json);
        } catch (e) {
            json_msg = null;
        }
        return json_msg;
    }

    var DeferInfo = {};

    function getDefer(key, force) {
        if (!DeferInfo[key] || !!force) {
            DeferInfo[key] = {};
            DeferInfo[key]["defer"] = new Deferred();
        }
        return DeferInfo[key]["defer"];
    }

    //将正确返回的回调函数与Promise模型中的resolve绑定，保证resolve的时候，也同样会调用回调函数
    function RsyncDefer(func_suc) {
        var defer = Deferred();
        var _funcResolve = defer.resolve;
        defer.resolve = function () {
            _funcResolve.apply(this, Array.prototype.slice.call(arguments, 0));
            func_suc && func_suc.apply && func_suc.apply(null, Array.prototype.slice.call(arguments, 0));
        };
        return defer;
    }
    /*
     * 调用接口的默认逻辑
     * @param
     *		str_method 接口名
     *		json_param 参数名
     *		fun_suc 返回值
     */
    function _handlerDefaultTpl(str_method, json_param, func_suc) {
        var defer = RsyncDefer(func_suc);
        _Bridge(function (json_msg) {
            if (json_msg && json_msg.state) {
                defer.resolve({
                    state: 1,
                    msg: "No Bridge Applied!"
                });
            } else {
                TenvideoJSBridge.invoke(str_method, json_param, function (str_msg) {
                    var json_res = parseJSON(str_msg);
                    defer.resolve({
                        state: 0,
                        data: json_res
                    });
                });
            }
        });
        return defer;
    }

    /** @description 获取的接口
     * @param
        func_suc 获取到接口之后的回调函数
     @remark 首先判断ios接口是否存在，如果不存在的话，就监听下接口ready的事件，如果再5秒钟内两者都没有获取到接口，就提示失败
     */
    function _Bridge(func_suc) {
        var defer = RsyncDefer(func_suc);

        if (window.TenvideoJSBridge) {
            if (isAdr) {
                bridge = window.Unicom;
            } else {
                bridge = window.TenvideoJSBridge;
            }
            defer.resolve();
        } else {
            document.addEventListener('onTenvideoJSBridgeReady', function () {
                if (isAdr) {
                    bridge = window.Unicom;
                } else {
                    bridge = window.TenvideoJSBridge;
                }
                defer.resolve();
            });
            //如果5秒钟之后，还是没有对应的接口，就直接返回false，说明拉取接口失败了。
            setTimeout(function () {
                if (!window.TenvideoJSBridge) {
                    defer.resolve({
                        state: 1,
                        msg: "No Bridge Applied!"
                    });
                }
            }, 5000);
        }
        return defer;
    }

    QQVideoBridge = {
        bridge: null,
        auth: function (token) {
            authToken = !!token ? token : authToken;
            var defer = new getDefer("auth");
            if (!isQQVideo) {
                defer.reject(-1);
                return defer;
            }
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        var iRet = bridge.auth(authToken.data, authToken.token);
                        defer.resolve(iRet);
                    } else {
                        bridge.invoke("auth", authToken, function (code) {
                            defer.resolve(code);
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        getCarrierInfos: function (json_param, func_suc) {
            return _handlerDefaultTpl("getCarrierInfos", json_param, func_suc);
        },
        getCarrierEnableState: function (json_param, func_suc) {
            return _handlerDefaultTpl("getCarrierEnableState", json_param, func_suc);
        },
        getUnicomNativieInfo: function (json_param) {
            var defer = new getDefer("getUnicomNativieInfo");
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        var json_msg = bridge.invoke('getUnicomNativeInfo', JSON.stringify(json_param));
                        defer.resolve(parseJSON(json_msg));
                    } else {
                        if (isLiveApp) {
                            bridge.invoke("getUnicomNativeInfo", json_param, function (json_msg) {
                                var res = json_msg && json_msg.result;
                                defer.resolve(res);
                            })
                        } else {
                            bridge.invoke("getUnicomNativieInfo", json_param, function (json_msg) {
                                defer.resolve(parseJSON(json_msg));
                            })
                        }
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        onNetworkChange: function () {
            tb.cookie.set("onNetworkChange", 1, location.hostname || location.host, false, 1);
            location.reload();
        },
        registNetworkChange: function () {
            var onNetworkChange = "QQVideoBridge.onNetworkChange";
            var netJson = {};
            netJson.callback = onNetworkChange;
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        window.Unicom.invoke('registerNetworkListener', JSON.stringify(netJson));
                    } else if (isIOS) {
                        bridge.invoke("registerNetworkListener", {}, function (json_msg) {
                            location.reload();
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
        },
        onRemoteUserMob: function (err, userMob) {
            var defer = new getDefer("getRemoteUserMob");
            if (err == 0) {
                defer.resolve(userMob);
            } else {
                defer.reject(-1);
            }
        },
        getRemoteUserMob: function (json_param) {
            var defer = new getDefer("getRemoteUserMob");
            if (!defer["loadok"]) {
                var defer = new getDefer("getRemoteUserMob", true);
            } else {
                return defer;
            }
            _Bridge(function () {
                if (bridge) {
                    json_param = json_param || {};
                    json_param.callback = "QQVideoBridge.onRemoteUserMob";
                    if (isAdr) {
                        bridge.invoke('getRemoteUserMob', JSON.stringify(json_param));
                    } else {
                        bridge.invoke("getRemoteUserMob", json_param, function (json_msg) {
                            var oJson = parseJSON(json_msg);
                            if (oJson.errcode == 0) {
                                defer["loadok"] = true;
                                defer.resolve(oJson.userMob);
                            } else {
                                defer.reject(-1);
                            }
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        processResult: function (str_name, json_result) {
            var defer = new getDefer(str_name);
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        var strJson = JSON.stringify(json_result);
                        var ret = bridge.invoke(str_name, strJson);
                        defer.resolve(ret);
                    } else {
                        bridge.invoke(str_name, json_result, function (ret) {
                            defer.resolve(ret);
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        saveResult: function (str_name, json_result) {
            var defer = new getDefer(str_name);
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        var strJson = JSON.stringify(json_result);
                        var ret = window.Unicom.invoke(str_name, strJson);
                        defer.resolve(ret);
                    } else {
                        bridge.invoke(str_name, json_result, function (ret) {
                            defer.resolve(ret);
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        getMd5: function (data) {
            var defer = new getDefer("getMd5");
            _Bridge(function () {
                if (bridge) {
                    var _json = {};
                    _json.data = data;
                    var str_param = JSON.stringify(_json);

                    function resolve(ret) {
                        var retJson = eval("(" + ret + ")");
                        var retValue = "";
                        if (!!retJson && !!retJson.value) {
                            retValue = retJson.value;
                        }
                        defer.resolve(retValue);
                    }
                    if (isAdr) {
                        var ret = window.Unicom.invoke('generateMd5', str_param);
                        resolve(ret)
                    } else {
                        bridge.invoke("generateMd5", _json, function (ret) {
                            resolve(ret)
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        getBase64: function (data, deferName) {
            var _deferName = deferName || "generateBase64";
            var defer = new getDefer(_deferName);
            _Bridge(function () {
                if (bridge) {
                    var _json = {};
                    _json.data = data;

                    function resolve(ret) {
                        var retJson = eval("(" + ret + ")");
                        var retValue = "";
                        if (!!retJson && !!retJson.value) {
                            retValue = retJson.value;
                        }
                        defer.resolve(retValue);
                    }
                    var str_param = JSON.stringify(_json);
                    if (isAdr) {
                        var ret = window.Unicom.invoke('generateBase64', str_param);
                        resolve(ret)
                    } else {
                        bridge.invoke("generateBase64", _json, function (json_msg) {
                            resolve(ret)
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        getNetworkType: function () {
            var defer = new getDefer("getNetworkType", true);
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        var ret = window.Unicom.invoke('getNetworkType');
                        var oJson = eval("(" + ret + ")");
                        defer.resolve(oJson.networkType);
                    } else {
                        bridge.invoke("getNetworkType", {}, function (ret) {
                            var oJson = eval("(" + ret + ")");
                            defer.resolve(oJson.networkType);
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        receiveHollywood: function (json_msg) {
            var defer = new getDefer("receiveHollywood");
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        var res = bridge.invoke('receiveHollywood', JSON.stringify(json_msg));
                        defer.resolve(parseJSON(res));
                    } else if (isIOS) {
                        bridge.callHandler("receiveHollywood", json_msg, function (res) {
                            defer.resolve(parseJSON(res));
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        unicomH5Report: function (json_param) {
            var defer = new getDefer("unicomH5Report");
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        bridge.invoke('reportOrderClickMta', JSON.stringify(json_param));
                        defer.resolve(0);
                    } else {
                        bridge.invoke("unicomH5Report", json_param, function () {
                            defer.resolve(0);
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        getLoginCookie: function (json_param, func_suc) {
            var defer = new getDefer("getLoginCookie", true);
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        var ret = window.Unicom.invoke('getLoginCookie');
                        var oJson = eval("(" + ret + ")");
                        defer.resolve(oJson.cookie);
                    } else {
                        bridge.invoke("getLoginCookie", {}, function (ret) {
                            var oJson = eval("(" + ret + ")");
                            defer.resolve(oJson.cookie);
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        getDeviceToken: function (json_param, func_suc) {
            var defer = new getDefer("getDeviceToken", true);
            _Bridge(function () {
                if (bridge) {
                    if (isAdr) {
                        var ret = window.Unicom.invoke('getDeviceToken');
                        var oJson = eval("(" + ret + ")");
                        defer.resolve(oJson.deviceToken);
                    } else {
                        bridge.invoke("getDeviceToken", {}, function (ret) {
                            var oJson = eval("(" + ret + ")");
                            defer.resolve(oJson.deviceToken);
                        });
                    }
                } else {
                    defer.reject(-1);
                }
            })
            return defer;
        },
        setMoreInfo: function (json_param, func_suc) {
            return _handlerDefaultTpl("setMoreInfo", json_param, func_suc);
        },
        openToolsDialog: function (json_param, func_suc) {
            return _handlerDefaultTpl("openToolsDialog", json_param, func_suc);
        },
        apply: function (name, json_param, func_suc) {
            return _handlerDefaultTpl(name, json_param, func_suc);
        }
    }

    var json_event = {};

    function _registerHandler(str_method, func_caller, func_suc) {
        var defer = RsyncDefer(func_suc);
        _Bridge(function (json_msg) {
            if (json_msg && json_msg.state) {
                defer.resolve({
                    state: 1,
                    msg: "No Bridge Applied!"
                });
            } else {
                defer.resolve({
                    state: 0
                });
                TenvideoJSBridge.on(str_method, function (data, responseCallback) {
                    func_caller && func_caller(data);
                    (typeof responseCallback == "function") && responseCallback("SUCESS"); //ios老接口有这个回调，这里保留一下
                });
            }
        });
        return defer;
    }

    /*
     * 注册APP的回调事件
     */
    QQVideoBridge.on = function (str_event, func_suc) {
        if (!json_event[str_event]) {
            json_event[str_event] = {
                eventName: str_event,
                func: []
            };
            window[str_event] = function () {
                for (var i in json_event[str_event].func) {
                    json_event[str_event].func[i].apply(null, Array.prototype.slice.call(arguments, 0));
                }
            }
            _registerHandler(str_event, window[str_event], function () {});
        }
        json_event[str_event].func.push(func_suc);
    }
    /*
     * 删除APP的回调事件
     */
    QQVideoBridge.off = function (str_event, func_suc) {
        if (!json_event[str_event]) {
            return;
        }

        if (!func_suc) {
            json_event[str_event].func = [];
        }

        for (var i = json_event[str_event].func.length - 1; i >= 0; i--) {
            if (json_event[str_event].func[i] == func_suc) {
                json_event[str_event].func.splice(i, 1);
            }
        }
    }
    /*
     * 触发事件
     */
    QQVideoBridge.trigger = function (str_event) {
        if (!json_event[str_event]) {
            return;
        }
        window[str_event].apply(null, Array.prototype.slice.call(arguments, 1));
    }

    window.QQVideoBridge = QQVideoBridge;
})();
