/**
 * Created by chen on 2017/8/2.
 */

let async_n = require("async");
let mongoose = require('mongoose');
let feeRateModel = mongoose.model('fee_rates');
let feeRateFileModel = mongoose.model('fee_rate_file');
let std_fee_rate_lib_model = mongoose.model('std_fee_rate_libs');
let project_feerate_temp = mongoose.model('project_feerate_temp');
let projectsModel = require("../../pm/models/project_schema");
let consts = require('../../main/models/project_consts');
let _=require("lodash");
let template = require('../controllers/feerate_template');
let logger = require("../../../logs/log_helper").logger;
const uuidV1 = require('uuid/v1');
let EngineeringLibModel = require("../../users/models/engineering_lib_model");

module.exports={
    save:save,
    getData:getData,
    getFeeRateStandardsByProjectID:getFeeRateStandardsByProjectID,
    changeFeeRateStandard:changeFeeRateStandard,
    checkFeeRateName:checkFeeRateName,
    getChangeInfo:getChangeInfo,
    changeFeeRateFileFromCurrent:changeFeeRateFileFromCurrent,
    changeFeeRateFileFromOthers:changeFeeRateFileFromOthers,
    newFeeRateFile:newFeeRateFile,
    getFeeRatesByProject:getFeeRatesByProject
};
let operationMap={
    'ut_create':create_fee_rate,
    'ut_update':update_fee_rate,
    'ut_delete':delete_fee_rate
};

let updateFunctionMap = {
    'normalUpdate':normalUpdate,
    'update_rates':update_rates,
    'updateStatusBySelected':updateStatusBySelected,
    'feeRateFileSaveAs':feeRateFileSaveAs
}

//测试数据 key projectID, value feeRateFileID
let project_feeRateF_map={
    99:'da059df1-7c18-11e7-9e2f-1390b52643b4'
}





function create_fee_rate() {

}

function update_fee_rate(user_id,datas) {
    if(datas.updateFunction){
        return updateFunctionMap[datas.updateFunction](user_id,datas);
    }else {
        return normalUpdate(user_id,datas);
    }
}

function updateStatusBySelected(user_id,datas) {
    return function(callback){
        feeRateModel.bulkWrite(generateUpdateTaks(datas.tasks),function (err,data) {
            console.log(data);
            commonCallback(callback,data,err);
        })

    }
}
function feeRateFileSaveAs(user_id,datas) {
    return function(callback){
        let doc = datas.doc;
        let projectID=datas.query.projectID;
        let feeRate={
            ID:doc.feeRateID,
            rates:doc.rates
        };
        delete doc._id;
        delete doc.rates;
        creatFeeRateFile(doc,feeRate,projectID).then(function (result) {
            commonCallback(callback,result,result.err);
        })

    }
}


async function creatFeeRateFile(feeRateFile,feeRate,projectID) {//预留projectID
    let result={
        err:null
    }
    try {
        let feeFile={
            id:feeRateFile.ID,
            name:feeRateFile.name
        }
        await projectsModel.findOneAndUpdate({ID:projectID},{'property.feeFile':feeFile});
        await feeRateFileModel.create(feeRateFile);
        await  feeRateModel.create(feeRate);
    }catch (err){
        console.log(err);
        result.err=err;
    }
    return result;
}


function normalUpdate(user_id,datas) {
    return function(callback){
        console.log(datas)
        callback(null,'');
    }
}


function  generateUpdateTaks(updateTasks) {
    var tasks=[];
    for(let u of updateTasks){
        let t ={
            updateOne:{
                filter:u.query,
                update: u.doc
            }
        }
        tasks.push(t);
    }
    return tasks;
}

function update_rates(user_id,datas) {
    return function(callback){
        feeRateModel.findOne(datas.query,['rates'],function(err, data){
            let doc = datas.doc;
            if(_.isArray(doc)){
                _.forEach(doc,function (item) {
                    data.rates[item.rateIndex]=item.rate;
                })
            }else {
                data.rates[doc.rateIndex]=doc.rate;
            }
            data.save(function (err) {
                commonCallback(callback,'',err);
            });
        })
    }
}

function delete_fee_rate() {

}

