import MqttClient from './mqttws31';
import mock from './mock.json';

export const NEW_MESSAGE = 'NEW_MESSAGE';
export class Message {
  constructor() {
    this.CreateTime,
      this.HisCreateTime,
      this.HisID,
      this.ID,
      this.InfoContent,
      this.InfoDist,
      this.InfoLevel,
      this.InfoType,
      this.IsRead,
      this.MessType,
      this.ToUsers,
      this.UserID,
      this.app_config,
      this.app_path,
      this.web_config,
      this.web_path,
      this.time;
  }
}

class Notifier {
  constructor(userInfo) {
    // this.userInfo=userInfo;
    this.userInfo = {
      site: '192_168_19_105_site_c8de50fc',
      OID: 5,
    };
    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;
  }

  // 对外接口
  async start() {
    this.loadHisMessages({ userID: this.userInfo.OID });
    this.connectMQTTServer();
  }
  stop() {
    this.disconnectMQTTServer();
  }
  subscribe(type, handler) {
    if (!(type in this._subscribers)) {
      this._subscribers[type] = [];
    }
    this._subscribers[type].push(handler);
  }
  unsubscribe(type, handler) {
    if (!(type in this._subscribers)) {
      console.log('无效事件无法删除');
    }
    if (!handler) {
      delete this._subscribers[type];
    } else {
      const idx = this._subscribers[type].findIndex(ele => ele === handler);
      if (idx === -1) {
        console.log('无效事件无法删除');
        return;
      }
      this._subscribers[type].splice(idx, 1);
      if (this._subscribers[type].length === 0) {
        delete this._subscribers[type];
      }
    }
  }
  publish(type, payload) {
    if (!(type in this._subscribers) || this._subscribers[type].length === 0)
      return;
    this._subscribers[type].forEach(handler => {
      try {
        handler(payload);
      } catch (e) {
        console.log('订阅器委托错误');
      }
    });
  }

  // mqtt
  async connectMQTTServer() {
    this._getMqttSiteCode().then(() => {
      let 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 MqttClient.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(e) {
          console.log(e);
        },
      };
      this.MQTTClient.connect(this.MQTTOptions);
      this.MQTTClient.onConnectionLost = this.onMQTTConnectionLost.bind(this);
      this.MQTTClient.onMessageArrived = this.onMessageArrived.bind(this);
    });
  }
  disconnectMQTTServer() {
    if (this.MQTTClient) {
      this.IsNeedReconnect = false;
      this.MQTTClient.diisconnect();
      this.MQTTClient = null;
    }
  }
  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/${this.userInfo.OID}`;
    this.MQTTClient.subscribe(UserTopic);
  }
  onMQTTConnectionLost(responseObject) {
    debugger;
    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);
    }
  }
  onMessageArrived(message) {
    let me = this;
    try {
      console.log('收到消息:' + message.payloadString);
      let temp = JSON.parse(message.payloadString);
      let infoType = this._typeInfo(temp);
      if (
        temp.tousers == '' ||
        me.userInfo.OID == temp.tousers ||
        temp.tousers.includes(me.userInfo.OID + ',') ||
        temp.tousers.includes(',' + me.userInfo.OID)
      ) {
        let messContent = temp.content;
        if (
          me._siteConfig.MessageLevel &&
          me._siteConfig.MessageLevel == '2.0'
        ) {
          messContent = me._messageThrome(infoType, JSON.parse(temp.content));
        }
        let timeH = (new Date() - new Date(temp.createTime)) / 1000 / 60;
        let timeMss =
          Math.abs(timeH) > 1440
            ? temp.createTime.split('.')[0]
            : Math.abs(timeH) > 60
            ? (timeH / 60).toFixed(0) + '小时前'
            : Math.abs(timeH) > 1
            ? timeH.toFixed(0) + '分钟前'
            : '刚刚';
        let messString = {
          ID: temp.infoId,
          Info: messContent,
          InfoLevel: temp.level,
          time: `${timeMss}`,
          infoType: infoType,
          messageType: '',
          dateTime: temp.createTime,
          web_config: temp.web_config,
          web_path: temp.web_path,
          messType: temp.MessType,
        };
        let message = me._handleMqttToMessage(messString);
        this.messageCache.totalCount += 1;
        this.messageCache.messages.push(message);
        me.publish(NEW_MESSAGE, this.messageCache);
      }
    } catch (e) {
      console.log('收到消息处理异常:'+e.message);
    }
  }

  // 工具类
  async loadHisMessages({ userID, pageIndex = 1, pageSize = 10 }) {
    let me = this;
    return Http.getInformationInfo({
      userID,
      pageIndex,
      pageSize,
      'request.preventCache': Date.now(),
    }).then(res => {
      let result = {
        totalCount: res.totalRcdNum,
        messages: res.getMe.map(this._handleHisToMessage),
      };
      this.messageCache.totalCount += result.totalCount;
      this.messageCache.messages.push(...result.messages);
      me.publish(NEW_MESSAGE, this.messageCache);
      return Promise.resolve(result);
    });
  }
  async _getMqttSiteCode() {
    let me = this;
    return Http.getMqttSiteCode({ 'request.preventCache': Date.now() }).then(
      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服务器参数失败');
        }
      },
    );
  }
  _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();
  }
  _typeInfo(temp) {
    var infoType = 'scadaType';
    switch (temp.infoType) {
      case '工单流程':
        infoType = 'caseType';
        break;
      case '系统消息':
      case '系统通知':
        infoType = 'sysType';
        break;
      case '节水通知':
        infoType = 'saveWaType';
        break;
      case '信息化':
        infoType = 'EIMType';
        break;
      case '消息提醒':
        infoType = 'remindType';
        break;
      default:
        break;
    }
    return infoType;
  }
  _messageThrome(themeName, info) {
    var messInfo = '';
    switch (themeName) {
      case 'caseType':
      case '工单提醒':
        messInfo = `【${info.caseType}】${info.flowName}\\n${
          info.nodeName
        }\\n承办意见：${info.content}`;
        break;
      case 'scadaType':
      case '通用报警':
        messInfo = `【${info.alarmType}】${info.alarmDevice}\\n${
          info.alarmContent
        }\\n${info.alarmValue} / ${info.alarmThreshold}\\n${info.deviceCode}`;
        break;
      case 'sysType':
      case '系统通知':
        messInfo = `【${info.noticeType}】${info.noticeTitle}\\n${
          info.noticeContent
        }`;
        break;
      // case "remindType": case "remindType":
      //     messInfo = ``;
      //     break;
      default:
        break;
    }
    return messInfo;
  }
  _handleHisToMessage(hisMessage) {
    let message = new Message();
    message = {
      ...hisMessage,
      ...{
        ToUsers: hisMessage.Tousers,
      },
    };
    delete message['Tousers'];
    return message;
  }
  _handleMqttToMessage(mqttMessage) {
    let message = new Message();
    message.ID = mqttMessage.ID;
    message.InfoContent = mqttMessage.Info;
    message.InfoLevel = mqttMessage.InfoLevel;
    message.time = mqttMessage.time;
    message.infoType = mqttMessage.infoType;
    message.CreateTime = mqttMessage.dateTime;
    message.web_config = mqttMessage.web_config;
    message.web_path = mqttMessage.web_path;
    message.MessType = mqttMessage.messType;
    return message;
  }
}

export default Notifier;
