import 'dart:collection';

import 'package:fis_common/event/event_type.dart';
import 'package:fis_lib_media_rt/base/member.dart';
import 'package:flutter/foundation.dart';

import '../interface/member.dart';
import '../interface/room.dart';

/// 会话房间
abstract class BaseRoom implements IRoom {
  final List<RemoteMember> _remoteMembers = [];
  late final String _roomId;
  late IMember _localMember;
  bool _isEntered = false;

  /// 会话房间
  ///
  /// [id] 房间号
  ///
  /// [member] 本地成员
  BaseRoom({String id = ""}) {
    _roomId = id;
    memberLeaved = FEventHandler<IMember>();
    memberJoined = FEventHandler<IMember>();
    exited = FEventHandler<void>();
    entered = FEventHandler<void>();
    errorOccurred = FEventHandler<Object>();
  }

  @override
  UnmodifiableListView<RemoteMember> get remoteMembers =>
      UnmodifiableListView(_remoteMembers);

  @override
  LocalMember get localMember => _localMember as LocalMember;
  @protected
  set localMember(LocalMember val) {
    _localMember = val;
  }

  @override
  String get roomId => _roomId;

  @override
  bool get isEntered => _isEntered;
  set isEntered(bool value) => _isEntered = value;

  @override
  late final FEventHandler<Object> errorOccurred;

  @override
  late final FEventHandler<void> exited;

  @override
  late final FEventHandler<void> entered;

  @override
  late final FEventHandler<IMember> memberJoined;

  @override
  late final FEventHandler<IMember> memberLeaved;

  @override
  Future<void> kickMember(String memberId) async {
    _remoteMembers.removeWhere((e) => e.id == memberId);
  }

  @override
  void loadLocalMember(ILocalMemberParams params) {
    _localMember = LocalMember(params: params);
  }

  @protected
  bool addMember(RemoteMember member) {
    if (member.userId != null &&
        _remoteMembers.any((e) => e.userId == member.userId)) {
      // 存在相同UserId成员
      return false;
    }
    _remoteMembers.add(member);
    return true;
  }

  @protected
  void removeMember(RemoteMember member) {
    _remoteMembers.remove(member);
  }

  @protected
  void removeMemberAt(int index) {
    _remoteMembers.removeAt(index);
  }
}
