/**
 * Created by Tony on 2017/4/24.
 * 重新构造，不适宜生成多个定额库db，还是得统一在一个表
 */
let async = require("async");
let moment = require('moment');
const mongoose = require('mongoose');
let counter = require('../../../public/counter/counter');
const gljMapModel = mongoose.model('std_glj_lib_map');
const rationRepository = mongoose.model('std_ration_lib_map');
const rationChapterTreeModel = mongoose.model('std_ration_lib_ration_chapter_trees');
const rationItemModel = mongoose.model('std_ration_lib_ration_items');
const rationCoeModel = mongoose.model('std_ration_lib_coe_list');
const rationInstallFeeItem = mongoose.model('std_ration_lib_installation');
const rationInstallSection = mongoose.model('std_ration_lib_installationSection');
const engLibModel = mongoose.model('engineering_lib');

function createNewLibModel(rationLibObj){
    var rst = {};
    rst.dispName = rationLibObj.dispName;
    rst.appType = rationLibObj.appType?rationLibObj.appType:'construct';
    rst.compilationId = rationLibObj.compilationId;
    rst.compilationName = rationLibObj.compilationName;
    rst.gljLib = rationLibObj.gljLib;
    rst.creator = rationLibObj.creator;
    rst.createDate = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss');
    rst.recentOpr = [{operator: rationLibObj.creator, operateDate: rst.createDate}],
    rst.deleted = false;
    return rst;
}

var rationRepositoryDao = function(){};

rationRepositoryDao.prototype.getRationLibsByCompilation = async function (compilationId) {
    return await rationRepository.find({compilationId: compilationId, deleted: false});
};

rationRepositoryDao.prototype.updateGljLib = function (gljLibId, callback) {
    rationRepository.update({gljLib: gljLibId}, {$set: {gljLib: -1}}, {multi: true}, function (err) {
        if(err){
            callback(err);
        }
        else{
            callback(null);
        }
    })
};

rationRepositoryDao.prototype.updateOprArr= function(findSet, oprtor, oprDate, cb){
    rationRepository.find(findSet, function (err, result) {
        if(err){
            cb(err);
        }
        else{
            if(result.length === 1){
                let recentOprArr = result[0].recentOpr;
                let isExist = false;
                for(let i =0 ; i<recentOprArr.length; i++){
                    if(recentOprArr[i].operator === oprtor){
                        recentOprArr[i].operateDate = oprDate;
                        isExist = true;
                    }
                }
                if(!isExist){
                    if(recentOprArr.length < 5){
                        recentOprArr.push({operator: oprtor, operateDate: oprDate});
                    }
                    else if(recentOprArr.length === 5){
                        recentOprArr.sort(function (a, b) {
                            if(a.operateDate > b.operateDate){
                                return -1;
                            }else {
                                return 1;
                            }
                            return 0;
                        });
                        recentOprArr.splice(recentOprArr.length -1, 1);
                        recentOprArr.splice(0, 1, {operator: oprtor, operateDate: oprDate});
                    }
                }
                rationRepository.update(findSet, {$set: {recentOpr: recentOprArr}}, function (err) {
                    if(err){
                        cb(err);
                    }
                    else{
                        cb(null);
                    }
                });
            }
            else{
                cb(err);
            }
        }
    })
};

rationRepositoryDao.prototype.getRealLibName = function(dispName,callback){
    if (callback) {
        rationRepository.find({"dispName": dispName}, function(err,data){
            if (err) {
                callback('Error', null);
            } else {
                callback(false, data);
            }
        });
    } else {
        var rst = rationRepository.find({"dispName": dispName}).exec();
        return rst;
    }
};

rationRepositoryDao.prototype.getLibIDByName = function(dispName, callback){
    rationRepository.findOne({"dispName": dispName}, function(err,data){
        if (err) {
            callback('Error', null);
        } else {
            callback(false, data.ID);
        }
    });
};

rationRepositoryDao.prototype.getRepositoryById = function(repId,callback = null){
    if (callback) {
        rationRepository.find({"ID": repId}, function(err,data){
            if (err) {
                callback('Error', null);
            } else {
                callback(false, data);
            }
        });
    } else {
        var rst = rationRepository.find({"ID": repId}).exec();
        return rst;
    }
};

