/**
 * Created by zhang on 2018/8/22.
 */

import mongoose from "mongoose";
const uuidV1 = require('uuid/v1');
let moment = require("moment");
let compilationModel = mongoose.model("compilation");
let materialLibModel = mongoose.model("std_material_replace_lib");
let replaceBillModel = mongoose.model("std_replace_bills");
let replaceMaterialModel = mongoose.model("std_replace_material");
let StdBillsLib = mongoose.model('std_bills_lib_list');
let stdBillsModel = mongoose.model('std_bills_lib_bills');
let stdGLJMode = mongoose.model('std_glj_lib_gljList');

const stdGljLibModel = mongoose.model('std_glj_lib_map');

let materialReplaceLib = {
    findByCondition:async function(conditions,options,single=true){
        if(single == true){
            return await materialLibModel.findOne(conditions,options);
        }else {
            return await  materialLibModel.find(conditions,options);
        }
    },
    addLib : async function (data){
        let now = new Date().getTime();
        let dateStr = moment(now).format('YYYY-MM-DD HH:mm:ss');
        //取编办信息
        let compilation = await compilationModel.findOne({_id:data.compilationId});
        //取清单规则信息
        let billLib = await StdBillsLib.findOne({billsLibId:data.billsLibId});
        if(compilation && billLib){
            let newLib = {
                creator: data.userAccount,
                createDate: now,
                recentOpr: [{operator: data.userAccount, operateDate: dateStr}],
                name: data.name,
                compilationId: data.compilationId,
                compilationName: compilation.name,
                billsLibId:billLib.billsLibId,
                billsLibName:billLib.billsLibName,
                deleted: false
            };
            newLib.ID = uuidV1();
            return await materialLibModel.create(newLib);
        }else {
            throw  new Error("编办或清单规则有误！");
        }
    },
    saveLib:async function(param) {
        return await materialLibModel.findOneAndUpdate(param.query,param.data,{new:true});
    },
    deleteLibByID:async function(ID){
        //删除材料数据
        await replaceMaterialModel.deleteMany({libID:ID});
        //删除清单数据
        await replaceBillModel.deleteMany({libID:ID});
        return await materialLibModel.deleteOne({ID:ID});
    },
    findGLJLibByComID:async function(compilationId){//跟据费用定额查找工料机库
        return await stdGljLibModel.findOne({compilationId:compilationId},['ID']);
    },
    findBillsByLibID:async function(libID){
        return await replaceBillModel.find({libID:libID});
    },
    saveBills:async function(data){
        let [addList,updateList,deleteList]  = prepareDatas(data);
        let p = await Promise.all([addBills(addList),updateBills(updateList),deleteBills(deleteList)]);
        return p;
    },
    saveMaterial:async function(data){
        let [addList,updateList,deleteList]  = prepareDatas(data);
        let p = await Promise.all([addMaterial(addList),replaceMaterial(updateList),deleteMaterial(deleteList)]);
        return p;
    },
    getMaterialByBillsID : async function(billsID){
       return  await replaceMaterialModel.find({billsItemID:billsID});
    },
    getStdBillsByLib:async function(libID){
        let bills = await stdBillsModel.find({billsLibId: libID},['ID','code','name','items']);
        return bills;
    }
};
function prepareDatas(data) {//整理数据
    let addList = [],updateList =[],deleteList=[];
    for(let d of data){
        if(d.type == 'add') addList.push(d);
        if(d.type == 'update') updateList.push(d);
        if(d.type == 'delete') deleteList.push(d);
    }
    return [addList,updateList,deleteList]
}
async function addMaterial(datas) {
    let newMaterial = [],missCodes=[];
    for(let d of datas){
        let stdGLJ = await stdGLJMode.findOne({repositoryId:d.gljLibID,code:d.code});
        if(stdGLJ){
            let temM = {
                libID:d.libID,
                billsItemID:d.billsItemID,
                code:d.code,
                name:stdGLJ.name,
                specs:stdGLJ.specs,
                type:stdGLJ.gljType,
                unit:stdGLJ.unit
            };
            temM.ID = uuidV1();
            newMaterial.push(temM);
        }else {
            missCodes.push(d.code);
        }
    }
    if(newMaterial.length>0){
        await replaceMaterialModel.create(newMaterial);
    }
    return {type:'add',list:newMaterial,missCodes:missCodes};
}
async function replaceMaterial(datas) {
    let tasks = [],list=[],missCodes = [];
    for(let d of datas){
        let stdGLJ = await stdGLJMode.findOne({repositoryId:d.gljLibID,code:d.code});
        if(stdGLJ){
            let updateData =  {code:d.code, name:stdGLJ.name, specs:stdGLJ.specs, type:stdGLJ.gljType, unit:stdGLJ.unit};
            let task = {
                updateOne:{filter:{ID:d.ID}, update :updateData}
            };
            tasks.push(task);
            list.push({ID:d.ID,updateData:updateData})
        }else {
            missCodes.push(d.code)
        }
    }
    if(tasks.length > 0) await replaceMaterialModel.bulkWrite(tasks);
    return {type:'update',list:list,missCodes:missCodes};
}
async function deleteMaterial(datas) {
    let IDList = [];
    for(let d of datas){
        if(d.ID) IDList.push(d.ID);
    }
    await replaceMaterialModel.deleteMany({ID:{"$in": IDList}});
    return {type:'delete',list:IDList};
}
async function addBills(datas) {
    let newBills = [],missCodes=[];
    for(let d of datas){
        //先查找清单规则库找到对应的清单
        let stdBill = await stdBillsModel.findOne({billsLibId:d.billsLibId,code:d.code});
        if(stdBill){
            let temBill = {
                libID:d.libID,
                code:d.code,
                name:stdBill.name,
            };
            temBill.ID = uuidV1();
            newBills.push(temBill);
        }else {
            missCodes.push(d.code);
        }
    }
    if(newBills.length>0){
        await replaceBillModel.create(newBills);
    }
    return {type:'add',list:newBills,missCodes:missCodes};
}
async function updateBills(datas) {
    let tasks = [],list=[],missCodes = [];
    for(let d of datas){
        let updateData = null;
        let filter = {libID:d.libID, code:d.oldCode};
        if(d.newCode && d.newCode !=''){//说明是要替换清单
            let stdBill = await stdBillsModel.findOne({billsLibId:d.billsLibId,code:d.newCode});
            if(stdBill){
                 updateData = {code:d.newCode, name:stdBill.name};
            }else {
                missCodes.push(d.newCode);
            }
        }else {
            updateData = d.updateData;
        }
        if(updateData){
            let task = {
                updateOne:{filter:filter, update :updateData}
            };
            tasks.push(task);
            list.push({code:d.oldCode,updateData:updateData})
        }
    }
    if(tasks.length > 0) await replaceBillModel.bulkWrite(tasks);
    return {type:'update',list:list,missCodes:missCodes};
}
async function deleteBills(datas) {
    let IDList = [];
    for(let d of datas){
        if(d.ID) IDList.push(d.ID)
    }
    await replaceMaterialModel.deleteMany({billsItemID:{"$in": IDList}});//删除清单时要把对应的材料也删除了
    await replaceBillModel.deleteMany({ID:{"$in": IDList}});
    return {type:'delete',list:IDList};
}


export default materialReplaceLib