import 'dart:async';
import 'dart:convert';

import 'package:flutter_webrtc/flutter_webrtc.dart';

import '../models/signal_message.dart';
import '../proto/control_message.pb.dart';
import '../signaling/signaling_client.dart';
import '../webrtc/webrtc_controller.dart';

/// 控制端编排器：组合信令客户端与 WebRTC 控制器，
/// 对外暴露连接/断开/发送指令等高层接口（对应 Android 端 MainActivity 的流程）。
class RemoteController {
  final String serverUrl;
  final String deviceId;
  final String targetDeviceId;
  String? authType;
  String? authValue;

  late final SignalingClient _signaling;
  WebRtcController? _webRtc;
  Timer? _statsTimer;

  /// 信令状态变化（如“正在连接…”、“已连接…”）。
  void Function(String status)? onStatusChanged;

  /// WebRTC 连接建立（可开始远程控制）。
  void Function()? onConnectionEstablished;

  /// 连接失败。
  void Function(String error)? onConnectionFailed;

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

  /// ICE 连接断开（用于提示用户并返回连接设置）。
  void Function(String message)? onIceDisconnected;

  /// 目标被控端不在线（服务器回送 TARGET_OFFLINE，用于提示用户并复位 UI）。
  void Function(String message)? onTargetOffline;

  /// 被控端拒绝了连接请求（用于提示用户并复位 UI）。
  void Function(String message)? onConnectionRejected;

  /// 远端视频渲染器就绪。
  void Function(RTCVideoRenderer renderer)? onRemoteStream;

  /// 统计信息刷新（每秒一次）。
  void Function(String stats)? onStats;

  /// 自编码解码纹理已就绪（textureId >= 0）。
  void Function(int textureId)? onSelfCodecReady;

  /// 自编码解码器已释放（连接断开时）。
  void Function()? onSelfCodecLost;

  /// 被控端上报当前生效的串流模式。
  void Function(int mode)? onStreamModeReport;

  /// 被控端/解码器上报分辨率。
  void Function(int width, int height)? onResolutionReported;

  /// 被控端上报当前采集帧率与支持的帧率档位。
  void Function(int width, int height, int fps, List<int> supportedFps)?
      onFpsReport;

  /// 当前平台不支持原生硬解时回调。
  void Function()? onSelfCodecNotSupported;

  RemoteController({
    required this.serverUrl,
    required this.deviceId,
    required this.targetDeviceId,
    this.authType,
    this.authValue,
  });

  /// 发起连接：先连接信令服务器，成功后建立 WebRTC 并创建 Offer。
  void connect({String? authType, String? authValue}) {
    this.authType = authType;
    this.authValue = authValue;
    onStatusChanged?.call('状态: 正在连接信令服务器...');

    _signaling = SignalingClient(serverUrl: serverUrl, deviceId: deviceId);
    _signaling.onConnected = () {
      onStatusChanged?.call('状态: 已连接信令服务器，正在发起连接...');
      _initWebRtc();
    };
    _signaling.onMessage = _handleSignalMessage;
    _signaling.onDisconnected = () {
      onStatusChanged?.call('状态: 已断开连接');
      onDisconnected?.call();
    };
    _signaling.onError = (error) {
      onStatusChanged?.call('状态: 连接错误 - $error');
      onConnectionFailed?.call(error);
    };
    _signaling.connect();
  }

  void _initWebRtc() {
    _webRtc = WebRtcController(
      signaling: _signaling,
      deviceId: deviceId,
      targetDeviceId: targetDeviceId,
      authType: authType,
      authValue: authValue,
    );
    _webRtc!.onConnectionEstablished = () {
      onConnectionEstablished?.call();
      _startStats();
    };
    _webRtc!.onConnectionFailed = (error) => onConnectionFailed?.call(error);
    _webRtc!.onDisconnected = () {
      onDisconnected?.call();
    };
    _webRtc!.onIceDisconnected = (message) => onIceDisconnected?.call(message);
    _webRtc!.onRemoteStream = (renderer) => onRemoteStream?.call(renderer);
    _webRtc!.onSelfCodecReady = (id) => onSelfCodecReady?.call(id);
    _webRtc!.onSelfCodecLost = () => onSelfCodecLost?.call();
    _webRtc!.onStreamModeReport = (mode) => onStreamModeReport?.call(mode);
    _webRtc!.onResolutionReported = (w, h) => onResolutionReported?.call(w, h);
    _webRtc!.onFpsReport =
        (w, h, fps, list) => onFpsReport?.call(w, h, fps, list);
    _webRtc!.onSelfCodecNotSupported = () => onSelfCodecNotSupported?.call();
    _webRtc!.initialize().catchError((e) {
      onStatusChanged?.call('状态: 连接失败 - $e');
      onConnectionFailed?.call(e.toString());
    });
  }

  void _handleSignalMessage(SignalMessage message) {
    switch (message.type?.toUpperCase()) {
      case 'ANSWER':
        final payload = jsonDecode(message.payload!) as Map<String, dynamic>;
        // 被控端已接受连接请求，进入 WebRTC 协商阶段。
        onStatusChanged?.call('状态: 被控端已接受连接，正在建立连接...');
        _webRtc?.handleAnswer(payload['sdp'] as String);
        break;
      case 'ICE_CANDIDATE':
        final payload = jsonDecode(message.payload!) as Map<String, dynamic>;
        _webRtc?.handleIceCandidate(payload);
        break;
      case 'TARGET_OFFLINE':
        final text = message.payload ?? '目标被控端不在线，请确认设备已开启并连接服务器';
        onStatusChanged?.call('状态: $text');
        onTargetOffline?.call(text);
        break;
      case 'CONNECTION_REJECTED':
      case 'REQUEST_ERROR':
      case 'REQUEST_TIMEOUT':
        final text = _parseRejectReason(message.payload);
        onStatusChanged?.call('状态: $text');
        onConnectionRejected?.call(text);
        break;
    }
  }

  /// 解析拒绝原因：优先读取 JSON 中的 reason 字段，否则直接返回原文。
  String _parseRejectReason(String? payload) {
    if (payload == null || payload.isEmpty) return '连接请求失败';
    try {
      final map = jsonDecode(payload) as Map<String, dynamic>;
      final r = map['reason'];
      if (r is String && r.isNotEmpty) return r;
    } catch (_) {}
    return payload;
  }

  void _startStats() {
    _statsTimer?.cancel();
    _statsTimer = Timer.periodic(const Duration(seconds: 1), (_) async {
      final text = await _webRtc?.getStatsText();
      if (text != null && text.isNotEmpty) {
        onStats?.call(text);
      }
    });
  }

  /// 发送控制指令（protobuf 二进制）。
  void sendControlCommand(ControlMessage command) {
    _webRtc?.sendControlCommand(command);
  }

  /// 请求被控端切换屏幕采集分辨率。
  void sendResolutionChange(int width, int height, int fps) {
    _webRtc?.sendResolutionChange(width, height, fps);
  }

  /// 请求被控端切换屏幕串流模式（0=WebRTC 全托管 / 1=自编码）。
  Future<void> sendStreamMode(int mode) =>
      _webRtc?.sendStreamMode(mode) ?? Future.value();

  /// 断开连接并释放资源。
  Future<void> disconnect() async {
    _statsTimer?.cancel();
    _statsTimer = null;
    await _webRtc?.close();
    _webRtc = null;
    _signaling.disconnect();
  }
}
