var system=require("../../system")
var settings=require("../../../config/settings");
const XMLParser = require('xml2js');
const Promise = require('bluebird');
const parseXML = Promise.promisify(XMLParser.parseString);
const WxopBase = require("../wxop.base");
const logCtl = system.getObject("web.oplogCtl");
/**
 * 公众号授权
 * zhuangbing
 * 2019.07.24
 */
class EmpowerWxop extends WxopBase{
   constructor(){
     super();
    //  this.cacheManager=system.getObject("db.cacheManager");
     this.openplatformWxop = system.getObject("wxop.openplatformWxop");
     this.publicplatformWxop = system.getObject("wxop.publicplatformWxop");
     this.wxappSve = system.getObject("service.wxappSve");
     this.wxuserSve = system.getObject("service.wxuserSve");
     this.userSve = system.getObject("service.userSve");
     this.companySve = system.getObject("service.companySve");
     this.cacheManager=system.getObject("db.cacheManager");
     this.options = settings.wxopenplatformconfig;
    this.appId = this.options.appid;
    this.encodingAESKey = this.options.encodingaeskey;
    this.token = this.options.checktoken;
    this.domainname = this.options.domainname || "igtest.gongsibao.com";
   }
   async checkAndLogin(obj,req){
     try {
      logCtl.info({
        optitle: "wxop微信开放平台 checkAndLogin --info",
        op: "/base/wxop/impl/pushmsgWxop.js/checkAndLogin",
        content: req.hostname+"#####"+JSON.stringify(req.session.company)+"@@@"+ JSON.stringify(req.session.wxuser),
        clientIp: ""
      });
      var hostname = req.hostname;
      if(!hostname){
        return {code:-101,msg:"hostname参数错误"};
      }
      var company = req.session.company;
      var wxuser = req.session.wxuser;
      var user = req.session.user;
      var wuser = req.session.wxuser;
      //根据域名获取企业
      var companytmp = await this.companySve.findOne({ domainname: hostname, isEnabled: true });
      if(!companytmp || !companytmp.id ){
        return {code:-102,msg:"未知企业"};
      }
      company=companytmp;
      // //获取站点绑定的公众号
      var wxapp = await this.wxappSve.dao.model.findOne({
        where:{company_id:company.id,authorized_status:"authorized"},
        raw:true
      });
      if(!wxapp){
        return {code:-103,msg:"站点未绑定公众号"};
      }
      if(!wxuser || !wxuser.appid || wxapp.appid!=wxuser.appid){
        wxuser=null;
        user=null;
      }
      if(!user || !user.company_id || company.id!=user.company_id){
        user=null;
      }
      return {code:1,user:user,company:company,wxuser:wxuser,wxapp:wxapp,wuser:wuser};
     } catch (e) {
      logCtl.error({
        optitle: "微信开放平台wxop checkAndLogin 异常",
        op: "/base/wxop/impl/pushmsgWxop.js/checkAndLogin",
        content: e.stack ,
        clientIp: ""
      });
      return {code:-200,err:e.stack};
     }

   }
   async checkAndLogin2(obj,req){
    try {
     logCtl.info({
       optitle: "wxop微信开放平台 checkAndLogin --info",
       op: "/base/wxop/impl/pushmsgWxop.js/checkAndLogin",
       content: req.hostname+"#####"+JSON.stringify(obj),
       clientIp: ""
     });
     var hostname = req.hostname;
     if(!hostname){
       return {code:-101,msg:"hostname参数错误"};
     }
     var company = null;
     var wxuser = null;
     var user = null;
     //根据域名获取企业
     var companytmp = await this.companySve.findOne({ domainname: hostname, isEnabled: true });
     if(!companytmp || !companytmp.id ){
       return {code:-102,msg:"未知企业"};
     }
     company=companytmp;
     req.session.company=company;
     //获取站点绑定的公众号
     var wxapp = await this.wxappSve.dao.model.findOne({
       where:{company_id:company.id,authorized_status:"authorized"},
       raw:true
     });
     if(!wxapp){
       return {code:-103,msg:"站点未绑定公众号"};
     }
     if(obj.openid){
        wxuser = await this.wxuserSve.dao.model.findOne({
          where:{openid:obj.openid,appid:wxapp.appid},
          raw:true
        });
        if(wxuser){
          req.session.wxuser=wxuser;
          user = await this.userSve.dao.model.findOne({
            where:{bindOpenId:wxuser.openid,company_id:company.id},
            attributes: ["userName", "id", "nickName", "headUrl", "mobile","company_id","bindOpenId"],
            raw:true
          });
          if(user){
            req.session.user=user;
          }
        }
     }
     logCtl.info({
      optitle: "wxop微信开放平台 checkAndLogin --info",
      op: "/base/wxop/impl/pushmsgWxop.js/checkAndLogin",
      content: JSON.stringify(req.session.company)+"#####"+JSON.stringify(req.session.user)+"%%%%%"+JSON.stringify(req.session.wxuser),
      clientIp: ""
    });
     return {code:1,user:user,company:company,wxuser:wxuser};
    } catch (e) {
     logCtl.error({
       optitle: "微信开放平台wxop checkAndLogin 异常",
       op: "/base/wxop/impl/pushmsgWxop.js/checkAndLogin",
       content: e.stack ,
       clientIp: ""
     });
     return {code:-200,err:e.stack};
    }

  }
   /**
    * 接收授权相关通知(授权事件接收)
    * 当公众号对第三方平台进行授权、取消授权、更新授权后，微信服务器会向第三方平台方的授权事件接收URL（创建第三方平台时填写）推送相关通知。
    */
   async receiveEmpowerMsg(pobj,obj){
      try {
        var result = await super.decryptMsg(obj.xml,pobj.msg_signature,pobj.timestamp,pobj.nonce);
        logCtl.info({
          optitle: "wxop微信开放平台接收解密消息result-info",
          op: "/base/wxop/impl/pushmsgWxop.js/receiveEmpowerMsg",
          content: JSON.stringify(result) ,
          clientIp: ""
        });
        if(result){
          result=result.xml;
          if(result.InfoType=="component_verify_ticket"){//推送component_verify_ticket协议
            await this.cacheManager["WxcomponentverifyticketCache"].cacheComponentVerifyTicket(result.ComponentVerifyTicket);
          }else if(result.InfoType=="authorized"){//授权成功通知

          }else if(result.InfoType=="unauthorized"){//取消授权通知
            var obj={
              appid:result.AuthorizerAppid,
              authorized_status:"unauthorized"
            };
            var wxapp = await this.wxappSve.dao.model.findOne({where:{appid:result.AuthorizerAppid},raw:true});
            if(wxapp){
              await this.wxappSve.createOrUpdateAppInfo2(obj);
            }
            await this.cacheManager["WxauthorizeraccesstokenCache"].del(result.AuthorizerAppid);
          }else if(result.InfoType=="updateauthorized"){//授权更新通知

          }
          return "success";
        }
      } catch (e) {
        logCtl.error({
          optitle: "微信开放平台wxop 异常",
          op: "/base/wxop/impl/pushmsgWxop.js/receiveEmpowerMsg",
          content: e.stack ,
          clientIp: ""
        });
        return "success";
      }


   }
   /**
    * 授权页网址xxxx
    * component_appid	是	第三方平台方appid
    * pre_auth_code	是	预授权码
    * redirect_uri	是	回调URI
    * auth_type	否	要授权的帐号类型， 1则商户扫码后，手机端仅展示公众号、2表示仅展示小程序，3表示公众号和小程序都展示。如果为未制定，则默认小程序和公众号都展示。第三方平台开发者可以使用本字段来控制授权的帐号类型。
    * biz_appid	否	指定授权唯一的小程序或公众号
    */
   async componentloginpage(obj,req){
     try {
      if(!req.session || !req.session.user){
        return {code:-1,msg:"用户数据为空"}
      }
      var user = req.session.user;
      var wxapp = await this.wxappSve.dao.model.findOne({
        where:{company_id:user.company_id,authorized_status:"authorized"},
        raw:true
      });
      if(wxapp && wxapp.openid){
        return {code:-102,msg:"操作失败，该站点已绑定公众号"};
      }
      var component_access_token_obj = await this.cacheManager["WxcomponentaccesstokenCache"].get();
      if(!component_access_token_obj || (component_access_token_obj.errmsg && component_access_token_obj.errmsg!="ok") ){
          return {code:-2,msg:"第三方调用凭据获取失败"};
      }
       var pre_auth_code_obj = await this.openplatformWxop.api_create_preauthcode(component_access_token_obj);//获取预授权码
        if(!pre_auth_code_obj || !pre_auth_code_obj.pre_auth_code){
          return {code:-3,msg:"获取预授权码失败"};
        }
        var pre_auth_code = pre_auth_code_obj.pre_auth_code;
        var domainname = this.domainname;
        var backurl = "http://"+domainname+"/wxop/empowerWxop/authorizedBack?company_id="+req.session.user.company_id;
        backurl = encodeURIComponent(backurl);
        // var url="https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid="+this.appId+"&pre_auth_code="+pre_auth_code+"&redirect_uri="+backurl+"&auth_type=1";
        var url ="https://mp.weixin.qq.com/safe/bindcomponent?action=bindcomponent&no_scan=1&component_appid="+this.appId+"&pre_auth_code="+pre_auth_code+"&redirect_uri="+backurl+"&auth_type=1#wechat_redirect"
        return {code:1,data:url};
     } catch (error) {
       return {code:-200,msg:"操作失败"};
     }

   }
   /**
    * 公众号授权回调
    */
   async authorizedBack(pobj){
    try {
      logCtl.info({
        optitle: "微信开放平台公众号授权回调pobj",
        op: "/base/wxop/impl/EmpowerWxop.js/authorizedBack",
        content: JSON.stringify(pobj) ,
        clientIp: ""
      });
      // return {code:1};
      var AuthorizationCode = pobj.auth_code;//授权码
      if(AuthorizationCode && pobj.company_id){
        var obj={
          company_id:pobj.company_id,AuthorizationCode:AuthorizationCode,
          authorized_status:"authorized"
        };
        //获取第三方平台调用凭据 -- component_access_token
        var component_access_token_obj =  await this.cacheManager["WxcomponentaccesstokenCache"].get();
        if(component_access_token_obj && component_access_token_obj.component_access_token){
          //使用授权码换取公众号或小程序的接口调用凭据和授权信息 ---》authorizer_appid authorizer_access_token expires_in authorizer_refresh_token
          var authorization_info_obj = await this.openplatformWxop.api_query_auth({
            component_access_token:component_access_token_obj.component_access_token,
            authorization_code:AuthorizationCode
          });
          if(authorization_info_obj && authorization_info_obj.authorization_info){
            var authorization_info = authorization_info_obj.authorization_info;
            await this.cacheManager["WxauthorizeraccesstokenCache"].set(authorization_info.authorizer_appid,authorization_info);
            obj["appid"]=authorization_info.authorizer_appid;
            obj["authorizer_refresh_token"] = authorization_info.authorizer_refresh_token;
            //获取授权方的帐号基本信息
            var authorizer_info_obj= await this.openplatformWxop.api_get_authorizer_info({
              component_access_token:component_access_token_obj.component_access_token,
              authorizer_appid:authorization_info.authorizer_appid
            });
            if(authorizer_info_obj && authorizer_info_obj.authorizer_info){
              var authorizer_info = authorizer_info_obj.authorizer_info;
              obj["nick_name"]=authorizer_info.nick_name;
              obj["head_img"]=authorizer_info.head_img;
              obj["service_type_info"]=authorizer_info.service_type_info.id;
              obj["verify_type_info"]=authorizer_info.verify_type_info.id;
              obj["original_id"]=authorizer_info.user_name;
              obj["principal_name"]=authorizer_info.principal_name;
              obj["alias"]=authorizer_info.alias;
              obj["qrcode_url"]=authorizer_info.qrcode_url;

            }
          }
        }
        logCtl.info({
          optitle: "微信开放平台公众号授权回调-----obj ",
          op: "/base/wxop/impl/EmpowerWxop.js/authorizedBack",
          content: JSON.stringify(obj) ,
          clientIp: ""
        });
        var r = await this.wxappSve.createOrUpdateAppInfo(obj);
        return r;
      }
      return {code:-1,msg:"参数错误"};
    } catch (error) {
      logCtl.info({
        optitle: "微信开放平台公众号授权回异常",
        op: "/base/wxop/impl/EmpowerWxop.js/authorizedBack",
        content: error.stack ,
        clientIp: ""
      });
      return {code:-100,err:error.stack};
    }

   }
   //oauth回调
   async oauth(obj,req){
    logCtl.info({
      optitle: "wxop微信开放平台 oauth obj",
      op: "/base/wxop/impl/empowerWxop.js/oauth",
      content: JSON.stringify(obj) ,
      clientIp: ""
    });
    try {
      var wxapp = await this.wxappSve.getWxapp({appid:obj.appid});
      if(!wxapp){
        return {code:-1,msg:"未知的公众号"};
      }
      var company = await this.companySve.dao.model.findOne({
        where:{id:wxapp.company_id,isEnabled:true},
        attributes: ["sitename","logo","name", "id", "domainname","onlyCode", "companyType","siteTheme","sitetheme_id"],
        raw:true});
      if(!company){
        return {code:-2,msg:"未知的企业信息"};
      }else{
        req.session["company"]=company;
      }
      var obj2 = {appid:obj.appid,code:obj.code};
      var tokenobj = await this.openplatformWxop.getPfAccesstoken(obj2);//根据返回code 获取Accesstoken
      if(tokenobj && tokenobj.openid && tokenobj.access_token){
        logCtl.info({
          optitle: "wxop微信开放平台 oauth tokenobj",
          op: "/base/wxop/impl/empowerWxop.js/oauth",
          content: JSON.stringify(tokenobj) ,
          clientIp: ""
        });
        //从微信获取用户信息
        var pfuserinfo = await this.openplatformWxop.getPfUserInfo({access_token:tokenobj.access_token,openid:tokenobj.openid});
        if(pfuserinfo && pfuserinfo.openid){
          logCtl.info({
            optitle: "wxop微信开放平台 oauth pfuserinfo",
            op: "/base/wxop/impl/empowerWxop.js/oauth",
            content: JSON.stringify(pfuserinfo) ,
            clientIp: ""
          });
          //新建/更新用户
          var userobj = {
            appid:obj.appid,openid:pfuserinfo.openid,nick_name:pfuserinfo.nickname,head_img:pfuserinfo.headimgurl,
            sex:pfuserinfo.sex,country:pfuserinfo.country,province:pfuserinfo.province,
            company_id:wxapp.company_id
          };
          var res = await this.wxuserSve.subscribeEditWxUser(userobj);
        }
        //获取已存微信用户信息
        var wxuser = await this.wxuserSve.getWxUser({appid:obj.appid,openid:tokenobj.openid});
        if(!wxuser){
          return {code:-3,msg:"未知的微信用户"};
        }
        req.session["wxuser"]= wxuser;
        //获取绑定微信的用户信息
        var user = await this.userSve.dao.model.findOne({
          where:{bindOpenId:tokenobj.openid,company_id:wxapp.company_id},
          attributes: ["userName", "id", "nickName", "headUrl", "mobile","company_id","bindOpenId"],
          raw:true
        });
        if(user){
          req.session["user"]= user;
        }
        logCtl.info({
          optitle: "wxop微信开放平台 oauth wxapp---wxuser---user",
          op: "/base/wxop/impl/empowerWxop.js/oauth",
          content: JSON.stringify(wxapp)+"111"+JSON.stringify(wxuser)+"111"+JSON.stringify(user) ,
          clientIp: ""
        });
      }
      var stateObj = await this.cacheManager["WxoauthstateCache"].get(obj.state);
      await this.cacheManager["WxoauthstateCache"].del(obj.state);
      return {code:1,msg:"success",state:obj.state,stateObj:stateObj};
    } catch (e) {
      logCtl.info({
        optitle: "wxop微信开放平台 oauth error",
        op: "/base/wxop/impl/empowerWxop.js/oauth",
        content: e.stack ,
        clientIp: ""
      });
      return {code:-200,msg:"error"};
    }
   }

