module.exports = {
  getData: getData,
  updateItem:updateItem,
  updateCoeAdjust:updateCoeAdjust
};

let mongoose = require('mongoose');
let divideModel = mongoose.model("divide_setting");
let consts = require('../models/project_consts');
let calculate_facade = require("../../ration_glj/facade/glj_calculate_facade");
let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade");
let projectConsts = consts.projectConst;
const uuidV1 = require('uuid/v1');


async function updateItem(data){
  let ID = data.ID;
  let tasks= [];
  let udatas = [];
  let proportioRationID = null;
  for(let u of data.updateDatas){
    if(u.type == 'add'){
      tasks.push({updateOne: {filter: {ID: ID}, update: {"$push":{divideList:u.doc} }}});
    }
    if(u.type == "update"){
      let ndoc = {};
      let pre = "divideList.$."
      if(u.model) pre= u.model+".$."; 
      for(let key in u.doc){
        ndoc[pre+key] = u.doc[key]
      }
      if(u.model){//改定额工料机的自定消耗或者子目换算时，要重算消耗量,所以就不走task流程了，另外算
        let query = {"ID": ID};
        query[u.model+".ID"] = u.ID;
        if(u.updateProportion == true){//更新稳定土的时候要先把所有定额工料机更新后，再计算消耗量，所以放在builkWrite后面
          tasks.push({updateOne: {filter: query, update: ndoc}});
          proportioRationID = u.rationID;
        }else{
          await divideModel.update(query,ndoc);
          //重新计算消耗量
          let [ntasks,ndatas] = await calculate_facade.calculateQuantityFromDivide(ID,u.rationID);
          if(ntasks.length > 0) tasks = tasks.concat(ntasks);
          if(ndatas.length > 0) udatas = udatas.concat(ndatas);
        }   
      }else if(u.updateAss == true){//修改辅助定额
        await divideModel.update({"ID": ID,"divideList.ID":u.ID},ndoc);
        let [ntasks,ndatas] = await calculate_facade.calculateQuantityFromDivide(ID,u.ID);
        if(ntasks.length > 0) tasks = tasks.concat(ntasks);
        if(ndatas.length > 0) udatas = udatas.concat(ndatas);
      }else{
        tasks.push({updateOne: {filter: {"ID": ID,"divideList.ID":u.ID}, update: ndoc}});
      }
    }
    if(u.type == "delete"){
      tasks.push({updateOne: {filter: {ID: ID}, update: {"$pull":{divideList:{ID:u.ID}} }}});
      if(u.itemType == "定额"){
        await divideModel.update(
          {ID:ID},
          { $pull: {ration_gljs:{rationID:u.ID},ration_coes:{rationID:u.ID}}},
          { multi: true })
      }
    }
  }

  if(tasks.length > 0) await divideModel.bulkWrite(tasks);
  if(udatas.length > 0) data.updateDatas = data.updateDatas.concat(udatas);

  if(proportioRationID!=null){//说明更新了稳定土
    let [ptasks,pdatas] = await calculate_facade.calculateQuantityFromDivide(ID,proportioRationID);
    if(ptasks.length > 0) await divideModel.bulkWrite(ptasks);
    if(pdatas.length > 0) data.updateDatas = data.updateDatas.concat(pdatas);
  }


  return data;
}

async function updateCoeAdjust(data,compilation){
  let replace = [],projectGLJList=[],ration_gljs=[];
  let result = {updateDatas:[]}
  let ndoc = {};
  let pre = "ration_coes.$."
  for(let key in data.doc){
    ndoc[pre+key] = data.doc[key]
  }
  await divideModel.update({ID:data.divideID,"ration_coes.ID":data.ID},ndoc);
  result.updateDatas.push({ID:data.ID,type:'update',model:'ration_coes',doc:data.doc});
   //添加单个工料机的情况
   if (data.add.length > 0){
     let [tg,pl] = await ration_glj_facade.insertAddTypeGLJ(data.add,compilation,false);
     await divideModel.update({ID:data.divideID},{$push:{ration_gljs:{$each:tg}}});
     ration_gljs = ration_gljs.concat(tg);
     if(pl.length > 0) projectGLJList = projectGLJList.concat(pl);
   }
  //删除的情况 
  if(data.delete.length > 0){
    await divideModel.update({ID:data.divideID},{$pull:{ration_gljs:{$in: data.delete}}});
  } 
  //替换工料机的情况
  if (data.replace.length > 0){
    let rationGLJlist = await getRationGLJs(data.divideID,data.rationID);
    for(let r of data.replace){
        let ration_glj_ID = r.ID;
        if(data.toCommercial == true) ration_glj_ID = r.originalID;
        let r_result = await  ration_glj_facade.replaceGLJByData(r,compilation,false,rationGLJlist);
        let rdoc = {};
        for(let key in r_result.data){
          rdoc[pre+key] = result.data[key]
        }
        //修改定额工料机
        await divideModel.update({ID:data.divideID,"ration_gljs.ID":ration_glj_ID},rdoc);
        result.updateDatas.push({ID:data.ID,type:'update',model:'ration_gljs',doc:r_result.data});
        projectGLJList.push(r_result.projectGLJ);
        
        //新增定额工料机
        if(r_result.newRecodes.length > 0){
          await divideModel.update({ID:data.divideID},{$push:{ration_gljs:{$each:r_result.newRecodes}}});
          ration_gljs = ration_gljs.concat(r_result.newRecodes);
        }
        //删除定额工料机
        if(r_result.deleteList.length > 0){
          await divideModel.update({ID:data.divideID},{$pull:{ration_gljs:{$in: r_result.deleteList}}});
          data.delete = data.delete.concat(r_result.deleteList);
        } 
    }
  }

  let [ptasks,pdatas] = await calculate_facade.calculateQuantityFromDivide(data.divideID,data.rationID);
  if(ptasks.length > 0) await divideModel.bulkWrite(ptasks);
  if(pdatas.length > 0) result.updateDatas = result.updateDatas.concat(pdatas);
  result.ration_gljs= ration_gljs;
  result.projectGLJList = projectGLJList;
  result.delete = data.delete;

  return result;
}


async function getRationGLJs(divideID,rationID){
  let gljList = [];
  let divide_setting = await divideModel.findOne({ID:divideID}).lean();
  for(let rg of divide_setting.ration_gljs){
    if(rg.rationID == rationID) gljList.push(rg);
  }
  return gljList;
}

function getData(projectID, callback) {
  divideModel.findOne({projectID: projectID}, '-_id', async function (err, datas) {
    if (!err) {
        // 旧项目没有人工系数文件，默认给它生成一个。
        if (!datas) {
          datas = {
            ID: uuidV1(),
            projectID:projectID,
            divideList:[],
            ration_gljs:[],
            ration_coes:[]
          }
          await divideModel.create(datas);
          callback(0, projectConsts.DIVIDE_SETTING, datas);
        } else {
            callback(0, projectConsts.DIVIDE_SETTING, datas);
        };
    } else {
        callback(1, projectConsts.DIVIDE_SETTING, null);
    };
  });

}