vatModule.controller('vatCaculateDataController', ['$scope', '$log', '$timeout','$interval', '$q', '$translate', 'loginContext',
    'apiInterceptor', 'Upload', 'dataImportService', 'SweetAlert', 'vatReductionService', 'vatSessionService', 'uiGridConstants',
    'enums', 'modelConfigurationService', 'vatReportService', 'vatCommonService', 'BSPLService', 'vatOperationLogService',
    'vatWorkflowService',
    function ($scope, $log, $timeout, $interval, $q, $translate, loginContext, apiInterceptor, Upload, dataImportService, SweetAlert,
              vatReductionService, vatSessionService, uiGridConstants, enums, modelConfigurationService, vatReportService, vatCommonService
        , BSPLService, vatOperationLogService, vatWorkflowService) {
        'use strict';
        $log.debug('vatCaculateDataController.ctor()...');

        var taskList = [];
        var fixedRef = [];
        $scope.period = vatSessionService.month;
        $scope.moduleid = enums.vatModuleEnum.Import_CalculateData;

        var initTasks = function () {

            var task = function (id, status, name,code) {
                this.id = id;
                this.name = _.isEmpty(name) ? $translate.instant(id) : name;
                this.status = status;
                this.text = $translate.instant(status);
                this.code = code;
            };
            task.prototype.doTask = function () {
                var _this = this;

                switch (_this.id) {
                    case 'GenerateStdTb':
                        //$q.all().then(function () {
                        //    var data = { result: true };
                        //    updateProgress(data, _this);
                        //}, function () {
                        //    taskError(_this);
                        //});
                        // vatReductionService.submitAccountMappingNoLoading(enums.vatReMapType.ReMapVoucher, enums.vatReMapType.ReMapCust).success(function (data) {
                        //     updateProgress(data, _this);
                        // }).error(function () {
                        //     taskError(_this);
                        // });
                        break;
                    case 'GenerateFinanceReport':
                        //$q.all().then(function () {
                        //    var data = { result: true };
                        //    updateProgress(data, _this);
                        //}, function () {
                        //    taskError(_this);
                        //});
                        // BSPLService.GenerateBSPLWithoutLoading(vatSessionService.project.id, vatSessionService.month).success(function () {
                        //     var data = { result: true };
                        //     updateProgress(data, _this);
                        // }).error(function () {
                        //     taskError(_this);
                        // });
                        break;
                    case 'CompareUnbilled':
                        //$q.all().then(function () {
                        //    var data = { result: true };
                        //    updateProgress(data, _this);
                        //}, function () {
                        //    taskError(_this);
                        //});
                        // vatReductionService.CompareOutputInvoice(vatSessionService.month).success(function (data) {
                        //     data.result = true;
                        //     updateProgress(data, _this);
                        // }).error(function () {
                        //     taskError(_this);
                        // });
                        break;
                    case 'CaculateUnbilled':
                        //$q.all().then(function () {
                        //    var data = { result: true };
                        //    updateProgress(data, _this);
                        //}, function () {
                        //    taskError(_this);
                        //});
                        // vatReductionService.CaculateUnbilled(vatSessionService.month, vatSessionService.project).success(function (data) {
                        //     data.result = true;
                        //     updateProgress(data, _this);
                        // }).error(function () {
                        //     taskError(_this);
                        // });
                        break;
                    case 'CaculateBuildinModel':
                        //$q.all().then(function () {
                        //    var data = { result: true };
                        //    updateProgress(data, _this);
                        //}, function () {
                        //    taskError(_this);
                        //});
                        modelConfigurationService.getModelResult(vatSessionService.project.id, enums.serviceType.VAT, vatSessionService.month).success(function (data) {
                            data.result = true;
                            updateProgress(data, _this);
                        }).error(function () {
                            taskError(_this);
                        });
                        break;
                    case 'CollectBuildinModelResult':
                        //$q.all().then(function () {
                        //    var data = { result: true };
                        //    updateProgress(data, _this);
                        //}, function () {
                        //    taskError(_this);
                        //});
                        modelConfigurationService.migrateModelResult(vatSessionService.project.organizationID, vatSessionService.project.year, vatSessionService.project.id, vatSessionService.project.serviceTypeID).success(function (data) {
                            data.result = true;
                            updateProgress(data, _this);
                        }).error(function () {
                            taskError(_this);
                        });
                        break;
                    case 'UpdateReportConfig':
                        //$q.all().then(function () {
                        //    var data = { result: true };

                        //    updateProgress(data, _this);

                        //}, function () {
                        //    taskError(_this);
//                        //});
//                        vatReportService.updateConfig(vatSessionService.project.id, true, vatSessionService.month,
//                                                      vatSessionService.logUser.id ? vatSessionService.logUser.id : "",
//                                                       $scope.isMergeManualDataSource ).success(function (data) {
//                            var data = {result: true};
//                            updateProgress(data, _this);
                            //vatReportService.getTemplateReferences(vatSessionService.month).then(function (refData) {
                            //    if (refData && refData.data) {
                            //        // 初始化resolve列表
                            //        var newRefData = _.chain(refData.data).reject(function (x) {
                            //            return _.isEmpty(x.referenceFromTemplateID) || _.isEmpty(x.referenceToTemplateID);
                            //        }).map(function (x) {
                            //            return {
                            //                referFrom: x.referenceFromTemplateID,
                            //                referTo: x.referenceToTemplateID,
                            //                resolved: x.isResolved
                            //            };
                            //        }).value();
                            //        $scope.resolveRef.push.apply($scope.resolveRef, newRefData);
                            //    }

                            //    return $q.when(data);
                            //}).then(function () {
                            //    updateProgress(data, _this);
                            //});
//                        }).error(function () {
//
//                            taskError(_this);
//                        });
                        break;
                    case 'CalculateKeyValue':
                        //$q.all().then(function () {
                        //    var data = { result: true };
                        //    updateProgress(data, _this);
                        //}, function () {
                        //    taskError(_this);
                        //});
                        vatReportService.calculateKeyValue(vatSessionService.project.id, vatSessionService.month).success(function (data) {
                            updateProgress(data, _this);
                        }).error(function () {
                            taskError(_this);
                        });
                        break;
                    default:
                        //$q.all().then(function () {
                        //    var data = { result: true };
                        //    updateProgress(data, _this);
                        //}, function () {
                        //    taskError(_this);
                        //});
                        //vatReportService.generate(vatSessionService.project.id, _this.id, true, vatSessionService.month, vatSessionService.logUser.ID).success(function (data) {
                        //    updateProgress(data, _this);
                        //}).error(function () {
                        //    taskError(_this);
                        //});
                        if (_.some($scope.resolveRef, function (x) {
                            return x.referFrom === _this.id || x.referTo === _this.id;
                        })) {
                            $q.when().then(function () {
                                $timeout(function () {
                                    var data = {result: true};
                                    updateProgress(data, _this, false);
                                }, 2000);
                            });
                        }
                        else {
                            vatReportService.generateAll(vatSessionService.project.id, true, vatSessionService.month, vatSessionService.logUser.id ? vatSessionService.logUser.id : "").success(function (data) {
                                updateProgress(data, _this);
                            }).error(function () {
                                taskError(_this);
                            });
                        }
                        break;
                }
            };
            task.prototype.name = null;
            task.prototype.id = null;
            task.prototype.status = null;
            task.prototype.text = null;
            task.prototype.code =null;

            vatReportService.getTemplate(vatSessionService.project.id, constant.serviceType.VAT, vatSessionService.month).then(function (report) {

                var result = [];
                // result.push({ name: $translate.instant('ProcessData'), items: [new task('GenerateStdTb', 'unstarted')] });
                // result.push({ name: $translate.instant('ProcessData'), items: [new task('CompareUnbilled', 'unstarted')] });
                // result.push({ name: $translate.instant('ProcessData'), items: [new task('CaculateUnbilled', 'unstarted'), new task('UpdateReportConfig', 'unstarted'), new task('GenerateFinanceReport', 'unstarted')] });

              /*  var dataValidateItems = [/!*"本期余额表累计数+导入调整表是否等于本期利润表累计数", "本期余额表本期数+导入调整表是否等于本期利润表本期数", "上期利润表本年累进+本期利润表本期数是否等于本期利润表本年累计",*!/ ""];
                var dataValidateCode = [/!*'DA001', 'DA002', 'DA003',*!/ ''];*/



                //数据配置
                result.push({ name: $translate.instant('ProcessData'), items: [new task('UpdateReportConfig', 'unstarted')] });
                result[result.length - 1].items.forEach(function (t) { t.seqNo = result.length - 1 });


                //数据校验
                var reItem  = [];
                reItem.push( new task(Math.ceil(Math.random()*1000000).toString(), "unstarted","上期导入调整表是否等于本期调整日记账发生额(摘要中包含“调表不调账”关键字)", "DA004"));
                result.push({ name: $translate.instant('dataValidate'),isReportTask: true, items : reItem});

                fixedRef = [];
                if (report && report.data && report.data.data) {
                    result.push({
                        name: $translate.instant('GenerateReport'),
                        isReportTask: true,
                        items: _.map(report.data.data, function (x) {
                            return new task(x.templateId, 'unstarted', x.templateName, x.templateCode);
                        })
                    });

                    // 从第二张报表开始添加依赖
                    for (var i = 1; i < report.data.data.length - 1; i++) {
                        fixedRef.push({
                            referFrom: report.data.data[i] && report.data.data[i].templateId,
                            referTo: report.data.data[i + 1] && report.data.data[i + 1].templateId,
                            resolved: false
                        });
                    }
                }

                // result.push({ name: $translate.instant('CalculateKeyValue'), items: [new task('CalculateKeyValue', 'unstarted')] });
                // result.push({ name: $translate.instant('BuildinModel'), items: [new task('CaculateBuildinModel', 'unstarted')] });
                // result.push({ name: $translate.instant('ModelCollection'), items: [new task('CollectBuildinModelResult', 'unstarted')] });

                var i = 0;
                result.forEach(function (item) {
                    result[i].items.forEach(function (t) {
                        t.seqNo = i
                    });
                    i++;
                    taskList = taskList.concat(item.items);
                });
                $scope.tasks = result;
                getInitTaskStatus();
            });
        };


        function doStartCaculate(isMergeManualDataSource) {
            $scope.readonly = true;
            $scope.resolveRef.length = 0;
            $scope.resolveRef.push({
                    referFrom: 'UpdateReportConfig',
                    referTo: 'UpdateReportConfig',
                    resolved: false
                }
                // , {
                //     referFrom: 'UpdateReportConfig',
                //     referTo: 'GenerateFinanceReport',
                //     resolved: false
                // }
            );
            fixedRef.forEach(function (r) {
                $scope.resolveRef.push(angular.copy(r));
            });
            taskList.forEach(function (t) {
                t.status = 'unstarted';
                t.text = $translate.instant(t.status);
            })
            $scope.tasks[0].items.forEach(function (t) {
                t.doTask();
                t.status = 'processing';
                t.text = $translate.instant(t.status);
            });
            writeLog($translate.instant('startCaculateData'), null);
            // $scope.tasks[1].items.forEach(function (t) {
            //     t.doTask();
            // });
        }

       function doStartCaculate2(isMergeManualDataSource) {
             vatReportService.generateAll(vatSessionService.project.id, isMergeManualDataSource, vatSessionService.month, vatSessionService.logUser.id ? vatSessionService.logUser.id : "").success(function (data) {
                 $scope.readonly = true;
                 if(data && data.result)
                   updateTasksStatus(data.data);
                   if(data.data.jobStatus=='Begin'||data.data.jobStatus=='Running'){
                     if(!$scope.timer)
                     $scope.timer= $interval(function(){
                       vatReportService.getJobStatus(vatSessionService.project.id,vatSessionService.month,data.data.id).then(function(result){
                          if(result.data && result.status == 200){
                               updateTasksStatus(result.data);
                            }else{
                             if($scope.timer)
                             $interval.cancel($scope.timer);
                            }
                       });

                   },1000);
                  }
               }).error(function (data,status,config,statusText) {
                  if(status==412){
                     SweetAlert.error('报表提审中!');
                  }else if(status == 409){
                     SweetAlert.error('报表已在处理中!');
                  }
               });

       }

       function isAllEnd(stepCode,status){
         var statusList = JSON.parse(status);
         var stepCodes = stepCode.split(",");

       }

        var startCaculate = function () {
            if (vatSessionService.project.projectStatusList[vatSessionService.month] >= constant.ProjectStatusEnum.Generated) {
                swal({
                        title: "warning!",
                        text: $translate.instant('IsConfirmReCalcuate').formatObj({status: vatCommonService.getProjectStautsEnumDesc(vatSessionService.project.projectStatusList[vatSessionService.month])}),
                        type: "warning",
                        showCancelButton: true,
                        confirmButtonColor: "#DD6B55",
                        confirmButtonText: $translate.instant('Yes'),
                        cancelButtonText: $translate.instant('No'),
                        closeOnConfirm: true,
                        closeOnCancel: true
                    },
                    function (isConfirm) {
                        if (isConfirm) {
                            vatReportService.hasManualDataSource(vatSessionService.project.id, vatSessionService.month).then(function (hasManual) {
                                if (hasManual) {
                                    setTimeout(function () {
                                        swal({
                                                title: "warning!",
                                                text: "是否保留手工数据!",
                                                type: "warning",
                                                showCancelButton: true,
                                                confirmButtonColor: "#DD6B55",
                                                confirmButtonText: $translate.instant('Yes'),
                                                cancelButtonText: $translate.instant('No'),
                                                closeOnConfirm: true,
                                                closeOnCancel: true
                                            },
                                            function (tmpConfirm) {
                                                if (tmpConfirm) {
                                                    doStartCaculate(true);
                                                } else {
                                                    doStartCaculate(false);
                                                }
                                            });
                                    }, 500);
                                } else {
                                    doStartCaculate(false);
                                }
                            });
                        } else {
                            swal.close();
                        }
                    });
            } else {
                doStartCaculate(false);
            }
        };

         var startCaculate2 = function () {
                    if (vatSessionService.project.projectStatusList[vatSessionService.month] >= constant.ProjectStatusEnum.Generated) {
                        swal({
                                title: "warning!",
                                text: $translate.instant('IsConfirmReCalcuate').formatObj({status: vatCommonService.getProjectStautsEnumDesc(vatSessionService.project.projectStatusList[vatSessionService.month])}),
                                type: "warning",
                                showCancelButton: true,
                                confirmButtonColor: "#dd6b55",
                                confirmButtonText: $translate.instant('Yes'),
                                cancelButtonText: $translate.instant('No'),
                                closeOnConfirm: true,
                                closeOnCancel: true
                            },
                            function (isConfirm) {
                                if (isConfirm) {
                                    vatReportService.hasManualDataSource(vatSessionService.project.id, vatSessionService.month).then(function (hasManual) {
                                        if (hasManual) {
                                            setTimeout(function () {
                                                swal({
                                                        title: "warning!",
                                                        text: "是否保留手工数据!",
                                                        type: "warning",
                                                        showCancelButton: true,
                                                        confirmButtonColor: "#DD6B55",
                                                        confirmButtonText: $translate.instant('Yes'),
                                                        cancelButtonText: $translate.instant('No'),
                                                        closeOnConfirm: true,
                                                        closeOnCancel: true
                                                    },
                                                    function (isConfirm) {
                                                        if (isConfirm) {
                                                            doStartCaculate2(true);
                                                        } else {
                                                            doStartCaculate2(false);
                                                        }
                                                    });
                                            }, 500);
                                        } else {
                                            doStartCaculate2(false);
                                        }
                                    });
                                }
                                else {
                                    swal.close();
                                }
                         });
                    }
                    else {
                        doStartCaculate2(false);
                    }
         };

        var caculateProgress = function (task) {

            var completedCnt = taskList.filter(function (t) {
                return (t.status === 'completed' || t.status === 'error');
            }).length;
            $scope.progress = PWC.round(completedCnt / taskList.length * 100, 0);
            if (!_.isEmpty($scope.resolveRef)) {
                var resolveTasks = _.where($scope.resolveRef, {referFrom: task.id});
                resolveTasks.forEach(function (x) {
                    x.resolved = true;
                });
            }

            var finish = $scope.tasks[task.seqNo].items.every(function (t) {
                return t.status === 'completed' || t.status === 'error';
            });

            //上一个任务完成
            if (finish && task.seqNo < $scope.tasks.length - 1) {
                var unstarted = $scope.tasks[task.seqNo + 1].items.every(function (t) {
                    return t.status === 'unstarted';
                });
                if (unstarted) {
                    var readyTasks;
                    var isGenedAll = false;
                    var isReport = false;
                    if (!_.isEmpty($scope.resolveRef)) {
                        readyTasks = _.reject($scope.tasks[task.seqNo + 1].items, function (t) {
                            return _.some($scope.resolveRef, function (x) {
                                if($scope.tasks[task.seqNo + 1].isReportTask)isReport=true;
                                return !x.resolved && x.referTo === t.id;
                            });
                        });
                    }
                    else {
                        readyTasks = $scope.tasks[task.seqNo + 1].items;
                        if($scope.tasks[task.seqNo + 1].isReportTask)isReport=true;
                    }

                    readyTasks.forEach(function (t) {
                        if(isReport&&!isGenedAll){
                           t.doTask();
                           isGenedAll=true;
                        }

                        t.status = 'processing';
                        t.text = $translate.instant(t.status);
                    });
                }
            }
            //查找任务中剩余子任务进行处理
            else {
                var unstarted = _.filter($scope.tasks[task.seqNo].items, function (t) {
                    return t.status === 'unstarted';
                });
                if (unstarted.length > 0) {
                    var readyTasks;
                    if (!_.isEmpty($scope.resolveRef)) {
                        readyTasks = _.reject(unstarted, function (t) {
                            return _.some($scope.resolveRef, function (x) {
                                return !x.resolved && x.referTo === t.id;
                            });
                        });
                    } else {
                        readyTasks = unstarted;
                    }
                    readyTasks.forEach(function (t) {
                        t.doTask();
                        t.status = 'processing';
                        t.text = $translate.instant(t.status);
                    });
                }
            }

            $scope.readonly = taskList.some(function (t) {
                return t.status !== 'completed' && t.status !== 'error';
            });

            if (!$scope.readonly) {
                vatCommonService.setProjectStatus(vatSessionService.project.id, vatSessionService.month, constant.ProjectStatusEnum.Generated
                    , constant.DictionaryDictKey.WFDataProcess, enums.FinishStatusEnum.Finished);
            }
        };

        var updateProgress = function (data, task, ifWriteLog) {
            if (data && data.result) {
                if( $scope.tasks[task.seqNo].isReportTask){
                    $scope.tasks[task.seqNo].items.forEach(function (t) {
                         t.status = 'completed';
                         t.text = $translate.instant(t.status);
                    });
                }else{
                 task.status = 'completed';
                 task.text = $translate.instant(task.status);
                }

            }
            else {
                task.status = 'error';
                task.text = $translate.instant(task.status);
                //SweetAlert.error($translate.instant('PleaseContactAdministrator'));
            }
            caculateProgress(task);
            if (ifWriteLog === undefined || ifWriteLog) {
                writeLog(task.name, task.text);
            }
            //sendMessage(task);
        };

        var taskError = function (task) {
            task.status = 'error';
            task.text = $translate.instant(task.status);
            caculateProgress(task);
            writeLog(task.name, task.text);
            sendMessage(task);
            //SweetAlert.error($translate.instant('PleaseContactAdministrator'));
        };

        $scope.showOperateLogPop = function () {
            $scope.isShowLog = true;
        };

        var writeLog = function (taskName, status) {
            var logDto = {};
            logDto.ModuleID = $scope.moduleid;
            logDto.CreatorID = vatSessionService.logUser.ID;
            logDto.OperationObject = $translate.instant('vatCaculateDataDesc');
            logDto.Comment = vatSessionService.project.name + " " + vatSessionService.project.year + "年" + vatSessionService.month + "月";
            logDto.Period = vatSessionService.month;

            logDto.ID = PWC.newGuid();
            logDto.CreateTime = new Date();
            logDto.UpdateTime = new Date();
            logDto.OperationContent = taskName;
            logDto.OperationName = taskName;
            logDto.OperationType = enums.vatLogOperationTypeEnum.CalculateData;
            logDto.UpdateState = status == null ? '' : status;
            vatOperationLogService.addOperationLog(logDto);
        };

        var updateTasksStatus = function(job){
            var items = $scope.tasks;
            var tasks = JSON.parse(job.status)
            if(job.jobStatus == 'End'){
              items.forEach(function(item,index){
                  item.status = 'completed';
                  item.text = $translate.instant('completed');
              });

               $scope.tasks[0].items[0].status = 'completed';
               $scope.tasks[0].items[0].text= $translate.instant('completed');
              if($scope.timer){
                $interval.cancel($scope.timer);
                vatCommonService.setProjectStatus(vatSessionService.project.id, vatSessionService.month, constant.ProjectStatusEnum.Generated
                  , constant.DictionaryDictKey.WFDataProcess, enums.FinishStatusEnum.Finished);
              }
            }else if(job.jobStatus=='Running'|| job.jobStatus=='Error'){


              var updateConfig = tasks[0];
              if(updateConfig.status == 'Error'){
                $scope.tasks[0].items[0].status = 'error';
             }else if(updateConfig.status == 'End'){
                $scope.tasks[0].items[0].status = 'completed';
             }else if(updateConfig.status == 'Begin'){
                $scope.tasks[0].items[0].status = 'processing';
             }
             $scope.tasks[0].items[0].text= $translate.instant($scope.tasks[0].items[0].status);
             /* items.forEach(function(item,index){
                 tasks.forEach(function(task){
                    if(task.code==item.code){
                       if(task.status == 'Error'){
                         item.status = 'error';
                       }else if(task.status == 'End'){
                         item.status = 'completed';
                       }else if(task.status == 'Begin'){
                         item.status = 'processing';
                       }
                       item.text = $translate.instant(item.status);
                    }
                 })
               });*/
                if(job.jobStatus == 'Error'){
                   if($scope.timer)$interval.cancel($scope.timer);
                }
          }

            items.forEach(function(item,index){
                item.items.forEach(function (_task, index) {
                    tasks.forEach(function(task){
                        if(task.code==_task.code){
                            if(task.status == 'Error'){
                                _task.status = 'error';
                            }else if(task.status == 'End'){
                                _task.status = 'completed';
                            }else if(task.status == 'Begin'){
                                _task.status = 'processing';
                            }
                            _task.text = $translate.instant(_task.status);
                        }
                    })
                })
            });
        }

        var getInitTaskStatus = function(){
            vatReportService.getRunningJob(vatSessionService.project.id,vatSessionService.month).then(function (result) {
               if(result.data && result.status == 200){
                   updateTasksStatus(result.data);
                   if(result.data.jobStatus=='Begin'||result.data.jobStatus=='Running'){
                      if(!$scope.timer)
                      $scope.timer= $interval(function(){
                        vatReportService.getJobStatus(vatSessionService.project.id,vatSessionService.month,result.data.id)
                        .then(function(result){
                           if(result.data && result.status == 200){
                                updateTasksStatus(result.data);
                             }else{
                                 if($scope.timer)
                                 $interval.cancel($scope.timer);
                             }
                        });
                    },1000);
                   }
               }else{
                  $log.debug("not running job");
               }
            });
         }


        var sendMessage = function (task) {
            var msgDto = {};
            msgDto.projectId = vatSessionService.project.id;
            msgDto.NodeDictKey = constant.DictionaryDictKey.DataProcess;
            msgDto.TaskDictKey = constant.DictionaryDictKey.WFDataProcess;
            msgDto.ExceptionDateTime = new Date();
            msgDto.ExceptionMessageDetails = [];

            var msgDetailDto = {};
            msgDetailDto.PeriodId = vatSessionService.month;
            msgDetailDto.ExceptionIssueTitle = constant.WorkflowMessage.Issue;
            msgDetailDto.ExceptionIssueValue = constant.WorkflowMessage.ExceptionIssueValue;
            msgDetailDto.ProcessDataDtTitle = constant.WorkflowMessage.CalDateTime;
            msgDetailDto.ProcessDataDtValue = new Date();
            msgDetailDto.ExceptionDetailTitle = constant.WorkflowMessage.MessageDetail;
            msgDetailDto.ExceptionDetailValue = task.name + task.text;

            msgDto.ExceptionMessageDetails.push(msgDetailDto);
            vatWorkflowService.addExceptionMessage(msgDto);
        };

        (function initialize() {
            $scope.readonly = false;
            $scope.progress = 0;
            $scope.resolveRef = [];
            initTasks();
            $scope.startCaculate = startCaculate;
            $scope.startCaculate2 = startCaculate2;
            $scope.$on('$destroy',function(){
                if($scope.timer)$interval.cancel($scope.timer);
            });

        })();
    }
]);