const system = require("../../../system");
const ServiceBase = require("../../sve.base");
const settings = require("../../../../config/settings");
const sha256 = require("sha256");
class TemplatelinkService extends ServiceBase {
  constructor() {
    super("template", ServiceBase.getDaoName(TemplatelinkService));
    this.templateLinkUrl = settings.templateLinkUrl();
    this.templateinfoDao = system.getObject("db.template.templateinfoDao");
    this.browsingrecordsDao = system.getObject("db.template.browsingrecordsDao");
    this.launchchannelDao = system.getObject("db.configmag.launchchannelDao");
    this.launchtypeDao = system.getObject("db.configmag.launchtypeDao");
    this.marketingsubjectDao = system.getObject("db.configmag.marketingsubjectDao");
    this.redisClient = system.getObject("util.redisClient");
    this.execClient = system.getObject("util.execClient");
    this.templateLinkInfoCache={};
    this.browsingRecordsLogUrl = settings.browsingRecordsLogUrl();
  }
  /**
   * 获取模板链接配置参数
   * @param {*} pobj 
   */
  async getLinkConfigParams(pobj){
    var ab = pobj.actionBody;
    var xctx = pobj.xctx;
    var company_id=xctx.companyid;
    var whereObj = {company_id:company_id};
    //渠道主体
    var launchChannelList = await this.launchchannelDao.model.findAll({
      attributes:["id","code","name"],
      where:whereObj,raw:true
    });
    //业务参数
    //投放方式
    var launchTypeList = await this.launchtypeDao.model.findAll({
      attributes:["id","code","name"],
      where:whereObj,raw:true
    });
    //营销主体
    var marketingSubjectList = await this.marketingsubjectDao.model.findAll({
      attributes:["id","code","name"],
      where:whereObj,raw:true
    });
    var res = {launchChannelList:launchChannelList,launchTypeList:launchTypeList,marketingSubjectList:marketingSubjectList};
    return system.getResultSuccess(res);
  }
  /**
   * 链接列表
   * @param {*} obj 
   */
  async findAndCountAll(obj){
    if(!obj || !obj.search || !obj.search.template_id){
      return system.getResultFail(-101,"模板id不能为空");
    }
    var res = await this.dao.findAndCountAll(obj);
    return res;
  }
  /**
   * 校验封装参数
   * @param {*} ab 
   * @param {*} xctx 
   */
  async checkAndPackageParams(ab,xctx){
    var codeParams={};
    if(!ab.channel_code){
      return system.getResultFail(-101,"渠道主体编码不能为空");
    }
    codeParams.channel_code = ab.channel_code;
    if(!ab.business_type_code){
      return system.getResultFail(-102,"业务类型编码不能为空");
    }
    codeParams.business_type_code = ab.business_type_code;
    if(!ab.lauch_type_code){
      return system.getResultFail(-103,"投放方式编码不能为空");
    }
    codeParams.lauch_type_code = ab.lauch_type_code;
    if(!ab.marketing_subject_code){
      return system.getResultFail(-104,"营销主体编码不能为空");
    }
    codeParams.marketing_subject_code = ab.marketing_subject_code;
    if(!ab.channel_name){
      return system.getResultFail(-105,"渠道主体名称不能为空");
    }
    if(!ab.business_type_name){
      return system.getResultFail(-106,"业务类型名称不能为空");
    }
    if(!ab.lauch_type_name){
      return system.getResultFail(-107,"投放方式名称不能为空");
    }
    if(!ab.marketing_subject_name){
      return system.getResultFail(-108,"营销主体名称不能为空");
    }
    if(!ab.delivery_word){
      return system.getResultFail(-109,"投放词不能为空");
    }
    if(!ab.else_channel_param){
      return system.getResultFail(-110,"其它渠道参数不能为空");
    }
    if(!ab.template_id){
      return system.getResultFail(-111,"模板参数不能为空");
    }
    if(!ab.name){
      return system.getResultFail(-112,"任务名称不能为空");
    }
    var checkCodeRes = await this.checkLinkCodeParams(codeParams);
    if(checkCodeRes && checkCodeRes.status && checkCodeRes.status<0){
      return checkCodeRes;
    }
    if(!ab.code){//新增
      ab.code = await this.getBusUid("tl");
      ab.user_id=ab.userid;
      ab.user_name=ab.username;
      ab.company_id=ab.company_id;
      ab.is_enabled=0;
      //查重
      var distinctObj = {
        template_id:ab.template_id,channel_code:ab.channel_code,else_channel_param:ab.else_channel_param,
        business_type_code:ab.business_type_code,lauch_type_code:ab.lauch_type_code,marketing_subject_code:ab.marketing_subject_code
      };
      var distinctres = await this.dao.model.findOne({
        where:distinctObj,raw:true
      });
      if(distinctres && distinctres.id){
        return system.getResultFail(-113,"操作失败，存在重复的链接");
      }
    }else{//修改
      var linkinfo = await this.dao.model.findOne({
        where:{code:ab.code},raw:true
      });
      if(!linkinfo || !linkinfo.id){
        return system.getResultFail(-300,"未知模板");
      }
      if(linkinfo.is_enabled===1){
        return system.getResultFail(-301,"该链接正在投放中，不能执行此操作");
      }
      ab.id = linkinfo.id;
      //查重
      var distinctObj = {
        template_id:ab.template_id,channel_code:ab.channel_code,else_channel_param:ab.else_channel_param,
        business_type_code:ab.business_type_code,lauch_type_code:ab.lauch_type_code,marketing_subject_code:ab.marketing_subject_code,
        id:{[this.db.Op.ne]:linkinfo.id}
      };
      var distinctres = await this.dao.model.findOne({
        where:distinctObj,raw:true
      });
      if(distinctres && distinctres.id){
        return system.getResultFail(-113,"操作失败，存在重复的链接");
      }
    }
    ab.link_url_pc = this.templateLinkUrl+"?id="+ab.template_id+"&source="+ab.channel_code+"&device=pc&event="+ab.else_channel_param+
    "&business="+ab.business_type_code+"&type="+ab.lauch_type_code+"&for="+ab.marketing_subject_code;
    ab.link_url_mobile = this.templateLinkUrl+"?id="+ab.template_id+"&source="+ab.channel_code+"&device=mobile&event="+ab.else_channel_param+
    "&business="+ab.business_type_code+"&type="+ab.lauch_type_code+"&for="+ab.marketing_subject_code;
    return ab;
  }

