const system=require("../../system");
const ServiceBase=require("../sve.base")
const settings=require("../../../config/settings")
const uiconfig=system.getUiConfig2(settings.wxconfig.appId);
class UserService extends ServiceBase{
  constructor(){
     super(ServiceBase.getDaoName(UserService));
     this.accountDao=system.getObject("db.accountDao");
     this.pConfigDao=system.getObject("db.pconfigDao");
     this.pTradeDao=system.getObject("db.tradeDao");
     this.appDao=system.getObject("db.appDao");
     this.roleDao=system.getObject("db.roleDao");
  }
  async getUserByUsername(username, appkey){
    var self=this;
    return this.db.transaction(function (t){
        return self.dao.getUserByUsername(username,appkey,t);
    });
  }
  async getUserByOpenId(popenid,appkey){
     var self=this;
     return this.db.transaction(function (t){
         return self.dao.getUserByOpenId(popenid,appkey,t);
     });
  }

  //根据擅长查询user
  async getMsgsUsersList(obj){
    var nickName=null;
    var tagInfo=null;
    if( obj.search != null )
    {
      nickName=obj.search.nickName==null?"":obj.search.nickName;
      tagInfo=obj.search.tagInfo==null?"":obj.search.tagInfo;
    }
    var pageSize=Number(obj.pageInfo.pageSize);
    var from=obj.pageInfo.pageNo==1?0:Number((obj.pageInfo.pageNo-1)*pageSize);
    var nickNamewhere="and user.nickName like '%"+ nickName  +"%'";
    var tagInfowhere="and partnerInfo.tagInfo like '%"+ tagInfo  +"%'";
    var sql=  "SELECT user.id,user.app_id,user.nickName,user.headUrl"
              +" FROM `p_user` AS user left join `h_partner_info` AS partnerInfo"
              +" on user.id=partnerInfo.user_id WHERE 1=1 ";
    if( nickName != '' && nickName != null )
    {
      sql += nickNamewhere;
    }
    if( tagInfo != '' && tagInfo != null )
    {
      sql += tagInfowhere;
    }
    sql += " LIMIT "+pageSize+" OFFSET "+from;
    var tmpResult=await this.dao.customQuery(sql);
    var tmpi=tmpResult.length;
    return {rows:tmpResult,total:tmpi};
  }

