/**
 * Created by zhang on 2018/1/26.
 */
let mongoose = require('mongoose');
let logger = require("../../../logs/log_helper").logger;
let  projectsModel = mongoose.model('projects');
let async_n = require("async");
let _ = require('lodash');
let ration_model = require('../models/ration');
let bill_model = require('../models/bills');
let consts = require('../models/project_consts');
let projectConsts = consts.projectConst;
let ration_glj_model = mongoose.model('ration_glj');
let rationTemplateModel = mongoose.model('ration_template');
let project_glj_model = mongoose.model('glj_list');
let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade");
const uuidV1 = require('uuid/v1');
const gljUtil = require('../../../public/gljUtil');
let stdColSettingModel = mongoose.model('std_main_col_lib');

module.exports = {
    markUpdateProject:markUpdateProject,
    removeProjectMark:removeProjectMark,
    updateNodes:updateNodes,
    calcInstallationFee:calcInstallationFee,
    saveProperty: saveProperty,
    getDefaultColSetting: getDefaultColSetting,
    markProjectsToChange:markProjectsToChange
};

async function calcInstallationFee(data) {
    let result={};
    let billTasks  = generateTasks(data.bills,data.useID);
    let rationTasks = generateTasks(data.ration,data.useID);
    if(billTasks.length>0){
        await bill_model.model.bulkWrite(billTasks);
    }
    console.log(rationTasks);
    if(rationTasks.length>0){
        await ration_model.model.bulkWrite(rationTasks);
    }
    //如果删除定额，需要删除对应的工料机
    if(data.ration.delete.length>0){
        let rationIDS = _.map(data.ration.delete,'ID');
        await ration_glj_model.deleteMany({projectID: data.ration.delete[0].projectID, rationID: {"$in": rationIDS}});//删除定额工料机
    }

    let rationGLJTasks = [];
    let updateList = [];
    if(data.ration.update.length>0){//如果有需要更新的定额工料机
        for(let ur of data.ration.update){
            for(let g of ur.glj){
                let gTasks = {
                    updateOne:{
                        filter:{
                            ID:g.ID,
                            projectID:g.projectID
                        },
                        update :{
                            quantity:g.quantity,
                            rationItemQuantity:g.rationItemQuantity
                        }
                    }
                };
                rationGLJTasks.push(gTasks);
                updateList.push(g);
            }
        }
    }
    if(rationGLJTasks.length>0){
       await ration_glj_model.bulkWrite(rationGLJTasks);
    }

    let newGljList = [];
    if(data.ration.add.length>0){//新增的安装子目要增加对应的工料机
        for(let nr of data.ration.add){
            for(let tkey in nr.glj){
                newGljList.push(await addInstallationGLJ(nr.glj[tkey]));
            }
        }
    }
    if(newGljList.length>0){
        await ration_glj_model.insertMany(newGljList);
    }
    result.update = updateList;
    result.add = newGljList;
    return result;
}

async function addInstallationGLJ(glj) {
    glj.ID = uuidV1();
    let info = await ration_glj_facade.getInfoFromProjectGLJ(glj);
    let newRecode  = ration_glj_facade.createNewRecord(info);
    return newRecode;
}


function generateTasks(data,userID) {
    let tasks=[];
    let deleteInfo={deleted: true, deleteDateTime: new Date(), deleteBy: userID};
    if(data.delete && data.delete.length > 0){
        for(let bd of data.delete){
            //原先是假删除，现在改成真删除
            let task = {
                deleteOne:{
                    filter:{
                        ID:bd.ID,
                        projectID:bd.projectID
                    }
                }
            };
           /* let task={
                updateOne:{
                    filter:{
                        ID:bd.ID,
                        projectID:bd.projectID
                    },
                    update :{
                        deleteInfo:deleteInfo
                    }
                }
            };*/
            tasks.push(task);
        }
    }
    if(data.add && data.add.length > 0){
        for(let n_data of data.add){
            let task = {
                insertOne :{
                    document:n_data
                }
            };
            tasks.push(task);
        }
    }
    return tasks;
}