  /**
   * 创建模板链接数据
   * @param {*} pobj 
   */
  async createTemplateLink(pobj){
    var ab = pobj;
    var xctx = pobj.xctx;
    if(!ab){
      return system.getResultFail(-100,"参数错误");
    }
    var checkres = await this.checkAndPackageParams(ab,xctx);
    if(checkres && checkres.status<0){
      return checkres;
    }
    ab = checkres;
    var res = await this.create(ab);
    return system.getResultSuccess(res);
  }

  /**
   * 修改模板链接
   * @param {*} pobj 
   */
  async editTemplateLink(pobj){
    var ab = pobj.actionBody;
    var xctx = pobj.xctx;
    if(!ab){
      return system.getResultFail(-100,"参数错误");
    }
    if(!ab.code){
      return system.getResultFail(-100,"模板编码不能为空");
    }
    var checkres = await this.checkAndPackageParams(ab,xctx);
    if(checkres && checkres.status<0){
      return checkres;
    }
    ab = checkres;
    await this.dao.update(ab);
    if(ab.code){
      this.delRedisInfoByLinkCode(ab.code);
    }
    return system.getResultSuccess();
  }

  /**
   * 获取模板链接详情数据
   * @param {*} pobj 
   */
  async findOneByCode(pobj){
    var ab = pobj.actionBody;
    var xctx = pobj.xctx;
    if(!ab){
      return system.getResultFail(-100,"参数错误");
    }
    if(!ab.code){
      return system.getResultFail(-101,"模板编码不能为空");
    }
    var templateInfo = await this.dao.model.findOne({
      where:{code:ab.code},raw:true
    });
    return system.getResultSuccess(templateInfo);
  }