   //微信用户绑定手机号 （使user与wxuser相关联）
   async wxuserBindMobile(pobj,obj,req){
     var wxuser = req.session.wxuser;
     var hostname = req.hostname;
     if(!hostname){
      return {code:-101,msg:"hostname参数错误"};
     }
     var companytmp = await this.companySve.findOne({ domainname: hostname, isEnabled: true });
     if(companytmp && companytmp.id){
      obj["company_id"] = companytmp.id;
     }
     if(wxuser){
        obj["wxuser"]=wxuser;
        try {
          var res = await this.wxuserSve.connectUser(obj);
          if(res && res.code==1){
            req.session["user"] = res.data;
          }
          return res;
        } catch (e) {
          logCtl.info({
            optitle: "微信开放平台微信用户绑定手机号异常",
            op: "/base/wxop/impl/EmpowerWxop.js/wxuserBindMobile",
            content: e.stack ,
            clientIp: ""
          });
          return {code:-200,msg:"操作失败"};
        }

     }else{
       return {code:-100,msg:"未知的微信用户"};
     }


   }

   //获取oauth链接

   async getOauthLink(obj,req){
      var hostname = req.hostname;
      if(!hostname){
      return {code:-101,msg:"hostname参数错误"};
      }
      var companytmp = await this.companySve.findOne({ domainname: hostname, isEnabled: true });
      if(!companytmp || !companytmp.id){
        return {code:-102,msg:"未知企业"};
      }
      obj["company_id"]=companytmp.id;
      try {
        var state = await this.getUidInfo(16,0);
        var stateObj = {};
        if(state){
          obj["state"]=state;
          var callbackpage = obj.callbackpage;//回调跳转路由
          if(callbackpage){
            stateObj["callbackpage"] = callbackpage;
          }
          var redirectPageName = obj.redirectPageName;//回调跳转页面
          if(redirectPageName){
            stateObj["redirectPageName"] = redirectPageName;
          }
          var entcode = obj.entcode;//企业渠道码
          if(entcode){
            stateObj["entcode"] = entcode;
          }
          logCtl.info({
            optitle:"微信开放平台 cache stateObj",
            op:"empowerWxop/getOauthLink",
            content:JSON.stringify(stateObj),
            clientIp:""
          });
          await this.cacheManager["WxoauthstateCache"].set(state,stateObj);
        }
        var url = await this.publicplatformWxop.getOauthLink(obj);
        if(url){
          return {code:1,data:url};
        }else{
          return {code:-103,msg:"获取失败"};
        }
      } catch (e) {
        logCtl.info({
          optitle: "微信开放平台 获取oauth链接 异常",
          op: "/base/wxop/impl/EmpowerWxop.js/getOauthLink",
          content: error.stack ,
          clientIp: ""
        });
        return {code:-200,msg:"操作失败"};
      }
   }
}
module.exports=EmpowerWxop;
// var task = new EmpowerWxop();
// task.componentloginpage({redirect_uri:"http://igirl.gongsibao.com"}).then(d=>{
//   console.log("dddddddddddddddddddddddddd");
//   console.log(d);
// })
