'use strict';

var angular = require('angular');
require('../modules');
require('uiRouter');
var module = angular.module('devicemanager.services');

/**
 * 设备状态属性：
 *
 * * locakStatus {string} - 锁定状态，'LOCK' or 'UNLOCK', 表示设备是否被锁定，与当前登录人无关
 * * bindUserId {string} @deprecated - 该设备已经绑定的人。与当前登录人无关
 * * bindUsers {string[]} - 该设备已经绑定的人。
 * * bind {boolean} - 当前登录人是否绑定过设备。与当前登录人相关
 * * bindStatus {string} - 当前登录人与当前设备的绑定申请状态，`1`表示申请中，`2`表示申请通过，`3`表示申请没通过。与当前登录人相关
 * * applyBindingUserId {string} - 发送绑定申请的人，与当前登录人一致。与当前登录人相关
 *
 * 规则：
 *
 * 1. 如果获取到的状态中applyBindingUserId不是当前登录人，则与当前登录人相关的状态属性值将会被抛弃。
 *
 */

/**
 * 同步设备状态
 */
module.run(function($rootScope, DeviceManager) {
  DeviceManager.syncRemote();
  $rootScope.$on('server.online', function() {
    DeviceManager.syncRemote();
  });
  $rootScope.$on('resume', function() {
    DeviceManager.syncRemote();
  });
});

module.factory('DeviceStatusCache', function() {
  return {
    get: function() {
      var deviceStatusJSON = localStorage.getItem('deviceStatus');
      return deviceStatusJSON? JSON.parse(deviceStatusJSON) : {};
    },
    set: function(deviceStatus) {
      if (deviceStatus) {
        localStorage.setItem('deviceStatus', JSON.stringify(deviceStatus));
      } else {
        localStorage.removeItem('deviceStatus');
      }
    }
  }
})
.factory('DeviceStatusService', function($http, LinkerService) {
  return {
    /**
     * 获取设备状态
     */
    fetchDeviceStatus: function() {
      var userId = LinkerService.currentUserId || '',
        url  = '/device/status/' + window.device.uuid + '?userId=' + userId;
      return $http.get(url).then(function(response) {
        return response.data;
      });
    },
    /**
     * 申请绑定
     * @param  {String} userId 用户id
     * @param  {String} devSn  设备编码
     * @return {Promise}
     */
    submitApply: function(userId, devSn) {
      var params = {};
      params.applyUserId = userId;
      params.devSn = devSn;
      return $http({
        url: '/device/binding/',
        method: 'POST',
        data: params
      }).then(function(response) {
        return response.data;
      });
    },

    /**
     * 直接绑定人与设备
     * @param {string} userId 绑定人
     * @param {string} devSn 设备
     */
    bind: function(userId, devSn) {
      devSn = devSn === -1 ? window.device.uuid : devSn;
      var url  = '/device/binding/passedBySelf/' + userId + '/' + devSn;
      return $http.put(url).then(function(response) {
        return response.data;
      });
    }
  };
});