rationRepositoryDao.prototype.addRationRepository = function( rationLibObj,callback){
    counter.counterDAO.getIDAfterCount(counter.moduleName.rationMap, 1, function(err, result){
        var rMap = createNewLibModel(rationLibObj);
        rMap.ID = result.sequence_value;
        new rationRepository(rMap).save(function(err, result) {
            if (err) callback("Error", null);
            else{
                //向引用工料机库的添加标记
                gljMapModel.update({ID: rMap.gljLib, deleted: false}, {$addToSet: {rationLibs: {ID: rMap.ID, dispName: rMap.dispName}}}, function (err, data) {
                    if(err){
                        rationRepository.remove({ID: rMap.ID}, function (err) {
                            if(err){
                                callback("创建失败且回滚失败！", null);
                            }
                            else{
                                callback("创建失败，已回滚！", null);
                            }
                        });
                    }
                    else{
                        callback(false, result);
                    }
                });
            }
        });
    });
};

rationRepositoryDao.prototype.getRationLib = function(libId, callback) {
    rationRepository.find({ID: libId, "deleted": false}, function(err, data){
        if (err) {
            callback( 'Error', null);
        } else {
            callback(0, data);
        }
    });
};

rationRepositoryDao.prototype.getDisplayRationLibs = function(callback) {
    rationRepository.find({"deleted": false}, function(err, data){
        if (err) {
            callback( 'Error', null);
        } else {
            callback( false, data);
        }
    });
};

rationRepositoryDao.prototype.updateName = function(oprtor, renameObj, callback){
    rationRepository.update({ID: renameObj.ID, deleted: false}, {$set: {dispName: renameObj.newName}}, function (err) {
        if(err){
            callback(err, '重命名失败！');
        } else{
            new rationRepositoryDao().updateOprArr({ID: renameObj.ID, deleted: false}, oprtor, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
                if(err){
                    callback(err, '更新最近操作者失败！');
                }
                else{
                    engLibModel.update({'ration_lib.id': renameObj.ID}, {$set: {'ration_lib.$.name': renameObj.newName}}, {multi: true}, function (err) {
                        if(err){
                            callback(err, '更新工程专业引用失败！');
                        }
                        else {
                            callback(null, '成功！');
                        }
                    });
                }
            });
        }
    });
}

rationRepositoryDao.prototype.deleteRationLib = function(oprtor, libId, callback){
    new rationRepositoryDao().updateOprArr({ID: libId, deleted: false}, oprtor, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
        if(err){
            callback(err, '失败!')
        }
        else{
            rationRepository.find({ID: libId, deleted: false}, function (err, result) {
               if(err){
                   callback(err, "没有数据！");
               }
                else{
                   rationRepository.remove({ID: libId}, function (err) {
                       if(err){
                           callback(err, '移除定额库失败！');
                       }
                       else{
                           async.parallel([
                               function (cb) {
                                   //移除工料机库内被引用标记
                                   gljMapModel.update({ID: result[0].gljLib, deleted: false}, {$pull: {rationLibs: {ID: libId}}}, function (err) {
                                       if(err){
                                           cb(err);
                                       }
                                       else{
                                           cb(null);
                                       }
                                   });
                               },
                               //删除库下定额
                               function (cb) {
                                   rationItemModel.remove({rationRepId: libId}, function (err) {
                                       if(err)cb(err);
                                       else cb(null);
                                   });
                               },
                               //删除库下章节树
                               function (cb) {
                                   rationChapterTreeModel.remove({rationRepId: libId}, function (err) {
                                       if(err)cb(err);
                                       else cb(null);
                                   })
                               },
                               //删除子目换算
                               function (cb) {
                                   rationCoeModel.remove({libID: libId}, function (err) {
                                       if(err)cb(err);
                                       else cb(null);
                                   });
                               },
                               //删除安装
                               async function (cb) {
                                    try{
                                        let feeItems = await rationInstallFeeItem.find({rationRepId: libId});
                                        let sectionIDs = [];
                                        for(let item of feeItems){
                                            for(let section of item.section){
                                                sectionIDs.push(section.ID);
                                            }
                                        }
                                        await rationInstallFeeItem.remove({rationRepId: libId});
                                        await rationInstallSection.remove({ID: {$in: sectionIDs}});
                                        cb(null);
                                    }
                                    catch (err){
                                        cb(err);
                                    }
                               }
                           ], function (err) {
                               if(err) callback(err, 'fail');
                               else callback(null, 'sc')
                           });
                       }
                   });
               }
            });
        }
    });
}

module.exports = new rationRepositoryDao();
