import Event from "../utils/event";
import User from "../model/user";
import Stream from "../model/stream";
import { EVENT } from "../common/constants";
const TAG_NAME = 'UserController';
/**
 * 通讯成员管理
 */

class UserController {
  constructor(componentContext) {
    // userMap 用于存储完整的数据结构
    this.userMap = new Map(); // userList 用于存储简化的用户数据 Object,包括 {userID hasMainAudio hasMainVideo hasAuxAudio hasAuxVideo}

    this.userList = []; // streamList 存储steam 对象列表,用于trtc-room 渲染 player

    this.streamList = [];
    this._emitter = new Event();
    this.componentContext = componentContext;
    this.isNewVersion = componentContext.isNewVersion;
  }

  userEventHandler(event) {
    const code = event.detail.code;
    let data;

    if (event.detail.message && typeof event.detail.message === 'string') {
      try {
        data = JSON.parse(event.detail.message);
      } catch (exception) {
        console.warn(TAG_NAME, 'userEventHandler 数据格式错误', exception);
        return false;
      }
    } else {
      console.warn(TAG_NAME, 'userEventHandler 数据格式错误');
      return false;
    }

    switch (code) {
      case 1020:
        // console.log(TAG_NAME, '远端用户全量列表更新:', code)
        if (!this.isNewVersion) {// TODO 旧版SDK处理逻辑,返回全量的用户列表,需要对userList 进行前后对比,筛选出新增用户,暂不实现
        }

        break;

      case 1031:
        // console.log(TAG_NAME, '远端用户进房通知:', code)
        // 1031 有新用户
        // {
        //   "userlist":[
        //          {
        //              "userid":"webrtc11"
        //          }
        //      ]
        // }
        this.addUser(data);
        break;

      case 1032:
        // console.log(TAG_NAME, '远端用户退房通知:', code)
        // 1032 有用户退出
        this.removeUser(data);
        break;

      case 1033:
        // console.log(TAG_NAME, '远端用户视频状态位变化通知:', code)
        // 1033 用户视频状态变化,新增stream或者更新stream 状态
        // {
        //   "userlist":[
        //          {
        //              "userid":"webrtc11",
        //              "playurl":" room://rtc.tencent.com?userid=xxx&streamtype=main",
        //              "streamtype":"main",
        //              "hasvideo":true
        //          }
        //      ]
        // }
        this.updateUserVideo(data);
        break;

      case 1034:
        // console.log(TAG_NAME, '远端用户音频状态位变化通知:', code)
        // 1034 用户音频状态变化
        // {
        //   "userlist":[
        //          {
        //              "userid":"webrtc11",
        //              "playurl":" room://rtc.tencent.com?userid=xxx&streamtype=main",
        //              "hasaudio":false
        //          }
        //      ]
        // }
        this.updateUserAudio(data);
        break;
    }
  }
  /**
   * 处理用户进房事件
   * @param {Object} data pusher 下发的数据
   */


  addUser(data) {
    // console.log(TAG_NAME, 'addUser', data)
    const incomingUserList = data.userlist;
    const userMap = this.userMap;

    if (Array.isArray(incomingUserList) && incomingUserList.length > 0) {
      incomingUserList.forEach(item => {
        const userID = item.userid; // 已经在 map 中的用户

        let user = this.getUser(userID);

        if (!user) {
          // 新增用户
          user = new User({
            userID: userID
          });
          this.userList.push({
            userID: userID
          });
        }

        userMap.set(userID, user);

        this._emitter.emit(EVENT.REMOTE_USER_JOIN, {
          userID: userID,
          userList: this.userList
        }); // console.log(TAG_NAME, 'addUser', item, userMap.get(userID), this.userMap)

      });
    }
  }
  /**
   * 处理用户退房事件
   * @param {Object} data pusher 下发的数据 {userlist}
   */


  removeUser(data) {
    // console.log(TAG_NAME, 'removeUser', data)
    const incomingUserList = data.userlist;

    if (Array.isArray(incomingUserList) && incomingUserList.length > 0) {
      incomingUserList.forEach(item => {
        const userID = item.userid;
        let user = this.getUser(userID); // 从userList 里删除指定的用户和 stream

        this._removeUserAndStream(userID); // 重置


        user.streams['main'] && user.streams['main'].reset();
        user.streams['aux'] && user.streams['aux'].reset(); // 用户退出,释放引用,外部调用该 user 所有stream 的 playerContext.stop() 方法停止播放
        // TODO 触发时机提前了,方便外部用户做出处理,时机仍需进一步验证

        this._emitter.emit(EVENT.REMOTE_USER_LEAVE, {
          userID: userID,
          userList: this.userList,
          streamList: this.streamList
        });

        user = undefined;
        this.userMap.delete(userID); // console.log(TAG_NAME, 'removeUser', this.userMap)
      });
    }
  }
  /**
   * 处理用户视频通知事件
   * @param {Object} data pusher 下发的数据 {userlist}
   */


