/**
 * Created by Zhong on 2017/8/11.
 */
const mongoose = require('mongoose');
const gljMapModel = mongoose.model('std_glj_lib_map');
const gljModel = mongoose.model('std_glj_lib_gljList');
const gljClassModel = mongoose.model('std_glj_lib_gljClass');
const rationRepository = mongoose.model('std_ration_lib_map');
const engLibModel = mongoose.model('engineering_lib');
const compleGljClassTemp = mongoose.model('complementary_glj_section_templates');
import moment from "moment";
import counter from "../../../public/counter/counter";
import async from "async";
let rationRepositoryDao =  require("../../ration_repository/models/repository_map");

class OprDao {
    static updateOprArr(findSet, oprtor, date, cb){
        let oprDate = moment(date).format('YYYY-MM-DD HH:mm:ss');
        gljMapModel.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});
                        }
                    }
                    gljMapModel.update(findSet, {$set: {recentOpr: recentOprArr}}, function (err) {
                        if(err){
                            cb(err);
                        }
                        else{
                            cb(null);
                        }
                    });
                }
                else{
                    cb(err);
                }
            }
        });
    };
}


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

    getGljLib(libId, callback){
        gljMapModel.find({ID: libId}, function (err, result) {
            if(err){
                callback(err, '没有数据！', null);
            }
            else{
                callback(null, '成功', result);
            }
        })
    }
    async getAllGljLib(callback){
        try{
            let gljLibs = await gljMapModel.find({deleted: false});
            for(let gljLib of gljLibs){
                let tempRationLibs = [];
                for(let rationLib of gljLib.rationLibs){
                    let rLib = await rationRepository.findOne({ID: rationLib.ID, deleted: false});
                    if(rLib !== undefined && rLib !== null){
                        tempRationLibs.push({ID: rationLib.ID, dispName: rLib.dispName});
                    }
                }
                gljLib._doc.rationLibs = tempRationLibs;
            }
            callback(null, '成功', gljLibs);
        }
        catch(err){
            callback(err, '没有定额库数据！', null);
        }
    }
    createGljLib(gljLibObj, callback){
        counter.counterDAO.getIDAfterCount(counter.moduleName.stdGljLib, 1, function (err, result) {
            if(err){
                callback(err, '获取新ID失败！');
            }
            else{
                let newGljLib = GljMapDao.createNewLibModel(gljLibObj);
                newGljLib.ID = result.sequence_value;
                gljMapModel.create(newGljLib, function (err, result) {
                    if(err){
                        callback(err, '创建新工料机库失败！', null);
                    }
                    else{
                        callback(null, '创建成功', result);
                    }
                });
            }
        })
    }
    renameGljLib(oprtor, renameObj, callback){
        gljMapModel.update({ID: renameObj.ID, deleted: false}, {$set: {dispName: renameObj.newName}}, function (err) {
            if(err){
                callback(err, '重命名失败！');
            }
            else{
                GljMapDao.updateOprArr({ID: renameObj.ID, deleted: false}, oprtor, Date.now(), function (err) {
                    if(err){
                        callback(err, '更新最近操作者失败！');
                    }
                    else{
                        engLibModel.update({'glj_lib.id': renameObj.ID}, {$set: {'glj_lib.$.name': renameObj.newName}}, {multi: true}, function (err) {
                            if(err){
                                callback(err, '更新工程专业引用失败！');
                            }
                            else {
                                callback(null, '成功！');
                            }
                        });
                    }
                });
            }
        });
    }
    removeGljLib(oprtor, libId, callback){
        GljMapDao.updateOprArr({ID: libId, deleted: false}, oprtor, Date.now(), function (err) {
            if(err){
                callback(err, '失败!')
            }
            else{
                gljMapModel.find({ID: libId, deleted: false}, function (err, result) {
                    if(err){
                        callback(err, '数据不存在！');
                    }
                    else{
                        if(result[0].rationLibs.length > 0){//已被引用
                            callback(null, '此人材机库已被引用！');
                        }
                        else{
                            async.parallel([
                                function (cb) {
                                    gljMapModel.remove({ID: libId}, function (err) {
                                        if(err){
                                            cb(err);
                                        }
                                        else{
                                            cb(null);
                                        }
                                    });
                                },
                                function (cb) {
                                    gljModel.remove({repositoryId: libId}, function (err) {
                                        if(err){
                                            cb(err);
                                        }
                                        else{
                                            cb(null);
                                        }
                                    });
                                },
                                function (cb) {
                                    gljClassModel.remove({repositoryId: libId}, function (err) {
                                        if(err){
                                            cb(err);
                                        }
                                        else{
                                            cb(null);
                                        }
                                    })
                                }
                            ], function (err) {
                                if(err){
                                    callback(err, '移除工料机库失败！');
                                }
                                else{
                                    callback(null, '删除成功');
                                }
                            });
                            /* gljMapModel.update({ID: libId, deleted: false}, {$set: {deleted: true}}, function (err) {
                             if(err){
                             callback(err, '移除工料机库失败！');
                             }
                             else{
                             callback(null, '删除成功');
                             }
                             });*/
                        }
                    }
                });
            }
        });
    }
    async classTemplateCount (compilationId) {
        return await compleGljClassTemp.find({compilationId}).count();
    }
    async initClassTemplate (gljLibId, compilationId) {
        let classTempCount = await compleGljClassTemp.find({compilationId}).count();
        if (classTempCount > 0) {
            await compleGljClassTemp.remove({compilationId});
        }
        let bulks = [];
        let stdGljClass = await gljClassModel.find({repositoryId: gljLibId});
        for (let data of stdGljClass) {
            delete data._doc._id;
            data._doc.compilationId = compilationId;
            bulks.push({insertOne: {document: data}});
        }
        if (bulks.length > 0) {
            await compleGljClassTemp.bulkWrite(bulks);
        }
    }
}

export {OprDao, GljMapDao};
