/**
 * Created by Tony on 2017/6/1.
 */

const mongoose = require("mongoose");

const async = require("async");
const counter = require("../../../public/counter/counter");

let RptTplModel = mongoose.model('rpt_templates');
let TreeNodeModel = mongoose.model('rpt_tpl_tree');

let rptCustCfgFacade = require("../facade/rpt_cust_cfg_facade");

const JV = require("../rpt_component/jpc_value_define");
const rttFacade = require("../facade/rpt_tpl_tree_node_facade");
const CompilationModel = require("../../users/models/compilation_model");

//统一回调函数
let callback = function(req, res, err, message, data){
    res.json({error: err, message: message, data: data});
};

let mExport = {
    getCustomerCfg(req, res) {
        let params = JSON.parse(req.body.params),
            userId = params.userId,
            me = this;
        ;
        if (req.session.sessionUser && req.session.sessionUser.id) userId = req.session.sessionUser.id;
        let userIds = [];
        userIds.push(userId);
        if (userId !== "-100") {
            userIds.push("-100");
        }
        rptCustCfgFacade.getCustomizeCfg(userIds).then(function (custCfg) {
            if (custCfg) {
                //success
                let rst = null;
                if (custCfg.length > 0) {
                    rst = [];
                    rst.push(null);
                    for (let itemCfg of custCfg) {
                        // rst = itemCfg;
                        let doc = (itemCfg._doc)?itemCfg._doc:itemCfg;
                        let dest = {};
                        copyRptCfg(doc, dest);
                        if (doc.userId !== "-100") {
                            rst.push(dest);
                        } else {
                            rst[0] = dest;
                        }
                    }
                }
                if (rst !== null && rst.length === 1) {
                    //copy dft config
                    let userDest = {};
                    copyRptCfg(rst[0], userDest);
                    rst.push(userDest);
                }
                callback(req,res, false, "", rst);
            } else {
                //failed
                callback(req,res, true, "失败!", null);
            }
        })
    },
    saveCustomerCfg: function (req, res) {
        let params = JSON.parse(req.body.params),
            userId = params.userId,
            custCfg = params.custCfg;
        ;
        if (req.session.sessionUser && req.session.sessionUser.id) userId = req.session.sessionUser.id;
        custCfg.userId = userId;
        rptCustCfgFacade.saveCustomizeCfg(custCfg).then(function (rst) {
            if (rst) {
                //success
                callback(req,res, false, "", "success!");
            } else {
                //failed
                callback(req,res, true, "更新失败！", null);
            }
        })
    },
    getDftTemplates(req, res) {
        let filter = {"userId": "-100", "$or": [{"isDeleted": null}, {"isDeleted": false} ]};
        TreeNodeModel.find(filter, '-_id', function(err, data){
            if (err) {
                callback(req,res, true,"", null);
            } else {
                callback(req,res,false,"", data);
            }
        });
    },
    getCompilationList(req, res) {
        let compilationModel = new CompilationModel();
        let compilationList = compilationModel.getCompilationList();
        if (compilationList) {
            compilationList.then(function (rst) {
                callback(req,res,false,"", rst);
            })
        } else {
            callback(req,res, true,"no result", null);
        }
    },
    getRptTplTree: function(req, res) {
        let params = JSON.parse(req.body.params),
            compilationId = params.compilationId,
            userId = params.userId,
            sessionUserId = null;
        let userIds = ["-100"];
        if (req.session.sessionUser && req.session.sessionUser.id) sessionUserId = req.session.sessionUser.id;
        if (userId !== null) {
            if (typeof userId === "string") {
                if (userIds.indexOf(userId) < 0) userIds.push(userId);
            } else if (userId instanceof Array) {
                for (let uid of userId) {
                    userIds.push(uid);
                }
            }
        } else {
        }
        if (sessionUserId && userIds.indexOf(sessionUserId) < 0) userIds.push(sessionUserId);
        if (!compilationId) {
            compilationId = req.session.sessionCompilation._id;
        }
        rttFacade.findTplTree(compilationId, userIds).then(function(result) {
            if (result) {
                callback(req,res,false,"", result);
            } else {
                callback(req,res, true,"no result", null);
            }
        });
    },
    getTplTreeByCompilation: function (req, res) {
        let params = JSON.parse(req.body.params),
            compilationId = params.compilationId;
        // if (req.session.sessionUser && req.session.sessionUser.id) sessionUserId = req.session.sessionUser.id;
        if (!compilationId) {
            compilationId = req.session.sessionCompilation._id;
        }
        rttFacade.findTplTreeByCompilation(compilationId).then(function(result) {
            if (result) {
                callback(req,res,false,"", result);
            } else {
                callback(req,res, true,"no result", null);
            }
        });
    },
    updateTreeNodes: function(req, res) {
        let params = JSON.parse(req.body.params),
            nodes = params.nodes;
        let functions = [];
        for (let node of nodes) {
            functions.push((function(doc) {
                return function(cb) {
                    TreeNodeModel.update({ID: doc.ID}, doc, cb);
                };
            })(node));
        }
        async.parallel(functions, function(err, results) {
            callback(req,res, err, "", results);
        });
    },
    deleteRptTplNodes: function(req, res){
        let params = JSON.parse(req.body.params),
            nodeIds = params.nodeIds,
            preNodeId = params.preNodeId,
            preNodeNextId = params.preNodeNextId;
        let functions = [];
        if (preNodeId !== -1) {
            functions.push((function(nodeId, nextId) {
                return function(cb) {
                    TreeNodeModel.update({ID: nodeId}, {"NextSiblingID": nextId}, cb);
                };
            })(preNodeId, preNodeNextId));
        }
        for (let nId of nodeIds) {
            functions.push((function(nodeId) {
                return function(cb) {
                    TreeNodeModel.update({ID: nodeId}, {"isDeleted": true}, cb);
                };
            })(nId));
        }
        async.parallel(functions, function(err, results) {
            callback(req,res, err, "", results);
        });
    },
    createTreeRootNode: function(req, res){
        let params = JSON.parse(req.body.params),
            doc = params.doc;
        rttFacade.createNewTree(doc).then(function (rst) {
            if (rst) {
                //success
                callback(req,res, false, "", rst);
            } else {
                //failed
                callback(req,res, true, "创建失败！", null);
            }
        })
    },
    updateTreeRootNode: function(req, res){
        let params = JSON.parse(req.body.params),
            doc = params.doc;
        rttFacade.updateTree(doc.compilationId, doc.engineerId, doc.userId, doc).then(function (rst) {
            if (rst) {
                //success
                callback(req,res, false, "", rst);
            } else {
                //failed
                callback(req,res, true, "更新失败！", null);
            }
        })
    },
    updateTopNodeName: function (req, res) {
        //备注：因设计的更改，此方法将被放弃
        let params = JSON.parse(req.body.params),
            compilationId = params.compilationId, engineerId = params.engineerId,
            userId = params.userId,
            nodeName = params.nodeName
        ;
        if (req.session.sessionUser && req.session.sessionUser.id) userId = req.session.sessionUser.id;
        let filter = {"compilationId": compilationId, "engineerId": engineerId, "userId": userId, "$or": [{"isDeleted": null}, {"isDeleted": false}]};
        let updateStatement = {"$set": {"name": nodeName}};
        rttFacade.updateTreeInDetail(filter, updateStatement).then(function (rst) {
            if (rst) {
                //success
                callback(req,res, false, "", rst);
            } else {
                //failed
                callback(req,res, true, "更新失败！", null);
            }
        });
    },
    updateSubLevelOneNode: function (req, res) {
        let params = JSON.parse(req.body.params),
            compilationId = params.compilationId,
            // engineerId = params.engineerId,
            userId = params.userId,
            subNode = params.subNode
        ;
        if (req.session.sessionUser && req.session.sessionUser.id) userId = req.session.sessionUser.id; //备注：这段逻辑只会在前端有效，后端运维不会走到
        let filter = {"compilationId": compilationId, "userId": userId, "items.ID": subNode.ID, "$or": [{"isDeleted": null}, {"isDeleted": false}]};
        let updateStatement = {$set: {"items.$": subNode}};
        rttFacade.updateTreeInDetail(filter, updateStatement).then(function (rst) {
            if (rst) {
                //success
                callback(req,res, false, "", rst);
            } else {
                //failed
                callback(req,res, true, "更新失败！", null);
            }
        });
    },

    removeTreeRootNode: function (req, res) {
        let params = JSON.parse(req.body.params),
            compilationId = params.compilationId,
            engineerId = params.engineerId,
            userId = params.userId,
            isPhysically = params.isPhysically
            ;
        if (req.session.sessionUser && req.session.sessionUser.id) userId = req.session.sessionUser.id;
        if (isPhysically) {
            rttFacade.removeTreePhycically(compilationId, engineerId, userId).then(function (rst) {
                if (rst) {
                    //success
                    callback(req,res, false, "", rst);
                } else {
                    //failed
                    callback(req,res, true, "删除失败！", null);
                }
            })
        } else {
            rttFacade.removeTree(compilationId, engineerId, userId).then(function (rst) {
                if (rst) {
                    //success
                    callback(req,res, false, "", rst);
                } else {
                    //failed
                    callback(req,res, true, "删除失败！", null);
                }
            })
        }
    },
    getNewNodeID: function(req, res) {
        let params = JSON.parse(req.body.params),
            scope = params.scope;
        counter.counterDAO.getIDAfterCount(counter.moduleName.report, scope, function(err, result){
            callback(req,res, false, "", result.sequence_value);
        });
    },
    createDftRptTpl: function(req, res) {
        let params = JSON.parse(req.body.params),
            treeNodeId = params.treeNodeId,
            rptDftTplId = params.rptDftTplId,
            rptName = params.rptName,
            grpKey = params.grpKey,
            compilationId = params.compilationId,
            engineerId = params.engineerId,
            userId = params.userId,
            subNode = params.subNode
        ;
        if (req.session.sessionUser && req.session.sessionUser.id) userId = req.session.sessionUser.id;
        let filter = {"ID": rptDftTplId};
        RptTplModel.findOne(filter, '-_id').exec().then(function(dftTplRst) {
            if (dftTplRst) {
                let _doc = dftTplRst["_doc"];
                _doc["ID"] = treeNodeId;
                _doc["GROUP_KEY"] = grpKey;
                _doc["ID_KEY"] = "";
                _doc[JV.NODE_MAIN_INFO][JV.NODE_MAIN_INFO_RPT_NAME] = rptName;
                let rptTpl = new RptTplModel(_doc);
                rptTpl.save(function (err, actTplRst) {
                    if (err) {
                        callback(req,res, "报表模板创建错误", "", null);
                    } else {
                        let filter = {"compilationId": compilationId, "engineerId": engineerId, "userId": userId, "items.ID": subNode.ID, "$or": [{"isDeleted": null}, {"isDeleted": false}]};
                        let updateStatement = {$set: {"items.$": subNode}};
                        rttFacade.updateTreeInDetail(filter, updateStatement).then(function (rst) {
                            if (rst) {
                                //success
                                callback(req,res, false, "", actTplRst);
                            } else {
                                //failed
                                callback(req,res, true, "更新失败！", null);
                            }
                        });
                    }
                });
            } else {
                callback(req, res, 'Create report template failed!', null);
            }
        })
    },
    getRefRptTpl: function (req, res) {
        let params = JSON.parse(req.body.params),
            rptTplId = params.rptTplId;
        let filter = {"ID": rptTplId};
        RptTplModel.findOne(filter, '-_id').exec().then(function(rstTpl) {
            if (rstTpl) {
                callback(req,res, false, "", rstTpl);
            } else {
                callback(req, res, 'The report template was not found!', null);
            }
        })
    },
    updateRptTpl: function (req, res) {
        let params = JSON.parse(req.body.params),
            rptTpl = JSON.parse(params.rptTpl);
        let filter = {"ID": parseInt(rptTpl[JV.PROP_ID])},
            options = {"overwrite": true};
        RptTplModel.update(filter, rptTpl, options, function (err, rst) {
            if (err) {
                callback(req, res, true, 'The report template was updated failed!', false);
            } else {
                callback(req, res, false, 'The report template was updated successfully!', true);
            }
        });
    },
    copyRptTpl: function (req, res) {
        let params = JSON.parse(req.body.params),
            orgRptTplId = params.orgRptTplId,
            newID = params.newRptTplId;
        let filter = {"ID": orgRptTplId};
        RptTplModel.findOne(filter, '-_id').exec().then(function(baseTplRst) {
            if (baseTplRst) {
                let _doc = baseTplRst["_doc"];
                _doc["ID"] = newID;
                if (_doc["GROUP_KEY"].indexOf("(Copy)") < 0) {
                    _doc["GROUP_KEY"] = _doc["GROUP_KEY"] + "(Copy)";
                }
                let rptTpl = new RptTplModel(_doc);
                rptTpl.save(function (err, actTplRst) {
                    if (err) {
                        callback(req,res, "报表模板创建错误", "", null);
                    } else {
                        callback(req,res, false, "", newID);
                    }
                });
            } else {
                callback(req, res, 'Create report template failed!', null);
            }
        });
    }
};

function copyRptCfg(src, dest) {
    dest.margins = {Left: src.margins.Left, Right: src.margins.Right, Top: src.margins.Top, Bottom: src.margins.Bottom};
    dest.showVerticalLine = src.showVerticalLine;
    dest.isNarrow = src.isNarrow;
    dest.fillZero = src.fillZero;
    dest.fonts = [];
    for (let font of src.fonts) {
        dest.fonts.push({"ID": font["ID"], "CfgDispName": font["CfgDispName"], "Name": font["Name"], "FontHeight": font["FontHeight"], "FontColor": font["FontColor"],
            "FontBold": font["FontBold"], "FontItalic": font["FontItalic"], "FontUnderline": font["FontUnderline"], "FontStrikeOut": font["FontStrikeOut"], "FontAngle": font["FontAngle"]});
    }
}

module.exports = mExport;