/**
 * Created by CSL on 2017-10-22.
 */

const uuidV1 = require('uuid/v1');
let logger = require("../../../logs/log_helper").logger;
let mongoose = require('mongoose');
let stdCalcProgramsModel = mongoose.model('std_calc_programs');
let projectCalcProgramsModel = mongoose.model('calc_programs');
let EngineeringLibModel = require("../../users/models/engineering_lib_model");
let _=require("lodash");
let consts = require('../models/project_consts');
let projectConsts = consts.projectConst;

module.exports = {
    newProjectCalcProgramFile: newProjectCalcProgramFile,
    getProjectCalcProgramFile: getProjectCalcProgramFile,
    getStdCalcProgramFile: getStdCalcProgramFile,
    getData: getData,
    save: save,
    saveCalcItem: saveCalcItem,
    saveCalcItems: saveCalcItems,
    updateTemplate: updateTemplate,
    updateTemplateFile: updateTemplateFile,
    addTemplate: addTemplate,
    deleteTemplate: deleteTemplate
};

async function newProjectCalcProgramFile(data) {
    logger.info(`Create new CalcProgram file for project : ${data.ID}`);
    let rst = null;
    // let egnrModel = new EngineeringLibModel();
    // let egnr = await egnrModel.getEngineering(data.property.engineering_id);
    // if(!egnr) return rst;
    // let valid_CP_libs = egnr._doc.program_lib;
    // if (valid_CP_libs == undefined  || valid_CP_libs.length == 0) return rst;
    // 绑定多个计算程序标准文件时，默认取第一个作为标准模板。
    // let stdCP = await getStdCalcProgramFile(valid_CP_libs[0].id);
    let stdCP = await getStdCalcProgramFile(data.property.calcProgram.id);
    let doc={
        ID: uuidV1(),
        projectID: data.ID,
        name: data.name,
        libID: stdCP.ID,
        libName: stdCP.libName,
        templates: stdCP.templates
    };
    await projectCalcProgramsModel.create(doc);
    rst = {ID: doc.ID, name: doc.name};
    return rst;
};

async function getProjectCalcProgramFile(ID) {
    let projCP = await projectCalcProgramsModel.findOne({ID:ID});
    return projCP;
};

async function getStdCalcProgramFile(libID) {
    let stdCP = await stdCalcProgramsModel.findOne({ID:libID});
    return stdCP;
};

// 统一的 getData() 方法供project调用
function getData(projectID, callback) {
    projectCalcProgramsModel.findOne({projectID: projectID}, '-_id', function (err, datas) {
        if (!err) {
            // 旧项目没有计算程序文件，默认给它生成一个。
            if (!datas) {
                logger.info(`Create a calcProgram file for old project : ${projectID}`);
                getStdCalcProgramFile(1).then(function (stdCP) {
                    let doc = {
                        ID: uuidV1(),
                        projectID: projectID,
                        name: '[旧项目补计算程序文件]',
                        libID: stdCP.ID,
                        libName: stdCP.libName,
                        templates: stdCP.templates
                    };
                    projectCalcProgramsModel.create(doc);
                    callback(0, projectConsts.CALC_PROGRAM, stdCP);
                });
            } else {
                callback(0, projectConsts.CALC_PROGRAM, datas);
            };
        } else {
            callback(1, projectConsts.CALC_PROGRAM, null);
        };
    });
};

// 统一的 save() 方法供project调用
function save (user_id, datas, callback) {
    let returnData ={
        moduleName:'calc_program',
        data:{}
    };
    projectCalcProgramsModel.update({"projectID": 553}, {"libName":"goo—test"}, callback(null, returnData));
}

// saveCalcItem({projectID: 597, templatesID: 4, calcItem: calcItem})
function saveCalcItem(dataObj, callback) {
    dataObj=JSON.parse(dataObj);
    projectCalcProgramsModel.findOne({projectID: dataObj.projectID}, function (err, data) {
        if(!err){
            for (let i = 0; i < data.templates.length; i++){
                if (data.templates[i].ID == dataObj.templatesID){
                    for (let j=0; j < data.templates[i].calcItems.length; j++){
                        if (data.templates[i].calcItems[j].ID == dataObj.calcItem.ID){
                            data.templates[i].calcItems[j] = dataObj.calcItem;
                            break;
                        };
                    };
                    break;
                };
            };
            data.save(function (err) {
                if (err) {
                    callback(1, '本条计算规则保存失败');
                } else {
                    callback(0, '本条计算规则保存成功');
                }
            });
        }
        else {
            callback(1, '没有找到计算程序文件');
        }
    });
};