module.factory('DeviceManager', function($state, LinkerService, $toast, DeviceStatusCache, DeviceStatusService, $timeout, AppConfig) {
  function syncDeviceState(nextAction) {
    DeviceManager._deviceStatus = DeviceStatusCache.get();
    DeviceManager.nextAction = nextAction ? nextAction : DeviceManager.nextAction;
    if (DeviceManager.nextAction) {
      DeviceManager.nextAction();
    }
  }

  /**
   * 保存设置状态数据
   *
   * @param {DeviceStatus} data
   */
  function applyDeviceStateData(data) {
    var _deviceStatus = data || {};
    DeviceManager._deviceStatus = _deviceStatus;
    DeviceStatusCache.set(_deviceStatus);
  }

  /**
   * 判别锁定状态是否发生变化
   *
   * @param {DeviceStatus} deviceInfo
   * @param {DeviceStatus} oldDeviceInfo
   * @returns {boolean}
   */
  function checkLockStatusChange(deviceInfo, oldDeviceInfo) {
    var newLockStatus = deviceInfo.lockStatus || 'UNLOCK';
    var oldLockStatus = oldDeviceInfo.lockStatus || 'UNLOCK';

    var lockPageStatusChange = newLockStatus === 'UNLOCK' && $state.$current.name === 'devicemanager.lockPage';
    var unLockPageStatusChange = newLockStatus === 'LOCK' && $state.$current.name !== 'devicemanager.lockPage';

    return (newLockStatus !== oldLockStatus) || lockPageStatusChange || unLockPageStatusChange;
  }

  function isArray(array) {
    return Object.prototype.toString.call(array) === "[object Array]";
  }

  function indexOf(array, item) {
    if (!array) {
      return -1;
    }
    for (var i = 0, len = array.length; i < len; i++) {
      if (array[i] === item) {
        return i;
      }
    }
    return -1;
  }

  function isSameArray(array1, array2) {
    if ((!array1) && (!array2)) {
      return true;
    }

    if (array1 && !isArray(array1)) {
      array1 = [array1];
    }

    if (array2 && !isArray(array2)) {
      array2 = [array2];
    }

    array1 = array1 || [];
    array2 = array2 || [];

    if (array1.length !== array2.length) {
      return false;
    } else {
      for (var i = 0, len = array1.length; i < len; i++) {
        if (indexOf(array2, array1[0]) === -1) {
          return false;
        }
      }

      for (var i = 0, len = array2.length; i < len; i++) {
        if (indexOf(array1, array1[0]) === -1) {
          return false;
        }
      }

      return true;
    }
  }

  function getBindUser(deviceInfo) {
    if (deviceInfo.bindUsers) {
      return deviceInfo.bindUsers;
    } else {
      return deviceInfo.bindUserId ? [deviceInfo.bindUserId] : [];
    }
  }

  /**
   * 判别绑定状态是否发生变化
   *
   * @param {DeviceStatus} deviceInfo
   * @param {DeviceStatus} oldDeviceInfo
   * @returns {boolean}
   */
  function checkBindStatusChange(deviceInfo, oldDeviceInfo) {
    var newBindUserId = getBindUser(deviceInfo);
    var oldBindUserId = getBindUser(oldDeviceInfo);

    var newBind = deviceInfo.bindStatus || '1';
    var oldBind = oldDeviceInfo.bindStatus || '1';

    return !isSameArray(newBindUserId, oldBindUserId) || newBind !== oldBind;
  }

  /**
   * 从服务器同步设备状态
   */
  function syncRemote() {
    return DeviceStatusService.fetchDeviceStatus().then(function(status) {
      DeviceManager.changeDeviceInfo(status, true);
    });
  }

  var DeviceManager = {
    sync: syncDeviceState,
    syncRemote: syncRemote,
    _deviceStatus: DeviceStatusCache.get(),
    applyDeviceStateData: applyDeviceStateData,

    /**
     * 获取设备编号
     */
    getDevSn: function() {
      return window.device.uuid;
    },

    /**
     * 用户之前是否绑定过设备
     * @return {Boolean}
     */
    isBindedDevice: function() {
      var _deviceStatus = DeviceStatusCache.get();
      return _deviceStatus !== null && _deviceStatus.bind;
    },
    /**
     * 设备是否被锁定
     *
     * @return {Boolean}
     */
    isLocked: function() {
      var _deviceStatus = DeviceStatusCache.get();
      return _deviceStatus !== null && _deviceStatus.lockStatus === 'LOCK';
    },
    /**
     * 设备是否已有绑定人。
     *
     * @return {Boolean}
     */
    isBinded: function() {
      var _deviceStatus = DeviceStatusCache.get();
      var bindUsers = getBindUser(_deviceStatus);
      return _deviceStatus !== null && bindUsers.length > 0;
    },
    /**
     * 设备是否绑定给某个用户
     *
     * @param  {String}  userId 用户id
     * @return {Boolean}
     */
    isBindedTo: function(userId) {
      var _deviceStatus = DeviceStatusCache.get();
      var bindUsers = getBindUser(_deviceStatus);
      return _deviceStatus !== null && indexOf(bindUsers, userId) >= 0;
    },

    /**
     * 获取当前认证用户与该设备的绑定申请状况。
     *
     * @return {Boolean}
     */
    getBindApplyStatus: function() {
      var _deviceStatus = DeviceStatusCache.get();
      return _deviceStatus !== null && _deviceStatus.bindingStatus || -1;
    },

    execLockJudge: function() {
      if (DeviceManager.isLocked()) {
        $state.go('devicemanager.lockPage');
      } else {
        if (DeviceManager.lockNextAction) {
          DeviceManager.lockNextAction();
        } else {
          if(!AppConfig.getCustomResult('passwordLoginEnable')) {
            $state.go('calogin');
          } else {
            $state.go('login'); // 定制是否所有密码登录页面
          }
        }
      }
    },

    judgeLocked: function(nextAction) {
      DeviceManager.lockNextAction = nextAction;
      DeviceManager.execLockJudge();
    },

    setLockStatus: function(lockStatus) {
      var deviceStatus = DeviceStatusCache.get();
      deviceStatus.lockStatus = lockStatus;
      DeviceManager.changeDeviceInfo(deviceStatus);
    },

    execBindJudge: function() {
      if (DeviceManager.isBindedTo(LinkerService.currentUserId) && DeviceManager.bindNextAction) {
        DeviceManager.bindNextAction();
      }
      if (!DeviceManager.isBinded()) {
        $state.go('devicemanager.unBinded');
      } else if (LinkerService.currentUserId && (!DeviceManager.isBindedTo(LinkerService.currentUserId))) {
        $state.go('devicemanager.bindedToOtherUser');
      }
    },

    judgeDeviceBind: function(nextAction) {
      DeviceManager.bindNextAction = nextAction;
      DeviceManager.execBindJudge();
    },

    /**
     * 变更设备状态
     *
     * @param {DeviceStatus} deviceInfo 设备状态
     */
    changeDeviceInfo: function(deviceInfo, forceUpdateBindingInfo) {
      var currentUserId = LinkerService.currentUserId;
      var _deviceStatus = DeviceStatusCache.get();
      var lockedChanged = checkLockStatusChange(deviceInfo, _deviceStatus);
      var bindChanged = checkBindStatusChange(deviceInfo, _deviceStatus);
      var isSelfBindInfo = currentUserId && currentUserId === deviceInfo.applyBindingUserId;

      if (!forceUpdateBindingInfo && !isSelfBindInfo) {
        _deviceStatus.lockStatus = deviceInfo.lockStatus;
        _deviceStatus.bindUserId = deviceInfo.bindUserId;
        _deviceStatus.bindUsers = deviceInfo.bindUsers;
        deviceInfo = _deviceStatus;
      }

      applyDeviceStateData(deviceInfo);

      if (lockedChanged) {
        DeviceManager.execLockJudge();
      } else if (bindChanged && isSelfBindInfo) {
        if (deviceInfo.bindingStatus === '3') {
          $toast.showShortCenter('设备绑定未通过，请重新绑定！');
        }

        DeviceManager.execBindJudge();
      }
    },

    /**
     * 直接绑定设备
     * @param  {string} userId 用户id
     * @param  {string} devSn  设备编码
     */
    bind: function(userId, devSn) {
      return DeviceStatusService.bind(userId, devSn);
    },

    /**
     * 申请绑定
     * @param  {string} userId 用户id
     * @param  {string} devSn  设备编码
     * @return {Promise}
     */
    submitApply: function(userId, devSn) {
      return DeviceStatusService.submitApply(userId, devSn)
        .then(function() {
          return DeviceManager.syncRemote();
        });
    },
    /**
     * 获取审核状态
     */
    viewApprovalStatus: function() {
      return DeviceStatusService.fetchDeviceStatus()
        .then(function(status) {
          var bindingStatus = status.bindingStatus;
          if(bindingStatus === '1') {
            $toast.showShortBottom('设备绑定申请仍处于审核阶段，请稍后...');
          } else if(bindingStatus === '2') {
            DeviceManager.applyDeviceStateData(status);
            DeviceManager.bindNextAction();
          } else if(bindingStatus === '3'){
            DeviceManager.changeDeviceInfo(status);
          } else {
            $toast.showShortCenter('设备绑定申请审核遭遇未知错误，请您联系管理员！');
          }
        });
    },

    /**
     * 获取绑定提示页面的提示状态
     *
     * 1：已有申请，提示等待审核；
     * 2：提交申请；
     * 3：审批不通过，提示重新申请
     * 4：该设备已经绑定给自己，不需要发出任何申请，直接进入下一阶段
    */
    getPageInfoStatus: function() {
      var _deviceStatus = DeviceStatusCache.get();
      var bindStatus = 4;
      if(!this.isBinded()) { //未绑定任何人
        if(this.getBindApplyStatus() === '1') {//已有申请，提示等待审核
          bindStatus = 1;
        } else if(this.getBindApplyStatus() !== '1' && this.getBindApplyStatus() !== '2'){ //提示提交申请
          bindStatus = 2;
        } else if(_deviceStatus !== null && _deviceStatus.bindingStatus === '3') {
          bindStatus = 3;
        }
      } else if(!this.isBindedTo(LinkerService.currentUserId)) { //绑定过其他人
        if(this.getBindApplyStatus() === '1') { //有申请，提示等待审核
          bindStatus = 1;
        } else if (_deviceStatus !== null && _deviceStatus.bindingStatus === '3') { //申请不通过，重新申请
          bindStatus = 3;
        } else {//无申请，有申请绑定按钮。
          bindStatus = 2;
        }
      }

      return bindStatus;
    }
  };

  return DeviceManager;
});
