const system=require("../../../system");
const ServiceBase=require("../../sve.base")
const settings=require("../../../../config/settings")
var md5=require("md5")
class RptTypeService extends ServiceBase{
  constructor(){
     super("rpt",ServiceBase.getDaoName(RptTypeService));
     this.redisClient=system.getObject("util.redisClient");
     this.cacheBatchId={};

     this.countMap={};//按照报表类型编码顺序号计数
     this.posMap={};//位置映射编码--兼容初始公式
     this.codeMap={};//编码映射位置，检查是否是否需要新增编码
     this.cacheModiRptDate={};
  }
  async queryPosMap(){
    if(Object.keys(this.posMap).length==0){
      var codes=await this.db.models.positionmap.findAll({
        attributes:['rpttypecode','nposition','desc','position'],
        order:[["nposition","ASC"]]
      });
      return system.getResult(codes);
    }
    return this.posMap;
  }
  async deleteUrlsCache(){
    await this.redisClient.delete("docurls");
    return {};
  }
  async saveRptHistory(hs){
    var self=this;
    return this.db.transaction(async t=>{
        var hisarray=[];
        var rptid=hs.rptid;
        var batchid=hs.batchid;
        var batch=null;
        if(!this.cacheBatchId[batchid]){
           batch=await this.db.models.uploadbatch.findOne({where:{id:batchid},transaction:t});
           this.cacheBatchId[batchid]=batch;
        }else{
          batch=this.cacheBatchId[batchid];
        }
        var hisdata=hs.hisdata;
        var rptdate=hs.rptdate;
        var rptcode=hs.rptcode;

        //查询编码表构造缓存
        var codeNewCache=[];
        if(Object.keys(this.countMap).length==0){
          var codes=await this.db.models.positionmap.findAll({
            order:[["nposition","ASC"]]
          });
          if(codes){
                codes.forEach((codeitem)=>{
                  this.countMap[codeitem.rpttypecode]=codeitem.nposition;
                  this.posMap[codeitem.rpttypecode+"~"+codeitem.nposition]=codeitem.position;
                  this.codeMap[codeitem.position]=codeitem.rpttypecode+"~"+codeitem.nposition;
            });
          }
        }
    
        hisdata.forEach(async hd=>{
          var  pposition=md5(hd.desc);
          var h={
            companycode:batch.companycode,
            companyname:batch.companyname,
            timetypecode:batch.timetypecode,
            batchdate:batch.batchdate,
            dateym:rptdate,
            rpttypecode:rptcode,
            position:pposition,
            valstr:hd.valstr,
            desc:hd.desc,
            uploadrpt_id:rptid,
            uploadbatch_id:batchid,
            nposition:hd.position,
          };
          hisarray.push(h);

          //判断报表编码是否含有_N,如果有，那么就按照报表id去修改报表中的日期字段
          if(rptcode.indexOf("_N")>=0){
              if(!this.cacheModiRptDate[batchid]){
                this.cacheModiRptDate[batchid]=[];
              }
              //判断是否修改过日期
              if(this.cacheModiRptDate[batchid].indexOf(rptid)<0){
                //按照报表ID修改日期                         ""
                await self.db.models.uploadrpt.update({"rptdate":rptdate},{ where: { id: rptid }, transaction: t })
                this.cacheModiRptDate[batchid].push(rptid);
              }
              
          }

          //检查是否存在于编码表中
          if(!this.codeMap[pposition]){
            var rptcodetmp="";
            if(rptcode.indexOf("_N")>=0){
              rptcodetmp=rptcode.replace("_N","");
            }else{
              rptcodetmp=rptcode;
            }
            
            //检查当前坐标是否存在于字典，解决后期插入新的行问题
            var pos=hd.position;
            if(this.posMap[rptcodetmp]){//如果已经存在
                 //需要设置新的位置坐标，先从计数中取最后编码
                 var lastNum=this.countMap[rptcodetmp];
                 var nis=isNaN(lastNum);
                 if(nis){
                  lastNum="1";
                 }else{
                  lastNum=Number(lastNum)+1;
                 }
                 pos=lastNum+"";
            }
            this.codeMap[pposition]=rptcodetmp+"~"+pos;
            this.posMap[rptcodetmp+"~"+pos]=pposition;
            this.countMap[rptcodetmp]=pos;
            var codetemp={
              rpttypecode:rptcodetmp,
              nposition:pos,
              position:pposition,
              desc:hd.desc
            }
            codeNewCache.push(codetemp);
          }
        });
        await self.db.models.rpthistory.bulkCreate(hisarray,{transaction:t});
        await self.db.models.positionmap.bulkCreate(codeNewCache,{transaction:t});
        //每保存一次历史数据，就是处理完成一个任务中的一个报表
        var  currentval= await self.redisClient.decr("batch"+batchid);
        console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"+currentval);
        if(currentval==0){
              await self.redisClient.rpush("riskmq",JSON.stringify({
                key:new Date().toLocaleString(),
                content:{
                  batchCode:batchid+"",
                  taxTypeCode:batch.taxtypecode,
                  accountTypeCode:batch.accountstandardcode,
                  taxCode:batch.companycode
                }
              
          }));
          console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>sended...........");
          self.redisClient.delete("batch"+batchid);
           //清空批报表缓存
           if(this.cacheModiRptDate[batchid]){
            delete this.cacheModiRptDate[batchid]
           }
          //改变批的状态为解析完毕
          batch.batchstatuscode="calc";
          await batch.save({transaction:t});
        }
        return {};
    });
  }
  async queryStatus(bs){
     return this.db.models.uploadbatch.findAll({where:{
          id:{
            [this.db.Op.in]: bs
          }
      }});
  }
  async queryStatus(u){
    return this.db.models.uploadbatch.findAll({where:{userid:u.userid}});
 }
  async queryReport(batchid){
    var batch=await this.db.models.uploadbatch.findById(batchid);
     var rs=await this.db.models.result.findAll({where:{"BatchNo":batchid},attributes:["indexName","status"],raw:true});
     var tmp={};
     rs.forEach((item=>{
         tmp[item.indexName]=Number(item.status);
     }));
     var rptdata=await this.apiCallWithoutAk("http://fkrptresult-service/gsb/api/report",tmp);
     if(rptdata){
        var rtn={
          batchdate:batch.batchdate,
          rptdate:batch.updated_at,
          companyName:batch.companyname,
          taxCode:batch.companycode,
          results:rptdata,
          };
          return rtn;
     }else{
         return null;
     }
  
  }
  buildRpt(rpt,upinfo,comp,batchtemp){
    var rptupload={
      companyname:upinfo.companyName,
      companycode:upinfo.companyTaxNum,
      rpttypecode:rpt.code,
      timetypecode:upinfo.dateType,
      urlpath:rpt.url,
      rptdate:rpt.date?rpt.date:'toparse',
      company_id:comp.id,
      uploadbatch_id:batchtemp.id,
    }
    return rptupload;
  }
  async saveRpt(upinfo){
    return this.db.transaction(async t=>{
         //构建批量对象
          var company={
              code:upinfo.companyTaxNum,
              name:upinfo.companyName,
          }
          var comp=await this.db.models.company.findOne({where:{code:upinfo.companyTaxNum}});
          if(!comp){
            comp=await this.db.models.company.create(company,{transaction:t});
          }
          var batchobj={
            batchdate:upinfo.date,
            companyname:upinfo.companyName,
            companycode:upinfo.companyTaxNum,
            name:upinfo.companyName+"_"+upinfo.date+"_"+upinfo.accountingType,
            batchstatuscode:"parserpt",
            taxtypecode:upinfo.valueAddedTax,
            timetypecode:upinfo.dateType,
            accountstandardcode:upinfo.accountingType,
            company_id:comp.id,
          //  userkey:null
          }
          //保存批量
          var batchtemp=await this.db.models.uploadbatch.create(batchobj,{transaction:t});
          var rptresult=[];
          Object.keys(upinfo).forEach(k=>{
              {
                if(k.indexOf("Report")>=0){
                  var rpts=upinfo[k];
                  var esrpts=rpts["essential"];
                  var unesrpts=rpts["unessential"];
                  esrpts.forEach(rpt=>{
                      var tmprpt=this.buildRpt(rpt,upinfo,comp,batchtemp);
                      rptresult.push(tmprpt);       
                  });
                  unesrpts.forEach(rpt=>{
                    var tmprpt=this.buildRpt(rpt,upinfo,comp,batchtemp);
                    rptresult.push(tmprpt);       
                   });
                }
             }
          });
          //保存报表
        await this.db.models.uploadrpt.bulkCreate(rptresult,{transaction:t});
        var lstspts=await this.db.models.uploadrpt.findAll({where:{uploadbatch_id:batchtemp.id},transaction:t});
        //保存当前批的报表数量到缓存，每保存一次历史，计数减1，当计数变为0时，改变批状态，给康发送消息，
        await this.redisClient.set("batch"+batchtemp.id,lstspts.length);
        try{
          lstspts.forEach(async (rpt)=>{
            console.log(rpt.rpttypecode);
            await this.redisClient.notifyConsume("k8stask","docurls",rpt.id+"~"+batchtemp.id+"~"+rpt.rptdate+"~"+rpt.rpttypecode+"~"+rpt.urlpath);
          });
        }catch(e){
          //需要记录要清理的批号历史数据
        }
        return batchtemp;
    });
  }
}
module.exports=RptTypeService;

