const Server = require('socket.io');
const system = require('../base/system');
const redisClient = system.getObject('util.redisClient');
const notifyCtl = system.getObject('web.socketNotifyCtl');
const msgHistoryService = system.getObject('service.msghistorySve');
class MsgHandler {
  constructor(server, client) {
    this.server = server;
    this.client = client;
    this.init();
  }
  notifyClient(ukchannel, msg) {
    const msgH = { msgType: 'system', sender: 's￥s￥s￥s', target: msg.to, content: msg.content };
    msgHistoryService.create(msgH).then((m) => {
      redisClient.publish(ukchannel, JSON.stringify(msg));
    })
      .catch((e) => {
        console.log(e);
      });
  }
  init() {
    const self = this;
    // 转发通信消息
    this.client.on('chatmsg', (msg) => {
      const { from } = msg;
      const { to } = msg;
      const msgContent = msg.content;
      const arrs = to.split('￥');
      const tochannel = `${arrs[0]}￥${arrs[1]}`;
      // 发布消息
      // 持久化消息
      const msgH = { msgType: 'single', sender: msg.from, target: msg.to, content: msg.content };
      msgHistoryService.create(msgH).then((m) => {
        redisClient.publish(tochannel, JSON.stringify(msg));
      })
        .catch((e) => {
          console.log(e);
        });
      // self.server.users[to].emit("chatmsg",msg);
    });

    // 响应消息处理
    this.client.on('replymsg', (msg, fn) => {
      let p = null;
      const invokeObj = system.getObject(`web.${msg.pkgname}.${msg.cls}`);
      if (invokeObj[msg.method]) {
        p = invokeObj[msg.method].apply(invokeObj, [msg.data]);
      }
      p.then((r) => {
        fn(r);
      }).then(() => {
        console.log('call success');
      })
        .catch((err) => {
          console.log(err);
        });
    });
  }
}
class SocketServer {
  constructor(httpServer) {
    this.server = Server(httpServer, {
      serveClient: false,
    });
    this.users = {};
    this.init();
    this.onlines = 0;
  }
  init() {
    const self = this;
    // 挂载到web应用的控制器
    notifyCtl.setSocketServer(self);
    // 订阅广播频道
    redisClient.subscribe('brc', self);
    // 中间件可以在链接事件发出前调用一次
    this.server.use((socket, next) => {
      next();
    });
    this.server.on('connection', (client) => {
      console.log('connection.....socket');
      // 链接登录事件
      client.on('login', (data) => {
        console.log('login...........................................................success');
        console.log(data);
        console.log(client.remoteAddress);
        const uk = `${data.appid}￥${data.id}`;
        client.uk = uk;
        client.uid = data.id;
        client.username = data.nickName;
        client.appname = data.appname;
        client.appkey = data.appkey;
        client.sex = data.sex;
        client.imgUrl = data.imgUrl;
        self.users[uk] = new MsgHandler(self, client);
        // 订阅uk私人频道
        const ss = redisClient.subscribe(uk, self);
        // 加入redisClient列表
        redisClient.sadd(`${'onlineset' + '￥'}${data.appkey}`, [`${uk}￥${data.nickName}￥${data.imgUrl}`]).then((n) => {
          // 当前在线
          self.onlines = n;
          redisClient.publish('brc', JSON.stringify({ type: 'online', content: n }));
        });
      });
      // 链接断开事件
      client.on('disconnect', async (r) => {
        console.log('connection.........................................dismiss.............');
        if (client.uk) {
          await redisClient.srem(`${'onlineset' + '￥'}${client.appkey}`, `${client.uk}￥${client.username}￥${client.imgUrl}`);
          await redisClient.publish('brc', JSON.stringify({ type: 'online', content: (self.onlines--) }));
          delete self.users[client.uk];
          redisClient.unsubscribe(client.uk);
          // redisClient.unsubscribe("brc");
          console.log(`${client.uk}￥${client.username}￥${client.imgUrl}`);
        }
      });
    });
  }
}
module.exports = SocketServer;