  /**
   * 修改投放状态
   * @param {*} pobj 
   */
  async updateLaunchStatus(pobj){
    var ab = pobj;
    if(!ab){
      return system.getResultFail(-100,"参数错误");
    }
    if(!ab.code){
      return system.getResultFail(-101,"链接编码不能为空");
    }
    if(!ab.hasOwnProperty("is_enabled")){
      return system.getResultFail(-102,"投放状态不能为空");
    }
    if(ab.is_enabled!==0 && ab.is_enabled!==1){
      return system.getResultFail(-103,"投放状态参数错误");
    }
    
    var linkinfo = await this.dao.model.findOne({
      where:{code:ab.code},raw:true
    });
    if(!linkinfo || !linkinfo.id){
      return system.getResultFail(-300,"未知链接");
    }
    if(ab.is_enabled===1){
      var checkLinkCodeParamsObj={
        channel_code:linkinfo.channel_code,
        lauch_type_code:linkinfo.lauch_type_code,
        marketing_subject_code:linkinfo.marketing_subject_code
      };
      var checkLinkCodeParamsRes = await this.checkLinkCodeParams(checkLinkCodeParamsObj);
      if(checkLinkCodeParamsRes && checkLinkCodeParamsRes.status && checkLinkCodeParamsRes.status<0){
        return checkLinkCodeParamsRes;
      }
    }
    await this.dao.update({id:linkinfo.id,is_enabled:ab.is_enabled});
    this.delRedisInfoByLinkCode(linkinfo.code);
    return system.getResultSuccess();
  }
  /**
   * 删除模板链接
   * @param {*} pobj 
   */
  async deleteTemplateLink(pobj){
    var ab = pobj;
    if(!ab){
      return system.getResultFail(-100,"参数错误");
    }
    if(!ab.id){
      return system.getResultFail(-101,"链接编码不能为空");
    }
    var linkinfo = await this.dao.model.findOne({
      where:{id:ab.id},raw:true
    });
    if(!linkinfo || !linkinfo.id){
      return system.getResultFail(-300,"未知模板链接");
    }
    if(linkinfo.is_enabled===1){
      return system.getResultFail(-301,"该链接正在投放中，不能执行此操作");
    }
    await this.dao.delete({id:linkinfo.id});
    return system.getResultSuccess();
  }


  /**
   * 根据链接参数获取模板链接信息
   * @param {*} pobj
   */
  async getTemplateAndLinkInfo(pobj){
    var ab = pobj.actionBody;
    var xctx = pobj.xctx;
    if(!ab){
      return system.getResultFail(-100,"参数错误");
    }
    if(!ab.channel_code){
      return system.getResultFail(-101,"渠道主体编码不能为空");
    }
    if(!ab.business_type_code){
      return system.getResultFail(-102,"业务类型编码不能为空");
    }
    if(!ab.lauch_type_code){
      return system.getResultFail(-103,"投放方式编码不能为空");
    }
    if(!ab.marketing_subject_code){
      return system.getResultFail(-104,"营销主体编码不能为空");
    }
    if(!ab.else_channel_param){
      return system.getResultFail(-110,"其它渠道参数不能为空");
    }
    if(!ab.template_id){
      return system.getResultFail(-111,"模板参数不能为空");
    }
    if(!ab.device){
      return system.getResultFail(-112,"投放终端参数不能为空");
    }
    var linkObj = {
      is_enabled:1,
      template_id:ab.template_id,channel_code:ab.channel_code,else_channel_param:ab.else_channel_param,
      business_type_code:ab.business_type_code,lauch_type_code:ab.lauch_type_code,
      marketing_subject_code:ab.marketing_subject_code
    };
    //获取链接数据
    var linkinfo = await this.dao.model.findOne({
      attributes:["code"],
      where:linkObj,raw:true
    });
    if(!linkinfo || !linkinfo.code){
      return system.getResultFail(-300,"未知链接或链接未投放");
    }
    // if(!linkinfo.is_enabled || linkinfo.is_enabled!==1){
    //   return system.getResultFail(-301,"无效链接，该链接未投放");
    // }
    var tempObj={id:ab.template_id,is_enabled:1};
    var templateinfo = await this.templateinfoDao.model.findOne({
      attributes:["title","keyword","describe","pic_url","template_content"],
      where:tempObj,raw:true
    });
    if(!templateinfo){
      return system.getResultFail(-400,"未知模板或模板未启用");
    }
    // if(!templateinfo.is_enabled || templateinfo.is_enabled!==1){
    //   return system.getResultFail(-401,"无效模板，该模板未启用");
    // }
    var resultObj = {
      templateinfo:templateinfo,linkinfo:linkinfo
    };
    var addObj = {
      ...ab,
      link_code:linkinfo.code,link_name:linkinfo.name,
      channel_name:linkinfo.channel_name,business_type_name:linkinfo.business_type_name,
      lauch_type_name:linkinfo.lauch_type_name,marketing_subject_name:linkinfo.marketing_subject_name,
      client_ip:pobj.clientIp

    };
    this.browsingrecordsDao.create(addObj);//添加链接浏览记录
    return system.getResultSuccess(resultObj);
  }