  //获取角色，角色产品ids
  async getAuths(userid){
    return this.dao.getAuths(userid);
  }
  async loginbyc(userInfo){
    var self=this;
      return this.db.transaction(function (t){
          return self.dao.create(userInfo,t).then(async function(user){
              //按照code查询出角色,设置默认访客角色
              var role=await self.roleDao.model.findOne({where:{code:"guest"},transaction:t});
              console.log(role);
              await user.setRoles([role],{transaction:t});
              //初次登录的赠送数量,创建一笔交易，同时增加账户数量,增加系统平台账户
              //先按照uniionID查看是否已经存在
              var account =  await  self.accountDao.findOrCreate(userInfo,t);
              var u=         await  self.dao.setAccount(user,account,t);
              //设置APP
             var app= await self.cacheManager["AppCache"].cacheApp(userInfo.appKey);
             //注意缓存的对象需要回复序列化能力，需要build
             if(app && !app.dataValues){//判断是否需要是具备orm能力
                app=self.db.models.app.build(app);
             }
              //const app=await self.appDao.findOne(userInfo.appKey,t);
              u=         await  self.dao.setApp(u,app,t);
              return u;
          });
      });
  }
  async loginWithoutGift(userInfo){
    var self=this;
    //return this.dbf.getCon().then(db=>{
      return this.db.transaction(function (t){
          if(userInfo.nickName=="蒋勇"){
            userInfo.isAdmin=true;
            userInfo.isSuper=true;
          }
          return self.dao.create(userInfo,t).then(async function(user){
              //按照code查询出角色,设置默认访客角色
              var role=await self.roleDao.model.findOne({where:{code:"guest"},transaction:t});
              console.log(role);
              await user.setRoles([role],{transaction:t});
              //初次登录的赠送数量,创建一笔交易，同时增加账户数量,增加系统平台账户
              //先按照uniionID查看是否已经存在
              var account =  await  self.accountDao.findOrCreate(userInfo,t);
              var u=         await  self.dao.setAccount(user,account,t);
              //设置APP
             var app= await self.cacheManager["AppCache"].cacheApp(userInfo.appKey);
             //注意缓存的对象需要回复序列化能力，需要build
             if(app && !app.dataValues){//判断是否需要是具备orm能力
                app=self.db.models.app.build(app);
             }
              //const app=await self.appDao.findOne(userInfo.appKey,t);
              u=         await  self.dao.setApp(u,app,t);
              return u;
          });
      });
  }
  async login(userInfo){
    var self=this;
    //return this.dbf.getCon().then(db=>{
      return this.db.transaction(function (t){
          if(userInfo.nickName=="蒋勇"){
            userInfo.isAdmin=true;
            userInfo.isSuper=true;
          }
          return self.dao.create(userInfo,t).then(async function(user){
              //按照code查询出角色,设置默认访客角色
              var role=await self.roleDao.model.findOne({where:{code:"guest"},transaction:t});
              console.log(role);
              await user.setRoles([role],{transaction:t});
              //初次登录的赠送数量,创建一笔交易，同时增加账户数量,增加系统平台账户
              //先按照uniionID查看是否已经存在
              var account =  await  self.accountDao.findOrCreate(userInfo,t);
              var u=         await  self.dao.setAccount(user,account,t);
              //设置APP
              console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                console.log(userInfo);

             var app= await self.cacheManager["AppCache"].cacheApp(userInfo.appKey);
             console.log(app);
             console.log("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy");
             //注意缓存的对象需要回复序列化能力，需要build
             if(app && !app.dataValues){//判断是否需要是具备orm能力
                app=self.db.models.app.build(app);
             }
              //const app=await self.appDao.findOne(userInfo.appKey,t);
              u=         await  self.dao.setApp(u,app,t);
              const giftNum=   await  self.pConfigDao.findByConfigType("initGift",t).then(cf=>{
                return Number(cf.configValue);
              });
              const cm= self.cacheManager;
              const giftNum2=await cm["InitGiftCache"].cacheGlobalVal(giftNum);
              //创建赠送类型交易
              var tradeObj={username:user.nickName,tradeDate:new Date(),status:"settled",baoAmount:giftNum2};

              await self.pTradeDao.create(u,account,tradeObj,t);

              // paccount.baoBalance=-1 * giftNum;
              // paccount.save({transaction:t});
              // console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
              // console.log(paccount);
              //userRtn=await self.getUserByOpenId(u.openId);
              return u;
          });
      });
  //  });
  }

  async getUserStatisticGroupByApp(){
    var sql=  "SELECT count(`user`.id) value,`user`.app_id appid,app.NAME name FROM `p_user` AS USER "
    +"LEFT JOIN p_app AS app ON app.id = `user`.app_id "
    +"WHERE `user`.app_id NOT IN(11,13,15) "
    +"GROUP BY `user`.app_id, app.`name`";
    console.log(sql);
    var result=await this.dao.customQuery(sql);
    return result;
  }

  async staffCount(userId) {
    var result = {all : 0, allBusinessLicenseCount : 0};
    var user = await super.findById(userId);
    if(!user || !user.companyOnlyCode) {
      return {count:0,rows:[]};
    }
    var whereObj={companyOnlyCode : user.companyOnlyCode};
    var onlyCodeList = await this.dao.model.findAll({where:whereObj, attributes:["onlyCode"],raw:true});

    if(onlyCodeList && onlyCodeList.length > 0) {
      result.count = onlyCodeList.length;
      var onlyCodes = [];
      for(var oc of onlyCodeList) {
        onlyCodes.push("'" + oc.onlyCode + "'");
      }

      var sql = "SELECT COUNT(1) AS num FROM `yz_business_license` WHERE onlyCode IN (" + onlyCodes.join(",") + ") AND deleted_at IS NULL ";
      var all = await this.dao.customQuery(sql);
      if(all && all.length > 0) {
        result.allBusinessLicenseCount = all[0].num;
      }
    }
    return result;
  }
  async staffList(userId, pageIndex, pageSize, nickName) {
    var user = await super.findById(userId);
    if(!user || !user.companyOnlyCode) {
      return {count:0,rows:[]};
    }
    var whereObj={companyOnlyCode : user.companyOnlyCode};
    if(nickName) {
      whereObj.nickName = {[this.db.Op.like]: "%" + nickName + "%" };
    }

    var attributesObj=["id", "openId", "nickName", "onlyCode" ,"headUrl", "mobile"];
    var result = await super.getPageList(Number(pageIndex),Number(pageSize),whereObj,[["id", 'DESC']],attributesObj);
    await this.setBusinessCount(result);
    await this.setRoles(result);
    return result;
  }

