var angular = require('angular');
require('../modules');
require('./SelectorModal');
require('../../../commons/services/sinoClickService');
require('../../linker/services/LinkerService');

var module = angular.module('flow.services');

/**
 *
 * @ngdoc service
 * @name  flow.services.WorkflowService
 * @requires $http, $q, $ionicPopup, SelectorModal
 *
 * @description 流程流转服务类
 */
module.factory('WorkflowTransfer', function ($http, $q, $ionicPopup, SelectorModal, 
$ionicLoading, Timer, sinoClickService, LinkerService) {
  var timerId,
    hideLoadingTaskId;

  function wrapperFnWithLoading(scope, fn) {
    return function () {
      showLoadingView();
      return fn.apply(scope, _.toArray(arguments))['finally'](hideLoadingView);
    };
  }

  function showLoadingView() {
    if (timerId) {
      Timer.clear(timerId);
      Timer.clear(hideLoadingTaskId);
    }
    timerId = Timer.delay(function () {
      $ionicLoading.show();
    }, 25);
    hideLoadingTaskId = Timer.delay(hideLoadingView, 5000);
  }

  function hideLoadingView() {
    Timer.clear(timerId);
    Timer.clear(hideLoadingTaskId);
    timerId = null;
    hideLoadingTaskId = null;
    $ionicLoading.hide();
  }

  function showSendResponseMessage(workflowResponse, callBackFunction) {
    var message = workflowResponse.success ? workflowResponse.info :
      workflowResponse.title + '<br/>' + workflowResponse.info;
    $ionicPopup.show({
      template: message,
      title: '提示',
      buttons: [{
        text: '<span>确定</span>',
        type: 'button-positive'
      }]
    }).then(function () {
      if (callBackFunction) {
        callBackFunction();
      }
    });
  }

  function showSendNoRoleMessage(workflowResponse, callBackFunction) {
    var message = '当前岗位不具有任何启动角色，请在设置中重新选择岗位！';
    $ionicPopup.show({
      template: message,
      title: '提示',
      buttons: [{
        text: '<span>确定</span>',
        type: 'button-positive'
      }]
    }).then(function () {
      if (callBackFunction) {
        callBackFunction();
      }
    });
  }

  /**
   * 从选择岗位返回后，修改当前发送参数中的deptid
   * 并且修改签字中的deptid和deptName
   */
  function modifyDeptid(workflowRequest, result) {
    var deptId = result.deptid,
      deptName = result.deptName;
    workflowRequest.deptid = deptId; // 修改deptid
    workflowRequest.sign = workflowRequest.sign.replace(/\d*\*/g, deptId + '*')
      .replace(/\|.*\|:/g, '|'+deptName+'|:'); // 修改签字中的有关岗位（部门）的deptid和deptName 
    return workflowRequest;
  }
  var WorkflowTransfer = {
    /**
     * 发送流程
     *
     * @param  {WorkflowResponse} workflowRequest
     * @return {Promise}
     */
    send: function(workflowRequest, selected) {
      var self = this;
      var removeModal = function () {
        if (self.selectorModal && self.selectorModal.modal) {
          self.selectorModal.modal.remove();
        }
      };
      showLoadingView();
      return this.sendWorkflowToServer(workflowRequest)
      .then(function(workflowResponse) {
        if (workflowResponse.info === '当前用户不具有任何启动角色且也没配置无角色启动节点!' 
        && LinkerService.currentUser.deptIds.length > 1) { // 当前登录人是一人多岗的情况才会展示选择岗位
          // 弹出弹框，进行岗位的选择，然后再发送出去。
          if(selected) { //表示选择的人的岗位还是没有任何启动角色
            showSendNoRoleMessage(workflowResponse, removeModal);
            return workflowResponse.success ? 'success' : 'failure';
          }
          workflowResponse.flag = 'selectJob';//选择岗位

          hideLoadingView();
          sinoClickService.clearCurrentTask();
          removeModal();

          self.selectorModal = new SelectorModal(workflowResponse);
          return self.selectorModal.show()
          .then(function(_workflowRequest) {
            if(_workflowRequest !== 'cancel') {
              workflowRequest = modifyDeptid(workflowRequest, _workflowRequest);
              return self.send(workflowRequest, 'selected');
            } else {
              removeModal();
              return "cancel";
            }
          });
        } else if (workflowResponse.flag) {
            hideLoadingView();
            sinoClickService.clearCurrentTask();
            removeModal();
            self.selectorModal = new SelectorModal(workflowResponse);
            return self.selectorModal.show()
              .then(function (workflowRequest) {
                if (workflowRequest !== 'cancel') {
                  return self.send(workflowRequest);
                } else {
                  removeModal();
                  return "cancel";
                }
              });
          } else {
            showSendResponseMessage(workflowResponse, removeModal);
            return workflowResponse.success ? 'success' : 'failure';
          }
        }, this.showErrorMessage)['finally'](function () {
          hideLoadingView();
        });
    },

    showErrorMessage: function () {
      var title = '发送失败!',
        info = '请您及时联系管理员修复!';
      if (!window.navigator.onLine) {
        title = '请您连接网络';
        info = '请您连接手机网络';
      }
      showSendResponseMessage({
        title: title,
        info: info
      });
    },

    /**
     * 发送流程请求到服务器
     *
     * @param  {WorkflowRequest} workflowRequest 发送流程的请求对象
     * @return {Promise}
     */
    sendWorkflowToServer: function (workflowRequest) {
      var _url = '/WorkFlowServlet' + '?recordId=' + workflowRequest.recordid + '&flowType=' + workflowRequest.filetypeid;
      return $http({
        method: 'POST',
        url: _url,
        data: workflowRequest,
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        timeout: 15000
      }).then(function (response) {
        return response.data;
      });
    },

    /**
     * 撤销办理
     * @param  {String} flowType 流程类型
     * @param  {String} recordId 业务ID
     * @return {Promise}
     */
    cancelDo: function (flowType, recordId) {
      return $http({
        method: 'POST',
        url: '/workflow/cancelDo?_method=PUT',
        params: {
          flowType: flowType,
          recordId: recordId
        },
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        timeout: 15000
      }).then(function (response) {
        return response.data;
      });
    },

    /**
     * 收回重办
     * @param  {String} flowType 流程类型
     * @param  {String} recordId 业务ID
     * @return {Promise}
     */
    recycle: function (flowType, recordId) {
      return $http({
        method: 'POST',
        url: '/workflow/cancelFlow?_method=PUT',
        params: {
          flowType: flowType,
          recordId: recordId
        },
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        timeout: 15000
      }).then(function (response) {
        return response.data;
      });
    },

    /**
     * 重启流程
     * @param  {String} flowType 流程类型，
     * @param  {String} recordId 业务数据ID
     * @return {Promise}
     */
    reuseProcess: function (flowType, recordId) {
      return $http({
        method: 'POST',
        url: '/workflow/reuse?_method=PUT',
        params: {
          flowType: flowType,
          recordId: recordId
        },
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        timeout: 15000
      }).then(function (response) {
        return response.data;
      });
    },

    /**
     * 恢复流程
     * @param  {String} flowType    流程类型
     * @param  {String} recordId    业务ID
     * @param  {String} subflag     文件状态
     * @param  {String} tableName   业务表名
     * @param  {String} idFieldName 业务表主键字段名
     * @return {Promise}
     */
    recoveryProcess: function (flowType, recordId, subflag, tableName, idFieldName) {
      return $http({
        method: 'PUT',
        url: '/workflow/resumeEndFlow',
        params: {
          flowType: flowType,
          recordId: recordId,
          subflag: subflag,
          tableName: tableName,
          idFieldName: idFieldName
        },
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        timeout: 15000
      }).then(function (response) {
        return response.data;
      });
    },

    /**
     * 结束流程
     * @param  {FinishWorkflowRequest} finishWorkflowRequest
     * @return {Promise}
     */
    finish: function (finishWorkflowRequest) {
      return $http({
        method: 'PUT',
        url: '/workflow/finish',
        data: finishWorkflowRequest,
        timeout: 15000
      }).then(function (response) {
        return response.data;
      });
    }
  };

  var methods = ['finish', 'recoveryProcess', 'reuseProcess', 'recycle', 'cancelDo'];

  for (var i = methods.length; i--;) {
    WorkflowTransfer[methods[i]] = wrapperFnWithLoading(WorkflowTransfer, WorkflowTransfer[methods[i]]);
  }

  return WorkflowTransfer;
});
