import 'dart:async';

/// 一对一语音会话防护：占线、超时、重复信令、销毁时释放计时器。
/// 不自建第二套信令，只约束官方 OpenIMLive 的进出场。
enum VoiceCallPhase { idle, outgoing, incoming, inCall }

class CallSessionGuard {
  CallSessionGuard({this.inviteTimeout = const Duration(seconds: 30)});

  final Duration inviteTimeout;

  VoiceCallPhase phase = VoiceCallPhase.idle;
  String? roomID;
  void Function()? onTimeout;

  final Set<String> _seenKeys = <String>{};
  Timer? _timeout;

  bool get isBusy => phase != VoiceCallPhase.idle;

  bool acceptSignaling({required int customType, required String roomID}) {
    if (roomID.isEmpty) return false;
    return _seenKeys.add('$customType:$roomID');
  }

  String? startOutgoing(String roomID) {
    if (isBusy) return 'busy';
    this.roomID = roomID;
    phase = VoiceCallPhase.outgoing;
    _armTimeout();
    return null;
  }

  String? startIncoming(String roomID) {
    if (isBusy) return 'busy';
    this.roomID = roomID;
    phase = VoiceCallPhase.incoming;
    _armTimeout();
    return null;
  }

  void markConnected() {
    if (!isBusy) return;
    _timeout?.cancel();
    _timeout = null;
    phase = VoiceCallPhase.inCall;
  }

  bool sameRoom(String? other) =>
      other != null && other.isNotEmpty && other == roomID;

  void dispose() {
    _timeout?.cancel();
    _timeout = null;
    _seenKeys.clear();
    phase = VoiceCallPhase.idle;
    roomID = null;
    onTimeout = null;
  }

  void _armTimeout() {
    _timeout?.cancel();
    _timeout = Timer(inviteTimeout, () {
      if (phase == VoiceCallPhase.outgoing || phase == VoiceCallPhase.incoming) {
        onTimeout?.call();
      }
    });
  }
}
