"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.Message = exports.NEW_MESSAGE = void 0;

var _mqttws = _interopRequireDefault(require("./mqttws31"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }

function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var NEW_MESSAGE = 'NEW_MESSAGE';
exports.NEW_MESSAGE = NEW_MESSAGE;

var Message = function Message() {
  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : message,
      id = _ref.id,
      infoContent = _ref.infoContent,
      infoLevel = _ref.infoLevel,
      time = _ref.time,
      infoType = _ref.infoType,
      dateTime = _ref.dateTime,
      webConfig = _ref.webConfig,
      webPath = _ref.webPath,
      messType = _ref.messType;

  _classCallCheck(this, Message);

  this.id = id;
  this.infoContent = infoContent;
  this.infoLevel = infoLevel;
  this.time = time;
  this.infoType = infoType; // 方案类型 - 工单 报警 公告 定时推送

  this.dateTime = dateTime;
  this.webConfig = webConfig;
  this.webPath = webPath;
  this.messType = messType; //方案名称 -  大类型下细类型
};

exports.Message = Message;

var Notifier =
/*#__PURE__*/
function () {
  function Notifier(userInfo) {
    _classCallCheck(this, Notifier);

    this.userInfo = userInfo;
    this.messageCache = {
      totalCount: 0,
      messages: []
    }; // 当前消息缓存

    this._subscribers = {}; //订阅器缓存

    this._siteConfig = {
      site_code: this.userInfo.site,
      TcpIP: '',
      TcpPort: 443,
      TimeOut: '',
      KeepAlive: '',
      IsSSL: true,
      mqtt_path: '/mqtt'
    };
    this._config = {
      mqtt_path: '/mqtt',
      nginxStart: 'false',
      mqtt_mess: {
        IsSSL: false
      }
    };
    this.MQTTCount = 0;
    this.MQTTClient = null;
    this.MQTTOptions = {};
    this.IsNeedReconnect = true; // 对外接口处理this指向问题

    this.start = this.start.bind(this);
    this.stop = this.stop.bind(this);
    this.subscribe = this.subscribe.bind(this);
    this.unsubscribe = this.unsubscribe.bind(this);
    this.confirmRead = this.confirmRead.bind(this);
  } // 对外接口


  _createClass(Notifier, [{
    key: "start",
    value: function start() {
      var _this = this;

      return regeneratorRuntime.async(function start$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              this._getMqttSiteCode().then(function () {
                _this.loadHisMessages({
                  userID: _this.userInfo.OID
                });

                _this.connectMQTTServer();
              });

            case 1:
            case "end":
              return _context.stop();
          }
        }
      }, null, this);
    }
  }, {
    key: "stop",
    value: function stop() {
      this.disconnectMQTTServer();
    }
  }, {
    key: "subscribe",
    value: function subscribe(type, handler) {
      if (!(type in this._subscribers)) {
        this._subscribers[type] = [];
      }

      this._subscribers[type].push(handler);
    }
  }, {
    key: "unsubscribe",
    value: function unsubscribe(type, handler) {
      if (!(type in this._subscribers)) {
        console.log('无效事件无法删除');
      }

      if (!handler) {
        delete this._subscribers[type];
      } else {
        var idx = this._subscribers[type].findIndex(function (ele) {
          return ele === handler;
        });

        if (idx === -1) {
          console.log('无效事件无法删除');
          return;
        }

        this._subscribers[type].splice(idx, 1);

        if (this._subscribers[type].length === 0) {
          delete this._subscribers[type];
        }
      }
    }
  }, {
    key: "publish",
    value: function publish(type, payload) {
      if (!(type in this._subscribers) || this._subscribers[type].length === 0) return;

      this._subscribers[type].forEach(function (handler) {
        try {
          handler(payload);
        } catch (e) {
          console.log('订阅器委托错误');
        }
      });
    }
  }, {
    key: "confirmRead",
    value: function confirmRead() {
      var isAll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var hisIDs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
      var list = [];
      if (this.messageCache && this.messageCache.totalCount == 0 && this.messageCache.messages.length == 0) return;
      if (isAll) hisIDs = this.messageCache.messages.map(function (item) {
        return item.id;
      });
      var me = this;
      Http.postInformationStatus({
        userID: this.userInfo.OID,
        hisID: hisIDs.join(','),
        isAll: isAll ? 1 : ''
      }).then(function (res) {
        if (res.statusCode != '0000') {
          console.log(res.errMsg);
          return;
        }

        if (isAll) {
          me.messageCache.totalCount = 0;
          me.messageCache.messages = [];
        } else {
          hisIDs.forEach(function (id) {
            var index = me.messageCache.messages.findIndex(function (item) {
              return item.id == id;
            });

            if (index != -1) {
              me.messageCache.messages.splice(index, 1);
              me.messageCache.totalCount--;
            }
          });
        }

        me.publish(NEW_MESSAGE, me.messageCache);
      })["catch"](function (err) {
        console.log('postInformationStatus调用失败' + err);
      });
    } // mqtt

  }, {
    key: "connectMQTTServer",
    value: function connectMQTTServer() {
      var hostname, port, clientId, timeout, keepAlive, cleanSession, ssl, userName, password, path;
      return regeneratorRuntime.async(function connectMQTTServer$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              hostname = this._siteConfig.TcpIP, port = this._siteConfig.TcpPort, clientId = 'client-' + this._createGuid(), timeout = 50, keepAlive = 60, cleanSession = true, ssl = this._siteConfig.IsSSL, userName = 'mao2080', password = '123', path = this._siteConfig.mqtt_path;
              this.MQTTCount = 0;
              this.MQTTClient = new _mqttws["default"].Client(hostname, port, path, clientId);
              this.MQTTOptions = {
                invocationContext: {
                  host: hostname,
                  port: port,
                  path: path,
                  clientId: clientId
                },
                timeout: timeout,
                keepAliveInterval: keepAlive,
                cleanSession: cleanSession,
                useSSL: ssl,
                userName: userName,
                password: password,
                onSuccess: this.onMQTTConnect.bind(this),
                onFailure: function onFailure(e) {
                  debugger;
                  console.log(e);
                }
              };
              this.MQTTClient.connect(this.MQTTOptions);
              this.MQTTClient.onConnectionLost = this.onMQTTConnectionLost.bind(this);
              this.MQTTClient.onMessageArrived = this.onMessageArrived.bind(this);

            case 7:
            case "end":
              return _context2.stop();
          }
        }
      }, null, this);
    }
  }, {
    key: "disconnectMQTTServer",
    value: function disconnectMQTTServer() {
      if (this.MQTTClient) {
        this.IsNeedReconnect = false;
        this.MQTTClient.diisconnect();
        this.MQTTClient = null;
      }
    }
  }, {
    key: "onMQTTConnect",
    value: function onMQTTConnect() {
      var site = this._siteConfig.site_code; //信息化主题

      var EIMTopic = site + "/EIM/info";
      this.MQTTClient.subscribe(EIMTopic); //节水主题

      var saveWaTopic = site + "/saveWater/info";
      this.MQTTClient.subscribe(saveWaTopic); //系统主题

      var sysTopic = site + "/system/info";
      this.MQTTClient.subscribe(sysTopic); //工单主题

      var caseTopic = site + "/workerOrder/info";
      this.MQTTClient.subscribe(caseTopic); //报警主题

      var SCADATopic = site + "/scada/alarm";
      this.MQTTClient.subscribe(SCADATopic); //用户主题

      var UserTopic = site + "/Message/".concat(this.userInfo.OID);
      this.MQTTClient.subscribe(UserTopic);
    }
  }, {
    key: "onMQTTConnectionLost",
    value: function onMQTTConnectionLost(responseObject) {
      console.log('连接丢失', responseObject);
      var me = this;

      if (this.IsNeedReconnect) {
        this.MQTTClient.connect(me.MQTTOptions);
        this.MQTTtester = setInterval(function () {
          if (me.MQTTClient.isConnected) {
            clearInterval(me.MQTTtester);
          } else {
            me.MQTTClient.connect(me.MQTTOptions);
          }
        }, 1000);
      }
    }
  }, {
    key: "onMessageArrived",
    value: function onMessageArrived(buffer) {
      var me = this;

      try {
        console.log('收到消息:' + buffer.payloadString);
        var temp = JSON.parse(buffer.payloadString);

        var infoType = this._typeInfo(temp.infoType);

        if (temp.tousers == '' || me.userInfo.OID == temp.tousers || temp.tousers.includes(me.userInfo.OID + ',') || temp.tousers.includes(',' + me.userInfo.OID)) {
          var messContent = temp.content;
          var timeH = (new Date() - new Date(temp.createTime)) / 1000 / 60;
          var timeMss = Math.abs(timeH) > 1440 ? temp.createTime.split('.')[0] : Math.abs(timeH) > 60 ? (timeH / 60).toFixed(0) + '小时前' : Math.abs(timeH) > 1 ? timeH.toFixed(0) + '分钟前' : '刚刚';
          var messString = {
            id: temp.ID,
            infoContent: messContent,
            infoLevel: temp.level,
            time: "".concat(timeMss),
            infoType: infoType,
            dateTime: temp.createTime,
            webConfig: temp.web_config,
            webPath: temp.web_path,
            messType: temp.MessType
          };
          if (this._IsVersion1()) messString.infoContent = this._handleMessageStrToJSON(infoType, messString);else messString.infoContent = JSON.parse(messString.infoContent);

          var _message = new Message(messString);

          this.messageCache.totalCount += 1;
          this.messageCache.messages.push(_message);
          me.publish(NEW_MESSAGE, this.messageCache);
        }
      } catch (e) {
        console.log('收到消息处理异常:' + e.message);
      }
    } // 工具类

  }, {
    key: "loadHisMessages",
    value: function loadHisMessages(_ref2) {
      var _this2 = this;

      var userID, _ref2$pageIndex, pageIndex, _ref2$pageSize, pageSize, me;

      return regeneratorRuntime.async(function loadHisMessages$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              userID = _ref2.userID, _ref2$pageIndex = _ref2.pageIndex, pageIndex = _ref2$pageIndex === void 0 ? 1 : _ref2$pageIndex, _ref2$pageSize = _ref2.pageSize, pageSize = _ref2$pageSize === void 0 ? 10 : _ref2$pageSize;
              me = this;
              return _context3.abrupt("return", Http.getInformationInfo({
                userID: userID,
                pageIndex: pageIndex,
                pageSize: pageSize,
                'request.preventCache': Date.now()
              }).then(function (res) {
                var _this2$messageCache$m;

                var result = {
                  totalCount: res.totalRcdNum,
                  messages: res.getMe.map(_this2._handleHisToMessage.bind(_this2))
                };
                _this2.messageCache.totalCount += result.totalCount;

                (_this2$messageCache$m = _this2.messageCache.messages).push.apply(_this2$messageCache$m, _toConsumableArray(result.messages));

                me.publish(NEW_MESSAGE, _this2.messageCache);
                return Promise.resolve(result);
              }));

            case 3:
            case "end":
              return _context3.stop();
          }
        }
      }, null, this);
    }
  }, {
    key: "_getMqttSiteCode",
    value: function _getMqttSiteCode() {
      var me;
      return regeneratorRuntime.async(function _getMqttSiteCode$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              me = this;
              return _context4.abrupt("return", Http.getMqttSiteCode({
                'request.preventCache': Date.now()
              }).then(function (res) {
                if (res.say.statusCode == '0000') {
                  if (res.getMe[0]) {
                    me._siteConfig.IsSSL = res.getMe[0].IsSSL ? res.getMe[0].IsSSL : false;
                    me._siteConfig.site_code = res.getMe[0].SiteCode || me._siteConfig.site_code;
                    me._siteConfig.TcpIP = res.getMe[0].TcpIP;
                    me._siteConfig.TcpPort = res.getMe[0].TcpPort ? parseInt(res.getMe[0].TcpPort) : 8083;
                    me._siteConfig.MessageLevel = res.getMe[0].MessageLevel ? res.getMe[0].MessageLevel : '1.0';
                  }

                  if (res.getMe[0].NginxStart) {
                    me._siteConfig.TcpIP = window.location.hostname;
                    me._siteConfig.TcpPort = parseInt(window.location.port);
                    me._siteConfig.mqtt_path = '/ws/';
                  } else {
                    me._siteConfig.TcpIP = 'emqttd.panda-water.cn';
                    me._siteConfig.TcpPort = 443;
                    me._siteConfig.IsSSL = true;
                  }
                } else {
                  console.log('获取mqtt服务器参数失败');
                }
              }));

            case 2:
            case "end":
              return _context4.stop();
          }
        }
      }, null, this);
    }
  }, {
    key: "_createGuid",
    value: function _createGuid() {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0,
            v = c == 'x' ? r : r & 0x3 | 0x8;
        return v.toString(16);
      }).toUpperCase();
    }
  }, {
    key: "_typeInfo",
    value: function _typeInfo(infoTypeStr) {
      var infoType = 'unknown';

      switch (infoTypeStr) {
        case '工单流程':
          infoType = 'caseType';
          break;

        case '系统消息':
        case '系统通知':
          infoType = 'sysType';
          break;

        case '节水通知':
          infoType = 'saveWaType';
          break;

        case '信息化':
          infoType = 'EIMType';
          break;

        case '消息提醒':
          infoType = 'remindType';
          break;

        case 'SCADA报警':
          infoType = 'scadaType';

        default:
          break;
      }

      return infoType;
    }
  }, {
    key: "_handleHisToMessage",
    value: function _handleHisToMessage(hisMessage) {
      var timeH = (new Date() - new Date(hisMessage.HisCreateTime)) / 1000 / 60;
      var timeMss = Math.abs(timeH) > 1440 ? hisMessage.HisCreateTime.split('.')[0] : Math.abs(timeH) > 60 ? (timeH / 60).toFixed(0) + '小时前' : Math.abs(timeH) > 1 ? timeH.toFixed(0) + '分钟前' : '刚刚';
      var message = {
        id: hisMessage.HisID,
        infoContent: hisMessage.InfoContent,
        time: "".concat(timeMss),
        infoType: this._typeInfo(hisMessage.InfoType),
        dateTime: hisMessage.HisCreateTime,
        infoLevel: hisMessage.InfoLevel,
        webConfig: hisMessage.web_config,
        webPath: hisMessage.web_path,
        messType: hisMessage.MessType
      };
      if (this._IsVersion1()) message.infoContent = this._handleMessageStrToJSON(message.infoType, message);else message.infoContent = JSON.parse(message.infoContent);
      return new Message(message);
    } // 1.0 解析规则

  }, {
    key: "_IsVersion1",
    value: function _IsVersion1() {
      return !this._siteConfig.MessageLevel || this._siteConfig.MessageLevel != '2.0';
    }
  }, {
    key: "_handleMessageStrToJSON",
    value: function _handleMessageStrToJSON(infoType, messString) {
      var infoContent = messString;

      switch (infoType) {
        case 'scadaType':
          infoContent = this._analysisAlarm(messString);
          break;

        case 'caseType':
          infoContent = this._analysisCase(messString);
          break;

        case 'sysType':
          infoContent = this._analysisNotice(messString);
          break;

        case 'saveWaType':
          break;

        case 'EIMType':
          break;

        default:
          break;
      }

      return infoContent;
    }
  }, {
    key: "_analysisCase",
    value: function _analysisCase(messString) {
      var attr = messString.infoContent.split('\\n');
      var caseContent = {
        caseType: attr[0].split('】')[0].split('【')[1],
        flowName: attr[0].split('】')[1],
        nodeName: attr[1],
        content: attr[2],
        time: messString.dateTime
      };
      return caseContent;
    }
  }, {
    key: "_analysisAlarm",
    value: function _analysisAlarm(messString) {
      var attr = messString.infoContent.split('\\n');
      var alarmContent = {
        alarmType: attr[0].split('】')[0].split('【')[1],
        deviceCode: '',
        alarmDevice: attr[0].split('】')[1],
        alarmContent: attr[1],
        alarmThreshold: attr[2].includes(' / ') ? attr[2].split('/')[1].trim(' ') : '',
        alarmValue: attr[2].includes(' / ') ? attr[2].split('/')[0].trim(' ') : attr[2].includes('：') ? attr[2].split('：')[1] : '',
        time: messString.dateTime
      };
      return alarmContent;
    }
  }, {
    key: "_analysisNotice",
    value: function _analysisNotice(messString) {
      var attr = messString.infoContent.split('\\n');
      var noticeContent = {
        noticeType: attr[0].split('】')[0].split('【')[1],
        noticeTitle: attr[0].split('】')[1],
        noticeContent: attr[1],
        time: messString.dateTime
      };
      return noticeContent;
    }
  }]);

  return Notifier;
}();

var _default = Notifier;
exports["default"] = _default;