function save (user_id, datas, callback) {
    let operations=[];
    if(_.isArray(datas)){
        for(let i=0;i<datas.length;i++){
            operations.push(operationMap[datas[i].updateType](user_id,datas[i]));
        }
    }else {
        operations.push(operationMap[datas.updateType](user_id,datas));
    }
    async_n.parallel(operations,function (err,results) {
        if(err){
            callback(err,'');
        }else {
            if(results.length==1){
                callback(null,results[0])
            }else {
                callback(null,results)
            }
        }
    })
}

function getData(projectID, callback) {
    getFeeRateData(projectID).then(function (result) {
        if(result.err){
            callback(1, '', null);
        }else {
            //feeRateModel
            callback(0, consts.projectConst.FEERATE, result.datas);
        }
    })
}

async function getFeeRateData(projectID) {
    let result={
        err:null
    }
    try {
        //
        let project =  await projectsModel.findOne({ID:projectID});
        if (project&&project.property&&project.property.feeFile){
            let feeRateData = await feeRateFileModel.findOne({'ID':project.property.feeFile.id,deleteInfo:null});
            if(feeRateData===null){
                result.datas=[];
            }else {
                let feeRate =  await feeRateModel.findOne({ID:feeRateData.feeRateID});
                feeRateData._doc.rates = feeRate?feeRate.rates:[];
                //
                feeRateData._doc.usageProjects=await getUsageProjects(feeRateData.ID);
                result.datas = feeRateData;
            }
        }else {
            result.datas=[];
        }
        logger.info("get fee rate data");

    }catch (err){
        console.log(err);
        result.err=err;
    }
    return result;
}

async function getUsageProjects(feeRateID){
    let projects = await projectsModel.find({'property.feeFile.id':feeRateID,'deleteInfo':null});
    return projects;
}


function commonCallback(callback,result,err) {
    if(err){
        callback(err,'');
    }else {
        callback(null,result);
    }
}

async function getFeeRateStandardsByProjectID(projectID) {
    logger.info("get feeRate standard, projectID:"+projectID)
    let feeRateStandards=[];
    let project =  await projectsModel.findOne({ID:projectID});
    let engineeringLibModel = new EngineeringLibModel();
    let engineeringInfo = project !== null && project.property.engineering_id !== undefined ?
        await engineeringLibModel.getEngineering(project.property.engineering_id) : null;
    if(engineeringInfo!=null){
        let fee_lib = engineeringInfo.fee_lib;
        for(let lib of fee_lib){
            feeRateStandards.push({ID:lib.id,libName:lib.name});
        }
    }
    return feeRateStandards;
}

async function changeFeeRateStandard(jdata){
    let data = JSON.parse(jdata);
    let template = await std_fee_rate_lib_model.findOne({"ID":data.newLibID});
    let newFeeRate = {};
    newFeeRate.ID =uuidV1();
    newFeeRate.rates=template.rates;
    await feeRateModel.create(newFeeRate);
    let doc={
        libID:data.newLibID,
        libName:template.libName,
        feeRateID: newFeeRate.ID
    };
    let deleteInfo = {deleted: true, deleteDateTime: new Date(), deleteBy: data.user_id};
    await feeRateFileModel.findOneAndUpdate({ID:data.feeRateFileID,deleteInfo:null},doc);
    await feeRateModel.findOneAndUpdate({ID:data.feeRateID},{deleteInfo:deleteInfo});
    doc.rates=newFeeRate.rates;
    return doc;
}

async function newFeeRateFile(updateData){
    if(updateData.property !== null){
        let property = updateData.property;
        logger.info("Create new feeRate file for project :"+updateData.ID);
        let feeFile = property.feeFile;
        let rootProjectID = property.rootProjectID;
        let name = updateData.name;
        let newFeeRate = {};
        if(feeFile.id.indexOf("newFeeRate")!=-1){
            let temFee = await feeRateFileModel.findOne({rootProjectID:rootProjectID,name:name,deleteInfo:null});
            if(temFee){
                newFeeRate.id=temFee.ID;
                newFeeRate.name = temFee.name;
                return newFeeRate;
            }
            let temA = feeFile.id.split("-");
            let libID = temA[1];
            let doc={
                rootProjectID:rootProjectID,
                name:name
            };
            if(libID!== ''){
                let template = await std_fee_rate_lib_model.findOne({"ID":libID});
                let newFeeRate = {};
                newFeeRate.ID =uuidV1();
                newFeeRate.rates=template.rates;
                await feeRateModel.create(newFeeRate);
                doc.libID = libID;
                doc.libName = template.libName;
                doc.feeRateID =  newFeeRate.ID;
            }
            doc.ID = uuidV1();
            await feeRateFileModel.create(doc);
            newFeeRate.id = doc.ID;
            newFeeRate.name =doc.name;
            return newFeeRate;
        }else {
            return feeFile
        }

    }
    return null;
}