  updateUserVideo(data) {
    // console.log(TAG_NAME, 'updateUserVideo', data)
    const incomingUserList = data.userlist;

    if (Array.isArray(incomingUserList) && incomingUserList.length > 0) {
      incomingUserList.forEach(item => {
        // 修改现有用户属性
        const userID = item.userid;
        const streamType = item.streamtype;
        const hasVideo = item.hasvideo;
        const src = item.playurl;
        const user = this.getUser(userID); // 如果找到该用户,则更新用户的信息和相关的stream 信息

        if (user) {
          let stream = user.streams[streamType]; // console.log(TAG_NAME, 'updateUserVideo', user, streamType, stream)
          // 更新指定的stream

          if (!stream) {
            user.streams[streamType] = stream = new Stream({
              streamType: streamType
            }); // 更新streamList

            this.streamList.push(stream);
          }

          if (hasVideo && streamType === 'aux') {
            stream.objectFit = 'contain';
          }

          if (!hasVideo && streamType === 'aux') {
            // TODO 如果是辅流可能要移除该 stream
            this._removeStream(stream);
          } else {
            stream.userID = userID;
            stream.streamID = userID + '_' + streamType;
            stream.hasVideo = hasVideo;
            stream.src = src;
          } // 更新所属user 的 hasXxx 值


          this.userList.find(item => {
            if (item.userID === userID) {
              item[`has${streamType.replace(/^\S/, s => s.toUpperCase())}Video`] = hasVideo;
              return true;
            }
          });
          const eventName = hasVideo ? EVENT.REMOTE_VIDEO_ADD : EVENT.REMOTE_VIDEO_REMOVE;

          this._emitter.emit(eventName, {
            stream: stream,
            streamList: this.streamList,
            userList: this.userList
          }); // console.log(TAG_NAME, 'updateUserVideo', user, stream, this.userMap)

        }
      });
    }
  }
  /**
   * 处理用户音频通知事件
   * @param {Object} data pusher 下发的数据 {userlist}
   */


  updateUserAudio(data) {
    // console.log(TAG_NAME, 'updateUserAudio', data)
    const incomingUserList = data.userlist;

    if (Array.isArray(incomingUserList) && incomingUserList.length > 0) {
      incomingUserList.forEach(item => {
        const userID = item.userid; // 音频只跟着 stream main ,这里只修改 main

        const streamType = 'main';
        const hasAudio = item.hasaudio;
        const src = item.playurl;
        const user = this.getUser(userID);

        if (user) {
          let stream = user.streams[streamType];

          if (!stream) {
            user.streams[streamType] = stream = new Stream({
              streamType: streamType
            }); // 更新streamList

            this.streamList.push(stream);
          }

          stream.userID = userID;
          stream.streamID = userID + '_' + streamType;
          stream.hasAudio = hasAudio;
          stream.src = src; // 更新所属 user 的 hasXxx 值

          this.userList.find(item => {
            if (item.userID === userID) {
              item[`has${streamType.replace(/^\S/, s => s.toUpperCase())}Audio`] = hasAudio;
              return true;
            }
          });
          const eventName = hasAudio ? EVENT.REMOTE_AUDIO_ADD : EVENT.REMOTE_AUDIO_REMOVE;

          this._emitter.emit(eventName, {
            stream: stream,
            streamList: this.streamList,
            userList: this.userList
          }); // console.log(TAG_NAME, 'updateUserAudio', user, stream, this.userMap)

        }
      });
    }
  }
  /**
   *
   * @param {String} userID 用户ID
   * @returns {Object}
   */


  getUser(userID) {
    return this.userMap.get(userID);
  }

  getStream({
    userID,
    streamType
  }) {
    const user = this.userMap.get(userID);

    if (user) {
      return user.streams[streamType];
    }

    return undefined;
  }

  getUserList() {
    return this.userList;
  }

  getStreamList() {
    return this.streamList;
  }
  /**
   * 重置所有user 和 steam
   * @returns {Object}
   */


  reset() {
    this.streamList.forEach(item => {
      item.reset();
    });
    this.streamList = [];
    this.userList = [];
    this.userMap.clear();
    return {
      userList: this.userList,
      streamList: this.streamList
    };
  }

  on(eventCode, handler, context) {
    this._emitter.on(eventCode, handler, context);
  }

  off(eventCode, handler) {
    this._emitter.off(eventCode, handler);
  }
  /**
   * 删除用户和所有的 stream
   * @param {String} userID 用户ID
   */


  _removeUserAndStream(userID) {
    this.streamList = this.streamList.filter(item => {
      return item.userID !== userID && item.userID !== '';
    });
    this.userList = this.userList.filter(item => {
      return item.userID !== userID;
    });
  }

  _removeStream(stream) {
    this.streamList = this.streamList.filter(item => {
      if (item.userID === stream.userID && item.streamType === stream.streamType) {
        return false;
      }

      return true;
    });
  }

}

export default UserController;