import 'dart:convert';

import 'package:web_socket_channel/web_socket_channel.dart';

import '../models/signal_message.dart';

/// 信令客户端，封装 WebSocket 连接与消息收发。
///
/// 连接成功后自动向服务器发送 REGISTER 注册为 CONTROLLER 设备，
/// 与 Android 端 WebSocketClient 行为一致。
class SignalingClient {
  final String serverUrl;
  final String deviceId;

  WebSocketChannel? _channel;

  /// 收到信令消息回调（已解析为 SignalMessage）。
  void Function(SignalMessage message)? onMessage;

  /// 连接成功回调。
  void Function()? onConnected;

  /// 连接断开回调。
  void Function()? onDisconnected;

  /// 连接错误回调。
  void Function(String error)? onError;

  SignalingClient({required this.serverUrl, required this.deviceId});

  /// 建立 WebSocket 连接并注册设备。
  void connect() {
    try {
      final uri = Uri.parse(serverUrl);
      _channel = WebSocketChannel.connect(uri);

      _channel!.stream.listen(
        _onData,
        onDone: () => onDisconnected?.call(),
        onError: (Object e) => onError?.call(e.toString()),
        cancelOnError: false,
      );

      // 连接建立后注册设备（与 Android 端 onOpen -> registerDevice 对应）。
      _register();
    } catch (e) {
      onError?.call(e.toString());
    }
  }

  void _onData(dynamic data) {
    if (data is! String) return;
    try {
      final map = jsonDecode(data) as Map<String, dynamic>;
      final message = SignalMessage.fromJson(map);
      onMessage?.call(message);
    } catch (_) {
      // 忽略无法解析的消息。
    }
  }

  void _register() {
    final msg = SignalMessage(
      type: 'REGISTER',
      fromDeviceId: deviceId,
      deviceType: 'CONTROLLER',
    );
    _send(msg);
    // 通知上层已“连接”（WebSocketChannel 会缓冲发送，直到底层连接就绪）；
    // 后续 OFFER 等消息会排在 REGISTER 之后发送，保证服务器先完成注册。
    onConnected?.call();
  }

  /// 发送信令消息。
  void send(SignalMessage message) => _send(message);

  void _send(SignalMessage message) {
    _channel?.sink.add(jsonEncode(message.toJson()));
  }

  /// 关闭连接。
  void disconnect() {
    _channel?.sink.close();
    _channel = null;
  }

  bool get isConnected => _channel != null;
}
