/**
 * Created by Tony on 2017/5/4.
 * 工料机的总库，根据不同定额库分类，参考原gljList表
 */
var mongoose = require("mongoose");
var async = require("async");
var repositoryMap = require('./repository_map');
var counter = require('../../../public/counter/counter');
let moment = require('moment');
const compleGljModel = mongoose.model('complementary_glj_lib');
const gljModel = mongoose.model('std_glj_lib_gljList');
const gljClassModel = mongoose.model('std_glj_lib_gljClass');

var gljItemDAO = function(){};

gljItemDAO.prototype.getGljTypes = function(gljLibID, callback){
    gljClassModel.find({"repositoryId": gljLibID, "$or": [{"isDeleted": null}, {"isDeleted": false} ]},function(err,data){
        if(data.length) callback(false,data);
        else  if(err) callback("获取工料机类型错误！",false)
        else callback(false,false);
    })
};

gljItemDAO.prototype.getGljItemsByRep = function(repositoryId,callback){
    gljModel.find({"repositoryId": repositoryId},function(err,data){
        if(err) callback(true, "")
        else callback(false,data);
    })
};

gljItemDAO.prototype.getGljItemByType = function(repositoryId, type, callback){
    gljModel.find({"repositoryId": repositoryId, "gljType": type},function(err,data){
        if(err) callback(true, "")
        else callback(false, data);
    })
};

gljItemDAO.prototype.getGljItem = function(repositoryId, code, callback){
    gljModel.find({"repositoryId": repositoryId, "code": code},function(err,data){
        if(err) callback(true, "")
        else callback(false, data);
    })
};

gljItemDAO.prototype.getGljItems = function(gljIds, callback){
    gljModel.find({"ID": {"$in": gljIds}},function(err,data){
        if(err) callback(true, "")
        else callback(false, data);
    })
};

/*gljItemDAO.prototype.getStdCompleGljItems = async function (rationGljList, callback) {
    try{
        let rst = [];
        let stdIds = [], compleIds = []
        for(let glj of rationGljList){
            if(glj.type !== undefined && glj.type === 'complementary'){
                compleIds.push(glj.gljId);
            }
            else{
                stdIds.push(glj.gljId);
            }
        }
        if(compleIds.length > 0){
            let compleGlj = await compleGljModel.find({ID: {$in: compleIds}, deleteInfo: null}, {ID: 1, gljType: 1, basePrice: 1});
            rst = rst.concat(compleGlj);
        }
        if(stdIds.length > 0){
            let stdGlj = await gljModel.find({ID: {$in: stdIds}, $or: [{deleted: null}, {deleted: false}]}, {ID: 1, gljType: 1, basePrice: 1});
            rst = rst.concat(stdGlj);
        }
        callback(0, rst);
    }
    catch(err){
        callback(err, null);
    }
};*/

gljItemDAO.prototype.getStdCompleGljItems = async function (compleGljIds, stdGljIds, callback) {
    try{
        let rst = [];
        if(compleGljIds.length > 0){
            let compleGlj = await compleGljModel.find({ID: {$in: compleGljIds}}, {ID: 1, gljType: 1, basePrice: 1});
            rst = rst.concat(compleGlj);
        }
        if(stdGljIds.length > 0){
            let stdGlj = await gljModel.find({ID: {$in: stdGljIds}}, {ID: 1, gljType: 1, basePrice: 1, priceProperty: 1});
            rst = rst.concat(stdGlj);
        }
        callback(0, rst);
    }
    catch(err){
        callback(err, null);
    }
};

gljItemDAO.prototype.getGljItemsByCode = function(repositoryId, codes, callback){
    gljModel.find({"repositoryId": repositoryId,"code": {"$in": codes}},function(err,data){
        if(err) callback(true, "")
        else callback(false, data);
    })
};

gljItemDAO.prototype.mixUpdateGljItems = function(repId, lastOpr, updateItems, addItems, rIds, callback) {
    var me = this;
    if (updateItems.length == 0 && rIds.length == 0) {
        me.addGljItems(repId, lastOpr, addItems, callback);
    } else {
        me.removeGljItems(repId, lastOpr, rIds, function(err, message, docs) {
            me.updateGljItems(repId, lastOpr, updateItems, function(err, results){
                if (err) {
                    callback(true, "Fail to update", false);
                } else {
                    if (addItems && addItems.length > 0) {
                        me.addGljItems(repId, lastOpr, addItems, callback);
                    } else {
                        callback(false, "Save successfully", results);
                    }
                }
            });
        });
    }
};

