import 'dart:collection';

import 'package:fis_common/event/event_type.dart';
import 'package:fis_lib_media_rt/interface/index.dart';

import '../utils/id_generator.dart';
import 'channel.dart';

/// 本地成员
class LocalMember extends BaseMember {
  /// 参数
  final ILocalMemberParams params;

  LocalMember({required this.params});

  @override
  String? get userId => params.userId;
}

/// 本地成员参数
class LocalMemberParams implements ILocalMemberParams {
  final Map<String, dynamic> _params = {};

  /// 本地成员参数
  ///
  /// [userId] 用户ID
  ///
  /// [userSig] 用户签名
  ///
  /// [extParams] 扩展参数
  LocalMemberParams({
    String? userId,
    String? userSig,
    Map<String, dynamic>? extParams,
  }) {
    _params['userId'] = userId;
    _params['userSig'] = userSig;
  }

  /// 用户ID
  @override
  String? get userId => _params['userId'];

  /// 用户签名
  @override
  String? get userSig => _params['userSig'];

  /// 获取参数值
  @override
  dynamic getParam(String paramKey) {
    return _params[paramKey];
  }
}

/// 访客成员，不参与实际会话
class VisitorMember extends RemoteMember {
  VisitorMember({super.userId});

  @override
  MemberRoleType get roleType => MemberRoleType.visitor;
}

/// 远端成员
abstract class RemoteMember extends BaseMember {
  late final String? _userId;

  RemoteMember({
    String? userId,
  }) {
    _userId = userId;
  }

  @override
  String? get userId => _userId;
}

/// 成员
abstract class BaseMember implements IMember {
  static final IDGenerator _idGenerator = IDGenerator();

  late final String _id;
  final List<BaseChannel> _channels = [];

  BaseMember() {
    _id = _idGenerator.generate();
  }

  final channelAdded = FEventHandler<BaseChannel>();
  final channelRemoved = FEventHandler<BaseChannel>();

  @override
  String get id => _id;

  @override
  MemberRoleType get roleType => MemberRoleType.normal;

  /// 用户ID
  String? get userId;

  /// 视频路
  UnmodifiableListView<BaseChannel> get channels =>
      UnmodifiableListView(_channels);

  void addChannel(BaseChannel channel) {
    _channels.add(channel);
    channelAdded.emit(this, channel);
  }

  void removeChannel(BaseChannel channel) {
    _channels.remove(channel);
    channelRemoved.emit(this, channel);
  }

  void clearChannels() {
    final len = _channels.length;
    for (int i = len - 1; i >= 0; i--) {
      final channel = _channels.removeAt(i);
      channelRemoved.emit(this, channel);
    }
  }
}