  //校验链接编码参数
  async checkLinkCodeParams(obj){
    var channelinfo = await this.launchchannelDao.model.findOne({
      attributes:["id"],
      where:{code:obj.channel_code},raw:true
    });
    if(!channelinfo || !channelinfo.id){
      return system.getResultFail(-120,"操作失败，渠道不存在或已被修改");
    }
    var lauchtype = await this.launchtypeDao.model.findOne({
      attributes:["id"],
      where:{code:obj.lauch_type_code},raw:true
    });
    if(!lauchtype || !lauchtype.id){
      return system.getResultFail(-121,"操作失败，投放类型不存在或已被修改");
    }
    var marketingsubject = await this.marketingsubjectDao.model.findOne({
      attributes:["id"],
      where:{code:obj.marketing_subject_code},raw:true
    });
    if(!marketingsubject || !marketingsubject.id){
      return system.getResultFail(-121,"操作失败，投放主体不存在或已被修改");
    }
    return system.getResultSuccess();
  }

  
  async getTemplateAndLinkInfo2(pobj){
    let ab = pobj.actionBody;
    // 校验传入的参数
    if(!ab){
      return system.getResultFail(-100,"参数错误");
    }
    if(!ab.channel_code){
      return system.getResultFail(-101,"渠道主体编码不能为空");
    }
    if(!ab.business_type_code){
      return system.getResultFail(-102,"业务类型编码不能为空");
    }
    if(!ab.lauch_type_code){
      return system.getResultFail(-103,"投放方式编码不能为空");
    }
    if(!ab.marketing_subject_code){
      return system.getResultFail(-104,"营销主体编码不能为空");
    }
    if(!ab.else_channel_param){
      return system.getResultFail(-110,"其它渠道参数不能为空");
    }
    if(!ab.template_id){
      return system.getResultFail(-111,"模板参数不能为空");
    }
    if(!ab.device){
      return system.getResultFail(-112,"投放终端参数不能为空");
    }

    let linkObj;    // 用于查询模板链接的参数，actionBody去除device参数
    let shaStr;     // 将linkObj转为字符串并计算出sha256的值
    let rtn;        // 根据shaStr从redis库中查询返回的值。
    let rtnObj;     // 1.如果从redis中查到数据，则是redis中返回的数据，2.否则就是将要储存到redis中的数据。
    let linkinfo;   // 模板链接信息
    let addObj;     // 储存访问信息
    linkObj = {
      is_enabled:1,
      template_id:ab.template_id?ab.template_id.toString():"",
      channel_code:ab.channel_code,
      else_channel_param:ab.else_channel_param,
      business_type_code:ab.business_type_code,
      lauch_type_code:ab.lauch_type_code,
      marketing_subject_code:ab.marketing_subject_code
    };
    console.log(this.templateLinkInfoCache,"222222222222222222222222222222222");
    console.log(linkObj);
    shaStr = await sha256(JSON.stringify(linkObj));
    shaStr = "templink_"+ab.template_id+"_"+shaStr;
    if(this.templateLinkInfoCache[shaStr]){
      rtn = this.templateLinkInfoCache[shaStr]; //从内存缓存读取数据 
    }else{
      rtn = await this.redisClient.get(shaStr);     //从redis读取数据 
      if(rtn){
        this.templateLinkInfoCache[shaStr] = rtn;
      }
    }
    //---- 从redis中读取到数据
    if (rtn) {    
      rtnObj = JSON.parse(rtn);
      linkinfo = rtnObj["linkinfo"];
    } else {
      // 获取模板链接信息
      linkinfo = await this.dao.model.findOne({
        attributes:[
          "code",
          "name",
          "channel_name",
          "business_type_name",
          "lauch_type_name",
          "marketing_subject_name"
        ],
        where:linkObj,raw:true
      });
      if(!linkinfo){
        return system.getResultFail(-300,"未知链接或该链接未投放");
      }

      // 模板链接存在，获取模板信息  
      let tempObj = {id:ab.template_id,is_enabled:1,};        // 用于查询templateinfo的条件
      let templateinfo = await this.templateinfoDao.model.findOne({     // 查询结果
        attributes:["title","keyword","describe","pic_url","template_content"],
        where:tempObj,raw:true
      });
      if(!templateinfo){
        return system.getResultFail(-400,"未知模板或该模板未启用");
      }
      rtnObj = {      // 组合模板链接和模板信息
        templateinfo,
        linkinfo
      };
      //将数据保存
      this.templateLinkInfoCache[shaStr] = JSON.stringify(rtnObj);
      // 将数据保存到redis中
      await this.redisClient.set(shaStr, JSON.stringify(rtnObj));
      // await this.redisClient.setWithEx(shaStr, JSON.stringify(rtnObj), 60);    // 保存的同时设置过期时间
    }

    addObj = {    // 需要保存到浏览记录的内容
      ...ab,
      link_code:linkinfo.code,
      link_name:linkinfo.name,
      channel_name:linkinfo.channel_name,
      business_type_name:linkinfo.business_type_name,
      lauch_type_name:linkinfo.lauch_type_name,
      marketing_subject_name:linkinfo.marketing_subject_name,
      client_ip:pobj.clientIp
    };
    this.writebrowsingrecords(addObj);
    return system.getResultSuccess(rtnObj);
  }
  //添加链接浏览记录
  async writebrowsingrecords(addObj){
    try {
      // var date = new Date();
      // var localeDateString = date .toLocaleDateString();
      // var haStr = await sha256(JSON.stringify(addObj));
      // shaStr = "browsingrecords_"+localeDateString+"_"+shaStr;
      // var rtn = await this.redisClient.get(shaStr);//从redis读取数据 
      // if(!rtn){
      //   await this.browsingrecordsDao.create(addObj);//添加链接浏览记录
      //   this.redisClient.set(shaStr,JSON.stringify(addObj));//从redis读取数据 
      // }

      //await this.browsingrecordsDao.create(addObj);//添加链接浏览记录
      //往Es中写入日志
      var myDate = new Date();
      addObj["created_at"] = myDate.getFullYear()+"-"+(myDate.getMonth()+1)+"-"+myDate.getDate();
      addObj["created_year"] = myDate.getFullYear();
      addObj["created_month"] =myDate.getMonth()+1;
      addObj["created_day"] =myDate.getDate();
      addObj["created_time"]=myDate.getTime();
      await this.execClient.execPostEs(addObj, this.browsingRecordsLogUrl);
    } catch (e) {
      console.log(e,"writebrowsingrecords++++++++++++++++++++")
    }
  }
  //清除模板链接redis缓存数据
  async delRedisInfoByLinkCode(code){
    try {
      var ab = await this.dao.model.findOne({
        where:{code:code},raw:true
      });
      if(ab){
        var linkObj = {
          is_enabled:1,
          template_id:ab.template_id?ab.template_id.toString():"",
          channel_code:ab.channel_code,
          else_channel_param:ab.else_channel_param,
          business_type_code:ab.business_type_code,
          lauch_type_code:ab.lauch_type_code,
          marketing_subject_code:ab.marketing_subject_code
        };
        // is_enabled:1,
        // template_id:ab.template_id,
        // channel_code:ab.channel_code,
        // else_channel_param:ab.else_channel_param,
        // business_type_code:ab.business_type_code,
        // lauch_type_code:ab.lauch_type_code,
        // marketing_subject_code:ab.marketing_subject_code
        console.log(JSON.stringify(linkObj),"111111111111111111111111111111");
        var shaStr = await sha256(JSON.stringify(linkObj));
        shaStr = "templink_"+ab.template_id+"_"+shaStr;
        await this.redisClient.publish("delTemplateCache",shaStr);
        await this.redisClient.delete(shaStr);
      }
    } catch (e) {
      console.log(e)
    }
  }

  //清除模板链接缓存数据
  async clearTemplateLinkInfoCache(key){
    if(key && this.templateLinkInfoCache[key]){
      delete this.templateLinkInfoCache[key];
    }
  }

}
module.exports = TemplatelinkService;