const system = require("../../system");
const ServiceBase = require("../sve.base")
const settings = require("../../../config/settings")
const md5 = require("MD5");
const uiconfig = system.getUiConfig2(settings.wxconfig.appId);
class UserService extends ServiceBase {
  constructor() {
    super(ServiceBase.getDaoName(UserService));
    this.pConfigDao = system.getObject("db.pconfigDao");
    this.roleDao = system.getObject("db.roleDao");
    this.usereaccountDao = system.getObject("db.usereaccountDao");
  }

  async aftercreate(result,u,t) {
    if(u.roles && u.roles.length>0){
      var roles=await this.db.models.role.findAll({where:{id:{[this.db.Op.in]:u.roles}}});
      console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
      console.log(roles);
      if(roles && roles.length>0){
        await result.setRoles(roles,{transaction:t});
      } else {
        var role=await this.roleDao.model.findOne({where:{code:"guest"},transaction:t});
        if(role){
          await result.setRoles([role],{transaction:t});
        }
      }
    }
    return result;
  }

  async userPage(pageInfo, search) {
    var currentPage = Number(pageInfo.pageNo || 1);
    var pageSize = Number(pageInfo.pageSize || 10);

    var where = {};

    if (search.nickName) {
      where.nickName = {
        [this.db.Op.like]: "%" + search.nickName + "%"
      };
    }

    if (search.userName) {
      where.userName =  search.userName;
    }

    if (search.mobile) {
      where.mobile =  search.mobile;
    }

    if(search.isBack) {
      where.utype = Number(search.isBack) - 1;
    }

    var orderby = [
      ["id", 'desc']
    ];
    var page = await this.getPageList(currentPage, pageSize, where, orderby);
    if (page && page.rows) {
      for (var row of page.rows) {
        // this.handleDate(row, ["pay_complete_time"], "YYYY-MM-DD", -8);
        await this.setRoles(page.rows);
        await this.serDepartment(page.rows)
      }
    }
    return page;
  }
  async serDepartment(list){
    if(!list || list.length == 0) {
      return;
    }
    var deIds = [];
    for(var u of list) {
      deIds.push(u.department_id);
    }
    var sql = [];
    sql.push('SELECT id,name FROM `p_department` WHERE id IN (:deIds)');
    var deList = await this.dao.customQuery(sql.join(" "), {deIds: deIds}) || [];

    var dmap = {};
    for(var de of deList) {
      dmap[de.id] = de;
    }
    for(var u of list) {
      u.department = dmap[u.department_id] || {};
    }
  }

  async setRoles(list) {
    if(!list || list.length == 0) {
      return;
    }
    var userIds = [];
    for(var u of list) {
      userIds.push(u.id);
    }

    var sql = [];
    sql.push('SELECT t1.*, t2.user_id FROM `p_role` t1 INNER JOIN p_userrole t2 ON t1.`id` = t2.`role_id`');
    sql.push('WHERE t2.`user_id` IN (:userIds)');

    var roleList = await this.dao.customQuery(sql.join(" "), {userIds: userIds}) || [];

    var roleMap = [];
    for(var role of roleList) {
      var Roles = roleMap["userid_" + role.user_id] || [];
      Roles.push(role);
      roleMap["userid_" + role.user_id] = Roles;
    }
    for(var u of list) {
      u.Roles = roleMap["userid_" + u.id] || [];
    }
  }

  async create(qobj) {
    var self = this;
    return this.db.transaction(async function (t) {
      var result = await self.dao.create(qobj, t);
      await self.aftercreate(result,qobj, t);
      return result;
    });
  }

  async getUserByOpenId(popenid, appkey) {
    var self = this;
    return this.db.transaction(function (t) {
      return self.dao.getUserByOpenId(popenid, appkey, t);
    });
  }

  async getDLGUserByOpenId(popenid, appkey) {
    var user = await this.dao.signleUserByOpenId(popenid, appkey);
    if (user) {
      var info = await this.usereaccountDao.model.findOne({
        where: {
          user_id: user.id
        },
        raw: true
      });
      if (!info) {
        var sex = user.sex;
        var sexName = "";
        info = {
          mobile: user.mobile,
          userName: user.nickName,
          personsSign: "",
          bankno: "",
          eaccountid: "",
          email: "",
          headUrl: user.headUrl,
          sex: user.sex,
          sexName: user.sex == 'male' ? "男" : "女",
          adv: "",
          experience: "",
        }
        info = await this.usereaccountDao.create(info);
      }
      user.info = info;
    }
    return user;
  }
  async getDLGUserById(id) {
    var user = await this.dao.getById(id);
    if (user) {
      user.info = await this.usereaccountDao.model.findOne({
        where: {
          user_id: user.id
        },
        raw: true
      });
    }
    return user;
  }


