var system=require("../../system")
var settings=require("../../../config/settings");
var crypto = require('crypto');
const XMLParser = require('xml2js');
const Promise = require('bluebird');
const parseXML = Promise.promisify(XMLParser.parseString);
const buildXML = new XMLParser.Builder({ rootName: 'xml', cdata: true, headless: true, renderOpts: { indent: ' ', pretty: 'true' } });
const WxopBase = require("../wxop.base");
/**
 * 微信开放平台(第三方平台)接口
 * zhuangbing
 * 2019.07.23
 */
class OpenplatformWxop extends WxopBase{
    constructor(){
        super();
        this.options = settings.wxopenplatformconfig;
        this.appId = this.options.appid;
        this.encodingAESKey = this.options.encodingaeskey;
        this.token = this.options.checktoken;
        this.aesKey = this.getAesKey(this.encodingAESKey);
        this.iv = this.getIv(this.aesKey);
        this.db=system.getObject("db.connection").getCon();
        this.cacheManager=system.getObject("db.cacheManager");
        this.rc=system.getObject("util.execClient");
        this.wxappSve=system.getObject("service.wxappSve");
    }
    /**
     * 获取第三方平台component_access_token
     * 第三方平台component_access_token是第三方平台的下文中接口的调用凭据，也叫做令牌（component_access_token）。
     * 每个令牌是存在有效期（2小时）的，且令牌的调用不是无限制的，请第三方平台做好令牌的管理，在令牌快过期时（比如1小时50分）再进行刷新。
     * @param component_appid	第三方平台appid 
     * @param component_appsecret	第三方平台appsecret 
     * @param component_verify_ticket	微信后台推送的ticket，此ticket会定时推送，具体请见本页的推送说明
     * 返回结果：
     * component_access_token	第三方平台access_token
     * expires_in	有效期
     */
    async api_component_token(){
        console.log("api_component_token+++++++start+++++++++++++++++++++++++++++++++++++++");
        var component_verify_ticket = await this.cacheManager["WxcomponentverifyticketCache"].cacheComponentVerifyTicket(null);
        console.log("component_verify_ticket:"+component_verify_ticket);
        if(!component_verify_ticket){
            return null;
        }
        var obj={
            component_appid:this.appId,//	第三方平台appid
            component_appsecret:this.options.appsecret,//	第三方平台appsecret
            component_verify_ticket:component_verify_ticket	//微信后台推送的ticket，此ticket会定时推送，具体请见本页的推送说明
        };
        var url="https://api.weixin.qq.com/cgi-bin/component/api_component_token";
        try{
            var rtn=await this.rc.execPost(obj,url);
            console.log(rtn);
            var result=JSON.parse(rtn.stdout);
            console.log("api_component_token+++++++end+++++++++++++++++++++++++++++++++++++++");
            return result;
        }catch(e){
            return null;
        }
    }
    /**
     * 获取预授权码pre_auth_code
     * 该API用于获取预授权码。预授权码用于公众号或小程序授权时的第三方平台方安全验证。
     * @param component_appid	第三方平台方appid
     * 返回结果：
     * pre_auth_code	预授权码
     * expires_in	有效期，为10分钟
     */
    async api_create_preauthcode(obj){
        var component_access_token = obj.component_access_token;
        var url="https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token="+component_access_token;
        try{
            var rtn=await this.rc.execPost({component_appid:this.appId},url);
            console.log(rtn);
            var result=JSON.parse(rtn.stdout);
            return result;
        }catch(e){
            return null;
        }
    }
    /**
     * 使用授权码换取公众号或小程序的接口调用凭据和授权信息
     * 该API用于使用授权码换取授权公众号或小程序的授权信息，并换取authorizer_access_token和authorizer_refresh_token。 
     * 授权码的获取，需要在用户在第三方平台授权页中完成授权流程后，在回调URI中通过URL参数提供给第三方平台方。
     * 请注意，由于现在公众号或小程序可以自定义选择部分权限授权给第三方平台，因此第三方平台开发者需要通过该接口来获取公众号或小程序具体授权了哪些权限，
     * 而不是简单地认为自己声明的权限就是公众号或小程序授权的权限。
     * @param component_appid	第三方平台appid
     * @param authorization_code	授权code,会在授权成功时返回给第三方平台，详见第三方平台授权流程说明
     * 返回结果：
     * authorization_info	授权信息
     * authorizer_appid	授权方appid
     * authorizer_access_token	授权方接口调用凭据（在授权的公众号或小程序具备API权限时，才有此返回值），也简称为令牌
     * expires_in	有效期（在授权的公众号或小程序具备API权限时，才有此返回值）
     * authorizer_refresh_token	接口调用凭据刷新令牌（在授权的公众号具备API权限时，才有此返回值），
     * 刷新令牌主要用于第三方平台获取和刷新已授权用户的access_token，只会在授权时刻提供，请妥善保存。 
     * 一旦丢失，只能让用户重新授权，才能再次拿到新的刷新令牌
     * func_info  授权给开发者的权限集列表，ID为1到26分别代表：
     * 1、消息管理权限 2、用户管理权限 3、帐号服务权限 4、网页服务权限 5、微信小店权限 6、微信多客服权限 7、群发与通知权限 
     * 8、微信卡券权限 9、微信扫一扫权限 10、微信连WIFI权限 11、素材管理权限 12、微信摇周边权限 13、微信门店权限 
     * 15、自定义菜单权限 16、获取认证状态及信息 17、帐号管理权限（小程序） 18、开发管理与数据分析权限（小程序） 
     * 19、客服消息管理权限（小程序） 20、微信登录权限（小程序） 21、数据分析权限（小程序） 22、城市服务接口权限 23、广告管理权限 
     * 24、开放平台帐号管理权限 25、 开放平台帐号管理权限（小程序） 26、微信电子发票权限 41、搜索widget的权限 
     * 请注意： 1）该字段的返回不会考虑公众号是否具备该权限集的权限（因为可能部分具备），请根据公众号的帐号类型和认证情况，来判断公众号的接口权限。  
     */
    async api_query_auth(obj){
        var url="https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token="+obj.component_access_token;
        try{
            var rtn=await this.rc.execPost({component_appid:this.appId,authorization_code:obj.authorization_code},url);
            console.log(rtn);
            var result=JSON.parse(rtn.stdout);
            return result;
        }catch(e){
            return null;
        }
    }
    /**
     * 获取（刷新）授权公众号或小程序的接口调用凭据（令牌）
     * 该API用于在授权方令牌（authorizer_access_token）失效时，可用刷新令牌（authorizer_refresh_token）获取新的令牌。
     * 请注意，此处token是2小时刷新一次，开发者需要自行进行token的缓存，避免token的获取次数达到每日的限定额度。
     * 当换取authorizer_refresh_token后建议保存。
     * @param component_appid	第三方平台appid
     * @param authorizer_appid	授权方appid
     * @param authorizer_refresh_token	授权方的刷新令牌，刷新令牌主要用于第三方平台获取和刷新已授权用户的access_token，只会在授权时刻提供，请妥善保存。一旦丢失，只能让用户重新授权，才能再次拿到新的刷新令牌
     * 返回数据：
     * authorizer_access_token	授权方令牌
     * expires_in	有效期，为2小时
     * authorizer_refresh_token	刷新令牌
     */
    async api_authorizer_token(obj){
        var component_access_token_obj = await this.cacheManager["WxcomponentaccesstokenCache"].get();
        if(!component_access_token_obj || !component_access_token_obj.component_access_token){
            return null;
        }
        var url="https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token="+component_access_token_obj.component_access_token;
        var authorizer_appid = obj.authorizer_appid;
        var app = await this.wxappSve.dao.model.findOne({where:{appid:authorizer_appid},raw:true});
        if(!app){
            return null;
        }
        try{
            var rtn=await this.rc.execPost({component_appid:this.appId,authorizer_appid:authorizer_appid,authorizer_refresh_token:app.authorizer_refresh_token},url);
            console.log(rtn);
            var result=JSON.parse(rtn.stdout);
            return result;
        }catch(e){
            return null;
        }
    }
    /**
     * 获取授权方的帐号基本信息(公众号)
     * 该API用于获取授权方的基本信息，包括头像、昵称、帐号类型、认证类型、微信号、原始ID和二维码图片URL。
     * 需要特别记录授权方的帐号类型，在消息及事件推送时，对于不具备客服接口的公众号，需要在5秒内立即响应；
     * 而若有客服接口，则可以选择暂时不响应，而选择后续通过客服接口来发送消息触达粉丝。
     * @param component_appid	第三方平台appid
     * @param authorizer_appid	授权方appid
     */
    async api_get_authorizer_info(obj){
        
        var url=url="https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token="+obj.component_access_token;;
        var obj={component_appid:this.appId,authorizer_appid:obj.authorizer_appid};
        try{
            var rtn=await this.rc.execPost(obj,url);
            console.log(rtn);
            var result=JSON.parse(rtn.stdout);
            return result;
        }catch(e){
            return null;
        }
        
    }
    /**
     * 通过oauth授权code换取公众号access_token（openid）
     * 传参：
     * appid	是	公众号的appid
        code	是	填写第一步获取的code参数
        grant_type	是	填authorization_code
        component_appid	是	服务开发方的appid
        component_access_token	是	服务开发方的access_token
     * 返回结果：
     *  access_token	接口调用凭证
        expires_in	access_token接口调用凭证超时时间，单位（秒）
        refresh_token	用户刷新access_token
        openid	授权用户唯一标识
        scope	用户授权的作用域，使用逗号（,）分隔
     */
    async getPfAccesstoken(obj){
        var component_access_token_obj = await this.cacheManager["WxcomponentaccesstokenCache"].get();
        if(!component_access_token_obj || !component_access_token_obj.component_access_token){
            return null;
        }
        var url="https://api.weixin.qq.com/sns/oauth2/component/access_token?appid="+obj.appid+"&code="+obj.code+"&grant_type=authorization_code&component_appid="+this.appId+"&component_access_token="+component_access_token_obj.component_access_token;
        try{
            var rtn=await this.rc.execGet({},url);
            console.log(rtn);
            var result=JSON.parse(rtn.stdout);
            return result;
        }catch(e){
            return null;
        }
    }
    /**
     * 通过网页授权access_token获取用户基本信息（需授权作用域为snsapi_userinfo）
     * @param access_token	网页授权接口调用凭证,注意：此access_token与基础支持的access_token不同
     * @param openid	用户的唯一标识
     */
    async getPfUserInfo(obj){
        var component_access_token_obj = await this.cacheManager["WxcomponentaccesstokenCache"].get();
        if(!component_access_token_obj || !component_access_token_obj.component_access_token){
            return null;
        }
        var url="https://api.weixin.qq.com/sns/userinfo?access_token="+obj.access_token+"&openid="+obj.openid+"&lang=zh_CN";
        try{
            var rtn=await this.rc.execGet({},url);
            console.log(rtn);
            var result=JSON.parse(rtn.stdout);
            return result;
        }catch(e){
            return null;
        }
    }
}
module.exports=OpenplatformWxop;