gljItemDAO.prototype.removeGljItems = function(repId, lastOpr, rIds, callback) {
    if (rIds && rIds.length > 0) {
        gljModel.collection.remove({ID: {$in: rIds}}, null, function(err, docs){
            if (err) {
                callback(true, "Fail to remove", false);
            } else {
                repositoryMap.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
                    if(err){
                        callback(true, "Fail to update operator", false);
                    }
                    else{
                        callback(false, "Remove successfully", docs);
                    }
                });
            }
        })
    } else {
        callback(false, "No records were deleted!", null);
    }
};

gljItemDAO.prototype.addGljItems = function(repId, lastOpr, items, callback) {
    if (items && items.length > 0) {
        counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, items.length, function(err, result){
            var maxId = result.sequence_value;
            var arr = [];
            for (var i = 0; i < items.length; i++) {
                var obj = new gljModel(items[i]);
                obj.ID = (maxId - (items.length - 1) + i);
                obj.repositoryId = repId;
                arr.push(obj);
            }
            gljModel.collection.insert(arr, null, function(err, docs){
                if (err) {
                    callback(true, "Fail to add", false);
                } else {
                    repositoryMap.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
                        if(err){
                            callback(true, "Fail to update Operator", false);
                        }
                        else{
                            callback(false, "Add successfully", docs);
                        }
                    });
                }
            })
        });
    } else {
        callback(true, "No source", false);
    }
};

gljItemDAO.prototype.updateGljItems = function(repId, lastOpr, items, callback) {
    var functions = [];
    for (var i=0; i < items.length; i++) {
        functions.push((function(doc) {
            return function(cb) {
                var filter = {};
                if (doc.ID) {
                    filter.ID = doc.ID;
                } else {
                    filter.repositoryId = repId;
                    filter.code = doc.code;
                }
                gljModel.update(filter, doc, cb);
            };
        })(items[i]));
    }
    functions.push((function () {
        return function (cb) {
            repositoryMap.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
                if(err){
                    cb(err);
                }
                else{
                    cb(null);
                }
            })
        }
    })());
    async.parallel(functions, function(err, results) {
        callback(err, results);
    });
};

gljItemDAO.prototype.updateNodes = function(repId, lastOpr, nodes, callback) {
    var functions = [];
    for (var i=0; i < nodes.length; i++) {
        functions.push((function(doc) {
            return function(cb) {
                gljClassModel.update({ID: doc.ID}, doc, cb);
            };
        })(nodes[i]));
    }
    functions.push((function () {
        return function (cb) {
            repositoryMap.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
                if(err){
                    cb(err);
                }
                else{
                    cb(null);
                }
            })
        }
    })());
    async.parallel(functions, function(err, results) {
        callback(err, results);
    });
};
gljItemDAO.prototype.removeNodes =  function(repId, lastOpr, nodeIds, preNodeId, preNodeNextId, callback){
    var functions = [];
    if (preNodeId != -1) {
        functions.push((function(nodeId, nextId) {
            return function(cb) {
                gljClassModel.update({ID: nodeId}, {"NextSiblingID": nextId}, cb);
            };
        })(preNodeId, preNodeNextId));
    }
    for (var i=0; i < nodeIds.length; i++) {
        functions.push((function(nodeId) {
            return function(cb) {
                gljClassModel.update({ID: nodeId}, {"isDeleted": true}, cb);
            };
        })(nodeIds[i]));
    }
    functions.push((function () {
        return function (cb) {
            repositoryMap.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
                if(err){
                    cb(err);
                }
                else{
                    cb(null);
                }
            })
        }
    })());
    async.parallel(functions, function(err, results) {
        callback(err, results);
    });
};

gljItemDAO.prototype.createNewNode = function(repId, lastOpr, lastNodeId, nodeData, callback) {
    return counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, 1, function(err, result){
        nodeData.repositoryId = repId;
        nodeData.ID = result.sequence_value;
        var node = new gljClassModel(nodeData);
        async.parallel([
            function (cb) {
                node.save(function (err, result) {
                    if (err) {
                        cb("章节树ID错误！", false);
                    } else {
                        if (lastNodeId > 0) {
                            gljClassModel.update({ID: lastNodeId}, {"NextSiblingID": nodeData.ID}, function(err, rst){
                                if (err) {
                                    cb("章节树ID错误！", false);
                                } else {
                                    cb(false, result);
                                }
                            });
                        } else cb(false, result);
                    }
                });
            },
            function (cb) {
                repositoryMap.updateOprArr({ID: repId}, lastOpr, moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'), function (err) {
                    if(err){
                        cb(err);
                    }
                    else{
                        cb(null);
                    }
                })
            }
        ], function (err, result) {
            if(err){
                callback(true, "章节树错误！", false);
            }
            else{
                callback(false, '', result[0]);
            }
        })
    });
};

module.exports = new gljItemDAO();