async function updateNodes(datas){
    let nodeGroups = _.groupBy(datas,'type');
    let rationTasks = [];
    let billTasks = [];
    let rationGLJTasks = [];
    let projectGLJTasks = [];
    let projectTasks = [];
    let rationTemplateTasks = [];
    let asyncTasks = [];
    for(let type in nodeGroups){
        for(let node of nodeGroups[type]){
            if(type == projectConsts.BILLS){
                billTasks.push(getTask(node));
            }else if(type == projectConsts.RATION){
                rationTasks.push(getTask(node));
            }else if(type == projectConsts.RATION_GLJ){
                rationGLJTasks.push(getTask(node));
            }else if(type == projectConsts.PROJECTGLJ){
                projectGLJTasks.push(getTask(node,'id'));
            }else if(type == projectConsts.PROJECT){
                projectTasks.push(getTask(node));
            }else if(type == projectConsts.RATION_TEMPLATE){
                rationTemplateTasks.push(getTask(node))
            }

        }
    }
    rationTasks.length>0?asyncTasks.push(ration_model.model.bulkWrite(rationTasks)):'';
    billTasks.length>0?asyncTasks.push(bill_model.model.bulkWrite(billTasks)):"";
    rationGLJTasks.length>0?asyncTasks.push(ration_glj_model.bulkWrite(rationGLJTasks)):"";
    projectGLJTasks.length>0?asyncTasks.push(project_glj_model.bulkWrite(projectGLJTasks)):"";
    projectTasks.length>0?asyncTasks.push(projectsModel.bulkWrite(projectTasks)):"";
    rationTemplateTasks.length>0?asyncTasks.push(rationTemplateModel.bulkWrite(rationTemplateTasks)):"";
    return  asyncTasks.length>0?await Promise.all(asyncTasks):"";

    function getTask(node,idFiled = 'ID') {

        let task={
            updateOne:{
                filter:{},
                update :_.cloneDeep(node.data)
            }
        };
        task.updateOne.filter[idFiled] = node.data[idFiled];//现在复制项目也重新生成一个新的ID了，所以ID是唯一的
        delete task.updateOne.update[idFiled];//防止误操作
        return task;
    }
}


/*function updateNodes(datas,callback) {
    let tasks = [];
    for(let node of datas){
        tasks.push(updateOne(node))
    }
    async_n.parallel(tasks, function(err, results) {
        if (!err){
            callback(0, '', results);
        }
        else{
            console.log(err);
            callback(1, 'save project failed'+err.message, null);
        }
    });
    function updateOne(node) {
        if(node.type == projectConsts.BILLS){
            return function (asCallback) {
                bill_model.model.findOneAndUpdate({projectID: node.data.projectID, ID: node.data.ID,deleteInfo: null}, node.data,{new: true}, asCallback);
            }
        }else if(node.type ==projectConsts.RATION){
            return function (asCallback) {
                ration_model.model.findOneAndUpdate({projectID: node.data.projectID, ID: node.data.ID,deleteInfo: null}, node.data,{new: true}, asCallback);
            }
        }
    }
}*/

//data = {feeRateID:111111,projectID:1245}; type = feeRate
async function markUpdateProject(data,type) {
    let query = {deleteInfo:null};
    if(type=="feeRate"){//更改了费率
        query['property.feeFile.id'] = data.feeRateID;
    }
    if(type=="unitFile"){//更改了单价文件
        query['property.unitPriceFile.id'] = data.unitFileID;//unitPriceFile
    }
    let projects = await projectsModel.find(query);
    return await markProjectsToChange(projects,type,data.projectID);
}

async function markProjectsToChange(projects,type,extProjectID){
    let tasks=[];
    for(let p of projects){
        if(extProjectID && p.ID===extProjectID) continue;//排除当前项目
        tasks.push(generateMarkTask(type,p.ID));
    }
    return tasks.length>0 ? await projectsModel.bulkWrite(tasks):null;
}

async function removeProjectMark(projectID) {
    return await projectsModel.findOneAndUpdate({ID:projectID},{"$unset":{"changeMark":1}});
}

function generateMarkTask(value,projectID) {
    let task = {
        updateOne:{
            filter:{
                ID:projectID
            },
            update:{
                changeMark:value
            }
        }
    };
    return task
}

// {projectID: 5, propertyName: 'aaa', propertyValue: 1}
function saveProperty(data, callback){
    let obj = {};
    let pn = 'property.' + data.propertyName;
    obj[pn] = data.propertyValue;
    projectsModel.update({"ID": data.projectID}, obj, function (err) {
        if (err) {
            logger.err(pn + ' save error: ' + err);
            callback(err, null)
        } else {
            logger.info(pn + ' saved.');
            callback('', null);
        }}
    );
}

async function getDefaultColSetting(libID){
    return await stdColSettingModel.findOne({ID: libID, deleted: false}, '-_id main_tree_col');
}