  async getUidStr(len, radix) {
    var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    var uuid = [],
      i;
    radix = radix || chars.length;
    if (len) {
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    } else {
      var r;
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16;
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
        }
      }
    }
    return uuid.join('');
  }

  //根据擅长查询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 loginWithoutGift(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
        });
        return user;
      });
    });
  }
  async register(userinfo) {
    var self = this;
    var eaccount = userinfo.eaccount;
    return this.db.transaction(function (t) {
      // userinfo.password
      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
        });

        if (eaccount) {
          eaccount.user_id = user.id;
          await self.usereaccountDao.create(eaccount, t);
        }
        return user;
      });
    });
  }

  async registerPartner(userinfo, t) {
    var self = this;
    // userinfo.password
    return self.dao.create(userinfo, t).then(async function (user) {
      //按照code查询出角色,设置默认访客角色
      var role = await self.roleDao.model.findOne({
        where: {
          code: "partner"
        },
        transaction: t
      });
      console.log(role);
      await user.setRoles([role], {
        transaction: t
      });
      return user;
    });
  }

  async registerEnt(userinfo) {
    var self = this;
    // userinfo.password
    return this.db.transaction(function (t) {
      // userinfo.password
      return self.dao.create(userinfo, t).then(async function (user) {
        //按照code查询出角色,设置默认访客角色
        var role = await self.roleDao.model.findOne({
          where: {
            code: "ent"
          },
          transaction: t
        });
        console.log(role);
        await user.setRoles([role], {
          transaction: t
        });
        return user;
      });
    });
  }
  async getUserByUserNamePwd(idobj) {
    var u = await this.dao.model.findOne({
      where: {
        userName: idobj.userName,
        password: idobj.password
      },
      include: [{
        model: this.db.models.role,
        as: "Roles",
        attributes: ["id", "code"]
      }, ]
    });
    return u;
  }
  async findPartnerUser(userName) {
    return await this.findOne({
      userName: userName,
      isPartner: true,
    });
  }

  async findEntUser(userName) {
    return await this.findOne({
      userName: userName,
      isEnt: true,
    });
  }

  async getPartnerUserByUserNamePwd(idobj) {
    var u = await this.dao.model.findOne({
      where: {
        userName: idobj.userName,
        password: idobj.password,
        [this.db.Op.or]: [{
            isAdmin: true
          },
          {
            isPartner: true
          }
        ],
      },
      include: [{
        model: this.db.models.role,
        as: "Roles",
        attributes: ["id", "code"]
      }, ]
    });
    return u;
  }

  async getEntUserByUserNamePwd(idobj) {
    var u = await this.dao.model.findOne({
      where: {
        userName: idobj.userName,
        password: idobj.password,
        [this.db.Op.or]: [{
            isAdmin: true
          },
          {
            isEnt: true
          }
        ],
      },
      include: [{
        model: this.db.models.role,
        as: "Roles",
        attributes: ["id", "code"]
      }, ]
    });
    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 findMapByIds(ids) {
    return await this.dao.findMapByIds(ids);
  }

  async idsLikeNickName(nickName) {
    var result = [];
    if (!nickName || !nickName.trim()) {
      return result;
    }

    var sql = "SELECT id FROM p_user WHERE nickName LIKE :nickName ";
    var list = await this.customQuery(sql, {
      nickName: "%" + nickName + "%"
    });


    if (list) {
      for (var item of list) {
        result.push(item.id);
      }
    }
    return result;
  }

  async editDLGInfo(id, obj) {
    var user = await this.findById(id);
    if (!user) {
      return;
    }

    var info = await this.usereaccountDao.findOne({
      user_id: id
    });
    var isCreate = false;
    if (!info) {
      isCreate = true;
      info = {};
    }

    info.headUrl = obj.headUrl || "";
    info.sexName = obj.sexName || "";
    info.sex = obj.sex || null;
    info.identityName = obj.identityName || "";
    info.identity = obj.identity || null;
    info.age = obj.age || 0;
    info.height = obj.height || 0;
    info.eduName = obj.eduName || "";
    info.edu = obj.edu || null;
    info.email = obj.email || "";
    info.adv = obj.adv || "";
    info.experience = obj.experience || "";

    if (obj.headUrl && obj.headUrl.trim()) {
      user.headUrl = obj.headUrl;
    }
    if (obj.userName && obj.userName.trim()) {
      user.nickName = obj.userName;
      info.userName = obj.userName || "";
    }
    if (obj.sex && obj.sex.trim()) {
      user.sex = obj.sex;
    }

    if (isCreate) {
      info.user_id = user.id;
      await this.usereaccountDao.create(info);
    } else {
      await info.save();
    }

    await user.save();
  }

  async suggestByRoleCodes(name, roleCodes, limit) {
    var sql = [];
    sql.push("SELECT t1.id, t1.userName, t1.nickName FROM p_user t1 ");
    sql.push("INNER JOIN `p_userrole` t2 ON t1.`id` = t2.`user_id`");
    sql.push("INNER JOIN `p_role` t3 ON t2.`role_id` = t3.id");
    sql.push("WHERE t1.`deleted_at` IS NULL AND t3.`deleted_at` IS NULL ");
    sql.push("AND t3.`code` IN (:roleCodes) AND (t1.`userName` LIKE :nameLike OR t1.`nickName` LIKE :nameLike)");
    sql.push("GROUP BY t1.id LIMIT :limit ");

    var params = {
      roleCodes: roleCodes,
      nameLike: "%" + name + "%",
      limit: limit
    }
    return await this.customQuery(sql.join(" "), params);
  }

  async getMyIds(userId) {
    return await this.dao.getMyIds(userId);
  }
}
module.exports = UserService;
// var task=new UserService();
// task.getUserStatisticGroupByApp().then(function(result){
//   console.log((result));
// }).catch(function(e){
//   console.log(e);
// });
