/**
 * Created by CSL on 2017-06-20.
 */
//var ModuleNames = require('./main_consts.js');

var FeeRate = {
    createNew: function (project) {

        function FeeRate(proj){
            this.datas = null;
            this.datasBackup = null;
            this.sourceType = ModuleNames.feeRate;
            proj.registerModule(ModuleNames.feeRate, this);
        };
        FeeRate.prototype.loadData = function (datas) {
            this.datas = datas;
        };
        FeeRate.prototype.backupDatas=function () {
          this.datasBackup = _.cloneDeep(this.datas);
        };
        FeeRate.prototype.dataRecovery=function () {
            this.datas = this.datasBackup;
            feeRateObject.activateFeeRate = this.getActivateFeeRate();
            feeRateObject.datas = feeRateObject.activateFeeRate.rates;
        };
        FeeRate.prototype.getActivateFeeRate = function () {
            var feeRate={
                rates:[]
            };
            if(this.datas){
                feeRate = this.datas;
            }
            return feeRate;
        };
        FeeRate.prototype.getActivateFeeRateFileID = function(){
            var feeRate = this.getActivateFeeRate();
            if(feeRate){
                return feeRate.ID;
            }else {
                return 0;
            }
        };
        FeeRate.prototype.getActivateFeeRateID = function(){
            var feeRate = this.getActivateFeeRate();
            if(feeRate){
                return feeRate.feeRateID;
            }else {
                return 0;
            }
        };
        FeeRate.prototype.getFeeRateByID=function (ID) {
            ID=parseInt(ID);
            var rates = this.getActivateFeeRate().rates;
            return _.find(rates,{'ID':ID})
        };
        FeeRate.prototype.getChildrenByID = function (ID) {
          ID = parseInt(ID);
          let rates = this.getActivateFeeRate().rates;
          return _.filter(rates,{'ParentID':ID});
        };
        FeeRate.prototype.getAllSubRates = function () {
            let rates =  this.getActivateFeeRate().rates;
            let subRates = [],nameMap={},temRates=[];
            for(let r of rates){
                if(gljUtil.isDef(r.subFeeRate)){
                    for(let p of r.subFeeRate.recodes){
                        if(nameMap[p.name] == true) continue;
                        nameMap[p.name] = true;
                        subRates.push(p);
                        if(p.subList && p.subList.length > 0){
                            for(let sub of p.subList){
                                sub.isSub = true;
                                sub.ParentID = p.ID;
                                subRates.push(sub);
                            }
                        }
                    }
                }
            }
            return _.sortByAll(subRates,['ID'])//要保证树节点的ID子项是紧跟着父项的，不然的话显示会有问题
        };
        FeeRate.prototype.getSubViewData= function(item) {
            var datas = [];
            if(item.hasOwnProperty('subFeeRate')&&item.subFeeRate!=undefined){
                datas = item.subFeeRate.recodes;
            }
            return datas;
        };
        FeeRate.prototype.getValueMap= function(item) {
            var valueMap = {};
            if(item.hasOwnProperty('subFeeRate')&&item.subFeeRate!=undefined){
                var recodes = item.subFeeRate.valueMaps;
                _.forEach(recodes,function (r) {
                    valueMap[r.ID] = r.value;
                })
                return valueMap;
            }else {
                return null;
            }
        };
        FeeRate.prototype.getOptions=function (options,subRates,parentID,itemID) {
            var data = {};
            var list = _.filter(subRates, {'ParentID':parentID});
            if(list&&list.length>0){
                if(parentID==-1){
                    data.ID = itemID+'_'+0;
                }else {
                    data.ID = itemID+'_'+parentID;
                }
                data.name = list[0].type;
                data.optionList=[];
            }
            var nexParent = null;
            _.forEach(list,function (c) {
                var option={};
                option.name = c.name;
                option.value = c.ID;
                option.selected = c.selected;
                data.optionList.push(option);
                if(c.selected&&!c.isLeaf){
                    nexParent = c.ID;
                }
            })
            options.push(data);
            if(nexParent!=null){
                this.getOptions(options,subRates,nexParent,itemID);
            }
        };
        FeeRate.prototype.getUpdateData=function(type,query,doc,callfunction){
            var updateData = [];
            var newobj = {
                'updateType': type,
                'query': query,
            }
            if(doc){
                newobj['doc']=doc;
            }
            if(callfunction){
                newobj['updateFunction']=callfunction;
            }
            updateData.push(newobj);
            return updateData;
        };
        FeeRate.prototype.updateFeeRateByEdit = function(params,feerate){
            var query={
                ID:feerate.feeRateID
            };
            var doc ={
                rateIndex:params.sourceIndex,
                rate:params.dataItem
            }
            doc.rate.rate =doc.rate.rate.toDecimal(getDecimal("feeRate"));
            this.updateFeeRate(query,doc);
            if(this.ifRateChange(params)){
                //this.synchronizeFeeRate();
                this.onFeeRateChange(params.dataItem.ID,params.dataItem.rate);
            }
            $.bootstrapLoading.end();
        };

        FeeRate.prototype.batchUpdateFeeRate = function (items,feerate) {
            var me = this;
            var data={
                query:{
                    ID:feerate.feeRateID
                },
                doc:items,
                user_id:userID
            }
            var errCallBack=function () {
                me.dataRecovery();
                $.bootstrapLoading.end();
            };
            $.bootstrapLoading.start();
            CommonAjax.post('/feeRates/updateRates', data, function (result) {
                _.forEach(items,function (t) {
                    feeRateObject.mainFeeRateSheet.setValue(t.rateIndex, 1, t.rate.rate);
                 });
                 me.onFeeRateFileChange();
                $.bootstrapLoading.end();
            },errCallBack);
        };
        FeeRate.prototype.updateFeeRate=function (query,doc) {
          var updateData = this.getUpdateData('ut_update',query,doc,'update_rates');
            project.pushNow('updateFeeRate',[this.sourceType],updateData);
        };
        FeeRate.prototype.updateStatusBySelected = function (updateTasks) {
            var updateData = [];
            var newobj = {
                'updateType': 'ut_update',
                'tasks': updateTasks,
                'updateFunction':'updateStatusBySelected'
            }
            updateData.push(newobj);
            project.pushNow('updateFeeRate',[this.sourceType],updateData);
        };
        FeeRate.prototype.synchronizeFeeRate = function () {
            var node = project.mainTree.selected;
            if(node){
                if (node.sourceType==='ration' && calcProgramObj.sheet) {
                    calcProgramObj.refreshCalcProgram(node, 3);
                }
            }
        };
        FeeRate.prototype.ifRateChange=function (params) {
            if(params.dataItem.memo==params.oldDataItem.memo){
                return true;
            }else {
                return false;
            }
        };
        FeeRate.prototype.onFeeRateChange=function (rateID,value) {
           this.onFeeRatesChange([{rateID:rateID,value:value}]);
        };

        FeeRate.prototype.onFeeRatesChange =async function (infos) {//{rateID:'AAAA',value:23}
            let node = project.mainTree.selected;
            let me = this;
            let rateMap = {};
            for(let i of infos){
                rateMap[i.rateID] = i.value;
                this.refreshBillsByRateID(i.rateID,i.value);
            }
            this.refreshCalProgramByRateID(rateMap);
            if(node){
                if (node.sourceType==='ration' && calcProgramObj.sheet) {
                    calcProgramObj.refreshCalcProgram(node, 3);
                }
            }
            await project.projectGLJ.calcAllMaterialWhenChange();
            project.calcProgram.calcAllNodesAndSave(calcAllType.catAll,function () {
                $.bootstrapLoading.start();
                project.markUpdateProject({projectID:project.ID(),feeRateID:me.getActivateFeeRateFileID()},"feeRate",function () {
                    $.bootstrapLoading.end();
                    socket.emit('feeRateChangeNotify', {projectID:project.ID(),feeRateID:me.getActivateFeeRateFileID(),userID:userID});
                });
            });

        };


        FeeRate.prototype.onFeeRateFileChange=function () {//整个费率文件换了，原费率文件内容不变
            this.refreshCalProgramWhenFeeFileChange();
            this.refreshBillsWhenFeeFileChange();
            let me = this;
            var node = project.mainTree.selected;
            if(node){
                if (node.sourceType==='ration' && calcProgramObj.sheet) {
                    calcProgramObj.refreshCalcProgram(node, 3);
                }
            }
            project.calcProgram.calcAllNodesAndSave(calcAllType.catAll,function () {
                if(socketObject.roomInfo){
                    //判断费率文件ID是否改变了
                    if(socketObject.roomInfo.feeRate == me.getActivateFeeRateFileID()){//如果没变，则是重选了标准
                        console.log(me.getActivateFeeRateFileID());
;                        project.markUpdateProject({projectID:project.ID(),feeRateID:me.getActivateFeeRateFileID()},"feeRate",function () {
                            socket.emit('feeRateChangeNotify', {projectID:project.ID(),feeRateID:socketObject.roomInfo.feeRate,userID:userID});
                        });
                    }else {
                        let data ={
                            projectID:project.ID(),
                            oldRoom:socketObject.roomInfo.feeRate,
                            newRoom:me.getActivateFeeRateFileID(),
                            userID:userID,
                            name:'feeRate'
                        };
                        socket.emit('changeNewRoom',data);
                        socketObject.roomInfo.feeRate = me.getActivateFeeRateFileID();
                    }
                }
            });


        };

        FeeRate.prototype.refreshBillsWhenFeeFileChange=function(){
            var me = this;
            var nodes = _.filter(projectObj.project.mainTree.items,function (n) {
                if(n.sourceType==ModuleNames.bills&&n.data.feeRateID){
                    if(n.data.hasOwnProperty("feeRateID")&&n.data.feeRateID){
                        var rate = me.getFeeRateByID(n.data.feeRateID);
                        if(rate){
                            n.data.feeRate=number_util.roundToString(rate.rate,getDecimal("feeRate"));
                            return true;
                        }else {
                            n.data.feeRate=null;
                            return true;
                        }
                    }
                }
                return false;
            })
            if(nodes.length>0){
                projectObj.mainController.refreshTreeNode(nodes)
            }
        };
        FeeRate.prototype.refreshCalProgramWhenFeeFileChange=function () {
            var me = this;
            var templates = project.calcProgram.datas.templates;
            for(var i =0;i<templates.length;i++){
                _.forEach(templates[i].calcItems,function (item) {
                    if(item.hasOwnProperty("feeRateID")&&item.feeRateID){
                        var rate = me.getFeeRateByID(item.feeRateID);
                        if(rate){
                            item.feeRate = rate.rate;
                        }
                    }
                })
            }
            project.calcProgram.compileAllTemps();
            calcProgramManage.refreshDetailSheet();
        }
        FeeRate.prototype.refreshCalProgramByRateID=function (rateMap) {
            var templates = project.calcProgram.datas.templates;
            for(var i =0;i<templates.length;i++){
                _.forEach(templates[i].calcItems,function (item) {
                    if(rateMap[item.feeRateID]){
                        item.feeRate = rateMap[item.feeRateID];
                    }
                })
            }
            project.calcProgram.compileAllTemps();
            calcProgramManage.refreshDetailSheet();
        };
        FeeRate.prototype.refreshBillsByRateID=function(rateID,value){
            let nodes = _.filter(projectObj.project.mainTree.items,function (n) {
                if(n.sourceType==ModuleNames.bills&&n.data.feeRateID==rateID){
                    n.data.feeRate=number_util.roundToString(value,getDecimal("feeRate"));
                    return true;
                }else {
                    return false;
                }
            });
            if(nodes.length>0){
                projectObj.mainController.refreshTreeNode(nodes)
            }
        };
        FeeRate.prototype.changeFeeRateStandard=function(newVal,callback){
            var me =this;
            var feeRate = this.getActivateFeeRate();
            var data={
                "newLibID": newVal,
                "feeRateFileID":feeRate.ID,
                "feeRateID":feeRate.feeRateID,
                "user_id":userID,
                "decimal":getDecimal("feeRate")
            };
            CommonAjax.post('/feeRates/changeFeeRateStandard', data, function (data) {
                if (data) {
                    me.datas.libID=data.libID;
                    me.datas.libName=data.libName;
                    me.datas.feeRateID=data.feeRateID;
                    if(newVal==feeRate.libID){//如果是本身，则是恢复标准值，设置回旧的树节点折叠属性
                       let oldRates =  me.datas.rates;
                       for(let i =0;i< oldRates.length;i++){
                            if(data.rates[i] && data.rates[i].ID == oldRates[i].ID) data.rates[i].collapsed = oldRates[i].collapsed;
                       }
                    }
                    me.datas.rates=data.rates;
                    me.onFeeRateFileChange();
                    callback();
                }
            },function () {
                $.bootstrapLoading.end();
            });
        };
        FeeRate.prototype.checkFeeRateName = function(newVal,callback){
            var me =this;
            var feeRate = this.getActivateFeeRate();
            var data = {
                name:newVal,
                rootProjectID:feeRate.rootProjectID
            }
            CommonAjax.post('/feeRates/checkFeeRateName', data, function (data) {
                callback(data);
            });
        };
        FeeRate.prototype.feeRateFileSaveAs = function (newName,callback) {
            var me = this;
            $.bootstrapLoading.start();
            this.backupDatas();
            this.datas.name = newName;
            this.datas.ID = uuid.v1();
            this.datas.feeRateID=uuid.v1();
            this.datas.usageProjects=[];
            this.datas.usageProjects.push({name:projectObj.project.projectInfo.name,ID:projectObj.project.projectInfo.ID});
            var data={
                query:{projectID:projectObj.project.projectInfo.ID},
                doc:this.datas,
                user_id:userID
            }
            CommonAjax.post('/feeRates/feeRateFileSaveAs', data, function (data) {
                callback(me.datas);
            },function () {
                me.dataRecovery();
                $.bootstrapLoading.end();
            });
        };
        FeeRate.prototype.getChangeInfo = function (callback) {
           // var projectID = projectObj.project.projectInfo.ID;
            var feeRate = this.getActivateFeeRate();
            var  rootProjectID= feeRate.rootProjectID;
            if(!rootProjectID){
                rootProjectID=projectObj.project.projectInfo.property.rootProjectID;
            }
            var data={
                "user_id":userID,
                "projectID":projectObj.project.ID(),
                "rootProjectID":rootProjectID
            };
            CommonAjax.post('/feeRates/getChangeInfo', data, function (data) {
                let newDataOther = [];
                if (data.others.length > 0) {
                    let fileHierarchyDatas = getFileHierarchyInfo(data.treeData);
                    for(let fileHierarchyData of fileHierarchyDatas){
                        let projData = _.find(data.others, {ID: fileHierarchyData.ID});
                        if(projData){
                            projData.name = fileHierarchyData.fileHierarchyName;
                            newDataOther.push(projData);
                        }
                    }
                    data.others = newDataOther;
                }
                callback(data);
            });
        };
        FeeRate.prototype.updateFeeRateFromBills=function(value,node){
            var me =this;
            if(node.sourceType === project.Bills.getSourceType()){
                if(value === ''||value ===null ||value === undefined){//费费为空或空字符串时，请空对应的费率值和ID
                    node.updateData.feeRateID = null;
                    node.updateData.feeRate = null;
                    node.changed = true;
                    project.calcProgram.calcAndSave(node);
                }else {
                    var fee_value= number_util.checkNumberValue(value,getDecimal("feeRate"));
                    if(fee_value!=null){
                        var bill = node.data;
                        var rate =me.getFeeRateByID(bill.feeRateID);
                        var data=me.getfbUpdateData(rate,bill,fee_value,value);
                        if(data==null){//只更改清单的值的情况下，由计算程序更新
                            project.calcProgram.calcAndSave(node);
                        }
                        this.setFeeRateToBill(data,function (result) {
                            if(data.hasOwnProperty('feeRate')){
                                rate.rate=fee_value;
                                me.onFeeRateChange(rate.ID,fee_value);
                            }
                        });
                    }else {
                        projectObj.mainController.refreshTreeNode([node]);
                    }
                }
            }
        };

        FeeRate.prototype.updateFeeRateFromCalc=function (value,editInfo) {
            if(value != null){
                value= number_util.checkNumberValue(value,getDecimal("feeRate"));
                if(value == null) {
                    calcProgramManage.refreshDetailSheet();
                    $.bootstrapLoading.end();
                }
            }
/*            if(editInfo.calcItem.feeRateID && value!= null){
                var rate = this.getFeeRateByID(editInfo.calcItem.feeRateID);
                if(rate!=undefined){
                    this.updateFeeRateByCalc(rate,value);
                    return;
                }
            }*/
            if(editInfo.calcItem.feeRateID){
                var rate = this.getFeeRateByID(editInfo.calcItem.feeRateID);
                if(rate!=undefined){
                    if (value == null) value = 0;
                    this.updateFeeRateByCalc(rate,value);
                    return;
                }
            }
            editInfo.calcItem.feeRate=value;
            editInfo.calcItem.feeRateID=null;
            var data={'projectID': projectObj.project.ID(),'templatesID': editInfo.template.ID,'calcItem': editInfo.calcItem};
            calcProgramManage.saveCalcItem(data,function (result) {
                project.calcProgram.compileAllTemps();
                project.calcProgram.calcAllNodesAndSave();
                calcProgramManage.refreshDetailSheet();
                $.bootstrapLoading.end();
            })

        };
        FeeRate.prototype.updateFeeRateByCalc=function (rate,value) {
            var me=this;
            me.updateFeeRateByID(rate.ID,{'rate':value},function () {
                me.onFeeRateChange(rate.ID,value);
            })
        };

        FeeRate.prototype.updateFeeRateByID = function (rateID,doc,callback) {
          let me = this,preKey = 'rates.$.';
          /*let data = {
              query:{
                  'ID':me.getActivateFeeRateID(),
                  'rates.ID':rateID
              },
              doc:{}
          };
          for(let prop in doc){//做了个转换，加上前缀
            data.doc[preKey+prop] = doc[prop];
          }
          CommonAjax.post('/feeRates/updateFeeRate', data, function (data) {
              //更新缓存
              let rate = me.getFeeRateByID(rateID);
              for(let dkey in doc){
                  rate[dkey] = doc[dkey];
              }
            if(callback){
                callback();
            }
          });*/
          me.updateFeeRatesByIDs([{rateID:rateID,doc:doc}],callback);

        };

        FeeRate.prototype.updateFeeRatesByIDs = function(datas,callback){
            let me = this,preKey = 'rates.$.';
            let updateDatas = [];
            for(let d of datas){
                let u = {
                    query:{
                        'ID':me.getActivateFeeRateID(),
                        'rates.ID':d.rateID
                    },
                    doc:{}
                }
                for(let prop in d.doc){//做了个转换，加上前缀
                    u.doc[preKey+prop] = d.doc[prop];
                }
                updateDatas.push(u);
            }
            CommonAjax.post('/feeRates/updateFeeRates', updateDatas, function (result) {
                //更新缓存
                for(let d of datas){
                    let rate = me.getFeeRateByID(d.rateID);
                    for(let dkey in d.doc){
                        rate[dkey] = d.doc[dkey];
                    }
                }
                if(callback){
                    callback();
                }
            });

        };
        FeeRate.prototype.getfbUpdateData=function (rate,bill,value,editText) {
            var data=null;
            if(bill.feeRateID&&editText!=null){
                data = {};
                data.feeRate={
                    query:{
                        'ID':this.getActivateFeeRateID(),
                        'rates.ID':rate.ID
                    },
                    doc:{
                        'rates.$.rate':value
                    }
                }
            }else  if(editText==null){
                bill.feeRateID = null;
                bill.feeRate =null;
            }else { //这里只改变当前清单的费率值，不在这里提交后台，交给计算程序处理。
                bill["feeRate"]=value
              /*  data.bills={
                    query:{
                        ID:bill.ID,
                        projectID:bill.projectID,
                        deleteInfo:null
                    },
                    doc:{
                        feeRate:value
                    }
                }*/
            }
            return data;
        };

        FeeRate.prototype.cleanFeeRateID=function (node) {
            var data ={
                bills:{
                    query:{
                        ID:node.data.ID,
                        projectID:node.data.projectID,
                        deleteInfo:null
                    },
                    doc:{
                        feeRate:null,
                        feeRateID:null
                    }
                }
            }
            this.setFeeRateToBill(data,function (result) {
                node.data.feeRate=null;
                node.data.feeRateID=null;
            });
        };
        FeeRate.prototype.submitFeeRateFromBill=function (rate,bills,callback) {
            var data ={
                    bills:{
                        query:{
                            ID:bills.ID,
                            projectID:bills.projectID,
                            deleteInfo:null
                        },
                        doc:{
                            feeRate:null,
                            feeRateID:rate.ID
                        }
                    }
                };
            this.setFeeRateToBill(data,callback);
        };

       

        FeeRate.prototype.setFeeRateToBill=function(data,callback){
            if(data){
                CommonAjax.post('/feeRates/setFeeRateToBill', data, function (data) {
                    callback(data);
                });
            }
        };
        FeeRate.prototype.loadFeeRateToBill=function (node) {
            if(node.data.feeRateID){
                var feeRate = this.getFeeRateByID(node.data.feeRateID);
                if(feeRate){
                    node.data.feeRate=number_util.roundToString(feeRate.rate,getDecimal("feeRate"));// parseFloat(feeRate.rate).toFixed(feeRate_consts.decimal);
                }
            }
        };
        FeeRate.prototype.changeFeeRateFileFromCurrent = function (newFeeRateFile,callback){
            let me=this;
            let projectID = projectObj.project.projectInfo.ID;
            let data={
                "projectID": projectID,
                "newFeeRateFile":newFeeRateFile
            };
            CommonAjax.post('/feeRates/changeFeeRateFileFromCurrent', data, function (data) {
                if (data) {
                    me.datas=data;
                    callback();
                }
            },function () {
                $.bootstrapLoading.end();
            });
        };

        FeeRate.prototype.changeFeeRateFileFromOthers=function (feeRateFileID,name,callback) {
            let me = this;
            let projectID = projectObj.project.projectInfo.ID;
            let data={
                "projectID": projectID,
                "feeRateFileID":feeRateFileID,
                "name":name,
                "userID":userID,
                "rootProjectID":me.getActivateFeeRate().rootProjectID
            };
            CommonAjax.post('/feeRates/changeFeeRateFileFromOthers', data, function (data) {
                if (data) {
                    me.datas=data;
                    callback();
                }
            },function () {
                $.bootstrapLoading.end();
            });

        };

        var feeRate = new FeeRate(project);
        return feeRate;
    },

};