  async staffDetail(openId) {
    var user = await this.dao.model.findOne({where:{openId:openId},raw:true});
    if(user) {
      var sql = "SELECT t1.code, t1.name FROM p_role t1 INNER JOIN p_userrole t2 ON t1.id = t2.`role_id` WHERE t2.`user_id` = " + user.id + " ";
      user.roleList = await this.dao.customQuery(sql);
    }
    return user;
  }

  async setRoles(result) {
    if(!result) {
      return;
    }

    var sql = "";
    var idList = [];
    for(var r of result.rows) {
      idList.push(r.id);
    }

    var sql = "SELECT t2.user_id, t1.code FROM p_role t1 INNER JOIN p_userrole t2 ON t1.id = t2.`role_id` WHERE t2.`user_id` IN (" + idList.join(",") + ")";
    var roleList = await this.dao.customQuery(sql);
    if(!roleList || roleList.length == 0) {
      return;
    }

    var roleMap = [];
    for(var role of roleList) {
      var key = "user_id" + role.user_id;
      var lst = roleMap[key];
      if(!lst) {
        lst = [];
      }
      lst.push(role.code);
      roleMap[key] = lst;
    }

    for(var r of result.rows) {
      r.roleCodes = roleMap["user_id" + r.id] || [];
    }
  }

  async setAllBusinessCount(result) {
    if(!result) {
      return;
    }

    var sql = "";


    var codeList = [];
    var codeMap = [];
    for(var r of result.rows) {
      r.businessLicenseCount = 0;
      codeList.push("'" + r.onlyCode + "'");
    }

    var sql = "SELECT onlyCode, COUNT(1) AS num FROM `yz_business_license` WHERE onlyCode IN (" + codeList.join(",") + ") AND deleted_at IS NULL GROUP BY onlyCode ";
    var blList = await this.dao.customQuery(sql);
    if(!blList || blList.length == 0) {
      return result;
    }

    for(var bl of blList) {
      codeMap[bl.onlyCode] = bl.num;
    }

    for(var r of result.rows) {
      r.businessLicenseCount = codeMap[r.onlyCode] || 0;
    }
  }

  async setBusinessCount(result) {
    if(!result || !result.rows || result.rows.length == 0) {
      return result;
    }

    var codeList = [];
    var codeMap = [];
    for(var r of result.rows) {
      r.businessLicenseCount = 0;
      codeList.push("'" + r.onlyCode + "'");
    }

    var sql = "SELECT onlyCode, COUNT(1) AS num FROM `yz_business_license` WHERE onlyCode IN (" + codeList.join(",") + ") AND deleted_at IS NULL GROUP BY onlyCode ";
    var blList = await this.dao.customQuery(sql);
    if(!blList || blList.length == 0) {
      return result;
    }

    for(var bl of blList) {
      codeMap[bl.onlyCode] = bl.num;
    }

    for(var r of result.rows) {
      r.businessLicenseCount = codeMap[r.onlyCode] || 0;
    }
  }

  async delStaff(userId, openid) {
    var user = await this.dao.findById(userId);
    if(!user || !user.companyOnlyCode) {
      return 0;
    }

    var updUser = await super.findOne({openId : openid});
    if(!updUser) {
      return 0;
    }

    if(user.companyOnlyCode != updUser.companyOnlyCode) {
      return 0;
    }

    // 清空代理管理员角色
    var delRoleSql = "DELETE FROM `p_userrole` WHERE user_id = " + userId + " AND role_id = 14 ";
    await this.dao.customExecAddOrPutSql(delRoleSql);

    updUser.companyOnlyCode = updUser.onlyCode;
    await updUser.save();
    return 1;
  }