async function checkFeeRateName(jdata) {
    let data = JSON.parse(jdata);
    let count = await feeRateFileModel.count({rootProjectID:data.rootProjectID,name:data.name,deleteInfo:null});
    if(count>0){
        return true;
    }
    return false;
}

async function getChangeInfo(jdata){
    let data = JSON.parse(jdata);
    //{ rootProjectID: 99, user_id: '76075' }
    let result={};
    let currentProject = await projectsModel.findOne({'ID':data.rootProjectID},['ID','name']); //{projectID:99,name:'建设项目1'};//dummy 数据
    if(currentProject){
        currentProject._doc.currentOptions=await getFeeRatesByProject(data.rootProjectID);
    }
    //根据用户ID 找除了当前项目的其它建设项目;
    let others =await projectsModel.find({'$and': [
            {'$or':[{'userID': data.user_id,'projType':'Project', 'deleteInfo': null}, {'userID': data.user_id,'projType':'Project', 'deleteInfo.deleted': {'$in': [null, false]}}]},
            { 'ID':{'$nin':[data.rootProjectID]}}
        ]},['ID','name']);
    for(let o of others){
        o._doc.optionList = await getFeeRatesByProject(o.ID);
    }
    result.currentProject=currentProject;
    result.others = others;
    return result;
}

async function getFeeRatesByProject(rootProjectID) {
       let feeRates = await feeRateFileModel.find({rootProjectID:rootProjectID,deleteInfo:null},['ID','name']);
       return feeRates;
}

async function changeFeeRateFileFromCurrent(jdata){
    let data = JSON.parse(jdata);
    let newFeeRateFile=data.newFeeRateFile;
    let result = await  projectsModel.findOneAndUpdate({ID:data.projectID},{'property.feeFile':newFeeRateFile});
    let feeRateData = await feeRateFileModel.findOne({'ID':newFeeRateFile.id});
    if(feeRateData!==null){
        let feeRate = await feeRateModel.findOne({ID:feeRateData.feeRateID});
        feeRateData._doc.rates = feeRate.rates;
    }
    //
    feeRateData._doc.usageProjects=await getUsageProjects(feeRateData.ID);
    return feeRateData;
}

async function changeFeeRateFileFromOthers(jdata) {
    let data = JSON.parse(jdata);
    console.log(data);
    let feeRateFile = await feeRateFileModel.findOne({'ID':data.feeRateFileID});
    let feeRate = await feeRateModel.findOne({ID:feeRateFile.feeRateID});
    let newFeeRate={};
    newFeeRate.ID=uuidV1();
    newFeeRate.rates =feeRate.rates;
    let newFeeRateFile = {};
    newFeeRateFile.ID = uuidV1();
    newFeeRateFile.name = data.name;
    newFeeRateFile.libName = feeRateFile.libName;
    newFeeRateFile.libID=feeRateFile.libID;
    newFeeRateFile.rootProjectID = data.rootProjectID;
    newFeeRateFile.feeRateID =newFeeRate.ID;
    await feeRateModel.create(newFeeRate);
    await feeRateFileModel.create(newFeeRateFile);
    let feeFile={
        id:newFeeRateFile.ID,
        name:data.name
    }
    await projectsModel.findOneAndUpdate({ID:data.projectID},{'property.feeFile':feeFile});
    newFeeRateFile.rates=newFeeRate.rates;
    newFeeRateFile.usageProjects=await getUsageProjects(newFeeRateFile.ID);
    return newFeeRateFile;
}