/**
 * Created by Zhong on 2017/8/22.
 */
import {complementaryGljModel, stdGljModel, gljClassModel} from "./schemas";
import counter from "../../../public/counter/counter";
import async from "async";

class GljDao {
    getGljTypes (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);
        })
    }


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

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

    getGljItem (repositoryId, code, callback){
        gljModel.find({"repositoryId": repositoryId, "code": code},function(err,data){
            if(err) callback(true, "")
            else callback(false, data);
        })
    };
    //获得用户的补充工料机和用户当前所在编办的标准工料机
    getGljItems (stdGljLibId, userId, compilationId, callback){
        let rst = {stdGljs: [], complementaryGljs: []};
        async.parallel([
            function (cb) {
                stdGljModel.find({repositoryId: stdGljLibId}, function (err, stdGljs) {
                    if(err){
                        cb(err);
                    }
                    else{
                        rst.stdGljs = stdGljs;
                        cb(null);
                    }
                });
            },
            function (cb) {
                complementaryGljModel.find({userId: userId, compilationId: compilationId}, function (err, complementaryGljs) {
                    if(err){
                        cb(err);
                    }
                    else{
                        rst.complementaryGljs = complementaryGljs;
                        cb(null);
                    }
                });
            }
        ], function (err) {
            if(err){
                callback(true, null);
            }
            else{
                callback(false, rst);
            }
        })

    };

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

    updateComponent(userId, updateArr, callback){
        let parallelFucs = [];
        for(let i = 0; i < updateArr.length; i++){
            parallelFucs.push((function(obj){
                return function (cb) {
                    if(typeof obj.component === 'undefined'){
                        obj.component = [];
                    }
                    complementaryGljModel.update({userId: userId, ID: obj.ID}, obj, function (err, result) {
                        if(err){
                            cb(err);
                        }
                        else{
                            cb(null, obj);
                        }
                    })
                }
            })(updateArr[i]));
        }
        async.parallel(parallelFucs, function (err, result) {
            if(err){
                callback(err, '更新组成物错误！', null);
            }
            else{
                callback(null, '成功！', result);
            }
        });
    }
    //-oprtor
    mixUpdateGljItems (userId, compilationId, updateItems, addItems, rIds, callback) {
        if (updateItems.length == 0 && rIds.length == 0) {
            GljDao.addGljItems(userId, compilationId, addItems, callback);
        }
        else if(rIds.length > 0 && updateItems.length > 0){
            async.parallel([
                function (cb) {
                    GljDao.removeGljItems(rIds, cb);
                },
                function (cb) {
                    GljDao.updateGljItems(userId, compilationId, updateItems, cb);
                }
            ], function (err) {
                if(err){
                    callback(true, "Fail to update and delete", false)
                }
                else{
                    callback(false, "Save successfully", false);
                }
            })
        }
        else if (rIds.length > 0 && updateItems.length === 0) {
            GljDao.removeGljItems(rIds, callback);
        }
        else if(updateItems.length > 0 || addItems.length > 0){
            GljDao.updateGljItems(userId, compilationId, updateItems, function(err, results){
                if (err) {
                    callback(true, "Fail to update", false);
                } else {
                    if (addItems && addItems.length > 0) {
                        GljDao.addGljItems(userId, compilationId, addItems, callback);
                    } else {
                        callback(false, "Save successfully", results);
                    }
                }
            });
        }
    }

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

    static removeGljItems (rIds, callback) {
        if (rIds && rIds.length > 0) {
            complementaryGljModel.collection.remove({ID: {$in: rIds}}, null, function(err, docs){
                if (err) {
                    callback(true, "Fail to remove", false);
                } else {
                    callback(false, "Remove successfully", docs);
                }
            })
        } else {
            callback(false, "No records were deleted!", null);
        }
    }

    static addGljItems (userId, compilationId, items, callback) {
        if (items && items.length > 0) {
            counter.counterDAO.getIDAfterCount(counter.moduleName.GLJ, items.length, function(err, result){
                var maxId = result.value.sequence_value;
                var arr = [];
                for (var i = 0; i < items.length; i++) {
                    var obj = new complementaryGljModel(items[i]);
                    obj.ID = (maxId - (items.length - 1) + i);
                    obj.userId = userId;
                    obj.compilationId = compilationId;
                    arr.push(obj);
                }
                complementaryGljModel.collection.insert(arr, null, function(err, docs){
                    if (err) {
                        callback(true, "Fail to add", false);
                    } else {
                        callback(false, "Add successfully", docs);
                    }
                });
            });
        } else {
            callback(true, "No source", false);
        }
    }

    static updateGljItems(userId, compilationId, 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.userId = userId;
                        filter.compilationId = compilationId;
                        filter.code = doc.code;
                    }
                    complementaryGljModel.update(filter, doc, cb);
                };
            })(items[i]));
        }
        async.parallel(functions, function(err, results) {
            callback(err, results);
        });
    }
}

export default GljDao;