  async countUserSuper(userId, appId) {
    var result = {all : 0, proxyCommon: 0, proxyAdmin : 0, bigBusiness : 0};
    var user = await this.dao.findById(userId);
    if(!user) {
      return result;
    }

    if(!await this.isHasRole(userId)) {
      return result;
    }
    // 查询所有用户
    var allSql = "SELECT COUNT(1) AS num FROM p_user WHERE deleted_at is NULL AND app_id = " + appId;
    var allList = await this.dao.customQuery(allSql);
    console.log(allList, "-----------------------allList----------------------------");
    result.all = allList ? allList[0].num : 0;

    // 查询普通代理人
    var commonIds = await this.idsByRole("yz_agent", appId);
    console.log(commonIds, "-----------------------commonIds----------------------------");
    if(commonIds && commonIds.length > 0) {
      var commonSql = "SELECT COUNT(1) AS num FROM p_user WHERE deleted_at is NULL AND id IN (" + commonIds.join(",") + ") AND app_id = " + appId;
      var commonList = await this.dao.customQuery(commonSql);
      console.log(commonList, "-----------------------commonList----------------------------");
      result.proxyCommon = commonList ? commonList[0].num : 0;
    }

    // 查询代理管理员
    var adminIds = await this.idsByRole("yz_agent_admin", appId);
    console.log(adminIds, "-----------------------adminIds----------------------------");
    if(adminIds && adminIds.length > 0) {
      var adminSql = "SELECT COUNT(1) AS num FROM p_user WHERE deleted_at is NULL AND id IN (" + adminIds.join(",") + ") AND app_id = " + appId;
      var adminList = await this.dao.customQuery(adminSql);
      console.log(adminList, "-----------------------adminList----------------------------");

      result.proxyAdmin = adminList ? adminList[0].num : 0;
    }

    // 查询大照商
    var bigBusinessIds = await this.idsByRole("yz_big_business", appId);
    console.log(bigBusinessIds, "-----------------------bigBusinessIds----------------------------");

    if(bigBusinessIds && bigBusinessIds.length > 0) {
      var bigBusinessSql = "SELECT COUNT(1) AS num FROM p_user WHERE deleted_at is NULL AND id IN (" + bigBusinessIds.join(",") + ") AND app_id = " + appId;
      var bigBusinessList = await this.dao.customQuery(bigBusinessSql);
      console.log(bigBusinessList, "-----------------------bigBusinessList----------------------------");

      result.bigBusiness = bigBusinessList ? bigBusinessList[0].num : 0;
    }
    return result;
  }

  async listUserSuper(param) {
    var userId = Number(param.userId);
    var pageIndex = Number(param.pageIndex);
    var pageSize = Number(param.pageSize);
    var search = param.search;
    var code = param.code;

    var user = await this.dao.findById(userId);
    if(!user) {
      return {count:0, rows:[]};
    }

    if(!await this.isHasRole(userId)) {
      return {count:0, rows:[]};
    }

    var whereObj={app_id:user.app_id};
    if(code) {
      var userIds = await this.idsByRole(code, user.app_id);
      if(!userIds || userIds.length == 0) {
        return {count:0, rows:[]};
      }
      whereObj.id = {[this.db.Op.in]:userIds};
    }

    if(search) {
      whereObj[this.db.Op.and] = {[this.db.Op.or]: [{nickName:{[this.db.Op.like]:"%" + search + "%" }},
                        {mobile:{[this.db.Op.like]:"%" + search + "%" }}]};
    }

    var attributesObj=["id", "openId", "nickName", "onlyCode" ,"headUrl", "mobile"];
    var result = await super.getPageList(pageIndex, pageSize ,whereObj, [["id", 'DESC']], attributesObj);
    await this.setBusinessCount(result);

    await this.setRoles(result);
    return result;
  }