// {  projectID: projectID, calcItems: [{templatesID, calcItem}]  }
function saveCalcItems(datas, callback) {
    let datasObj = JSON.parse(datas);
    projectCalcProgramsModel.findOne({projectID: datasObj.projectID}, function (err, data) {
        if(!err){
            for (let cI of datasObj.calcItems){
                for (let i = 0; i < data.templates.length; i++){
                    if (data.templates[i].ID == cI.templatesID){
                        for (let j=0; j < data.templates[i].calcItems.length; j++){
                            if (data.templates[i].calcItems[j].ID == cI.calcItem.ID){
                                data.templates[i].calcItems[j] = cI.calcItem;
                                break;
                            };
                        };
                        break;
                    };
                };
            };
            data.save(function (err) {
                if (err) {
                    callback(1, '本条计算规则保存失败');
                } else {
                    callback(0, '本条计算规则保存成功');
                }
            });
        }
        else {
            callback(1, '没有找到计算程序文件');
        }
    });
};

// {  projectID: 3, ID: 5, name: '建筑工程', custom: true, calcItems: [{},{}] }  其中name、custom、calcItems可选，其它必填。
// 插入一条计算规则、删除一条计算规则，则整套计算规则整个传入更新，仅calcItems指定值。
// 修改文件名称，则只传入name。
function updateTemplate(dataObj, callback) {
    dataObj=JSON.parse(dataObj);
    projectCalcProgramsModel.findOne({projectID: dataObj.projectID}, function (err, data) {
        if(!err){
            for (let i = 0; i < data.templates.length; i++){
                if (data.templates[i].ID == dataObj.ID){
                    if (dataObj.name)
                        data.templates[i].name = dataObj.name;
                    if (dataObj.custom)
                        data.templates[i].custom = dataObj.custom;
                    if (dataObj.calcItems)
                        data.templates[i].calcItems = dataObj.calcItems;
                    break;
                };
            };
            data.save(function (err) {
                if (err) {
                    callback(1, '计算模板保存失败');
                } else {
                    callback(0, '计算模板保存成功');
                }
            });
        }
        else {
            callback(1, '没有找到计算程序文件');
        }
    });
};

// 一次性替换所有模板：用于切换模板文件。（这里实际上只替换了所有模板，基本信息如projectID、name等保留）
// {projectID: 2706, libID: 2}
async function updateTemplateFile(dataObj, callback) {
    dataObj=JSON.parse(dataObj);
    let stdCP = await getStdCalcProgramFile(dataObj.libID);
    projectCalcProgramsModel.findOne({projectID: dataObj.projectID}, function (err, data) {
        if(!err){
            data.templates = stdCP.templates;
            data.save(function (err) {
                if (err) {
                    callback(1, '计算模板文件保存失败', null);
                } else {
                    callback(0, '计算模板文件保存成功', stdCP.templates);
                }
            });
        }
        else {
            callback(1, '没有找到项目的计算模板文件', null);
        }
    });
};

// {  projectID: 1233, ID: 19, name: '建筑工程2', custom: true, calcItems: [{},{}] }
function addTemplate(dataObj, callback) {
    dataObj=JSON.parse(dataObj);
    projectCalcProgramsModel.update({projectID: dataObj.projectID},
        {
            $push:{
                templates:{
                    "ID": dataObj.ID,
                    "name": dataObj.name,
                    "calcItems": dataObj.calcItems,
                    "custom": dataObj.custom
                }
            }
        },
        function (err) {
            if (!err) {
                callback(0, '计算模板创建成功');
            }
            else {
                callback(1, '计算模板创建失败');
            }
        }
    );
};

// {  projectID: 1233, ID: 19}
function deleteTemplate(dataObj, callback) {
    dataObj=JSON.parse(dataObj);
    projectCalcProgramsModel.update({projectID: dataObj.projectID},
        {
            $pull:{
                templates:{
                    "ID": dataObj.ID
                }
            }
        },
        function (err) {
            if (!err) {
                callback(0, '计算模板删除成功');
            }
            else {
                callback(1, '计算模板删除失败');
            }
        }
    );
};

// for test
// let s = '{"projectID":2164,"ID":23,"name":"建筑工程7","custom":true,"calcItems":[]}';
// addTemplate(s, function(data){console.log('add successfull!')});
// let s = '{"projectID":2164,"ID":15}';
// deleteTemplate(s, function(data){console.log('delete successfull!')});