  async addResponsibleRole(opUserId, openId) {
    var roleSql = "SELECT t1.id, t1.code, t1.name FROM `p_role` t1 INNER JOIN p_userrole t2 ON t1.`id` = t2.`role_id` WHERE t2.`user_id` = :userId AND t1.`code` IN ('yz_agent_admin', 'yz_big_business')";
    var roleList = await this.dao.customQuery(roleSql, {userId:opUserId});
    if(!roleList || roleList.length == 0) {
      return 0;
    }

    return await this.addUserRole(opUserId, openId, "yz_agent_responsible")
  }

  async superAddUserRole(opUserId, openId, code) {
    if(!await this.isHasRole(opUserId)) {
      return 0;
    }

    return await this.addUserRole(opUserId, openId, code)
  }

  async addUserRole(opUserId, openId, code) {
    if(!code || !openId) {
      return 0;
    }

    var opUser = await this.dao.findById(opUserId);
    if(!opUser) {
      return 0;
    }

    var user = await this.dao.findOne({openId:openId, app_id:opUser.app_id});
    if(!user) {
      return 0;
    }

    var role = await this.roleDao.model.findOne({where:{code:code}});
    if(!role) {
      return 0;
    }

    var roleSql = "SELECT t1.code FROM `p_role` t1 INNER JOIN p_userrole t2 ON t1.`id` = t2.`role_id` WHERE t2.`user_id` = :userId AND t1.`code` = :code ";
    var roleList = await this.dao.customQuery(roleSql, {userId:user.id, code:code});
    if(roleList && roleList.length > 0) {
      console.log("user has this role");
      return 2;
    }

    var sql="insert into `p_userrole` (`created_at`,`updated_at`,`user_id`,`role_id`) values (?,?,?,?)";
    var tmpDate=new Date();
    var params={replacements: [tmpDate,tmpDate,user.id,role.id]};
    await this.dao.customExecAddOrPutSql(sql, params);

    // 代理管理员和大照商
    if(code == 'yz_agent_admin' || code == 'yz_big_business') {
      user.companyOnlyCode = user.onlyCode;
      user.save();
    }
    return 1;
  }

  async delUserRole(opUserId, openId, code) {
    if(!code || !openId) {
      return 0;
    }

    var user = await this.dao.findOne({openId:openId});
    if(!user) {
      return 0;
    }

    var role = await this.roleDao.model.findOne({where : {code : code}});
    if(!role) {
      return 0;
    }

    var roleSql = "DELETE FROM `p_userrole` WHERE user_id = " + user.id + " AND role_id = " + role.id;
    return await this.dao.customExecAddOrPutSql(roleSql);
  }

  // 是否超管
  async isHasRole(userId, code) {
    code = code || "yz_super_admin";
    var roleSql = "SELECT t1.id, t1.code, t1.name FROM `p_role` t1 INNER JOIN p_userrole t2 ON t1.`id` = t2.`role_id` WHERE t2.`user_id` = :userId AND t1.`code` = :code"
    var roleList = await this.dao.customQuery(roleSql, {userId:userId, code:code});

    return roleList && roleList.length > 0;
  }

  // 角色查询用户ids
  async idsByRole(code, appId) {
    var sql = "";
    sql = sql + "SELECT DISTINCT(t3.id) ";
    sql = sql + "FROM `p_role` t1 ";
    sql = sql + "INNER JOIN p_userrole t2 ON t1.`id` = t2.`role_id` ";
    sql = sql + "INNER JOIN p_user t3 ON t2.`user_id` = t3.id ";
    sql = sql + "WHERE t3.`deleted_at` IS NULL AND t1.`code`=:code AND t3.app_id=:appId ";

    var params = {code:code,appId:appId};
    var rs = await this.dao.customQuery(sql, params);
    if(!rs || rs.length == 0) {
      return [];
    }
    var ids = [];
    for(var r of rs) {
      ids.push(r.id);
    }
    return ids;
  }
}
module.exports=UserService;
// var task=new UserService();
// task.getUserStatisticGroupByApp().then(function(result){
//   console.log((result));
// }).catch(function(e){
//   console.log(e);
// });
