import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';

import 'config/ice_servers.dart';
import 'controller/remote_controller.dart';
import 'utils/control_commands.dart';
import 'utils/device_utils.dart';
import 'webrtc/self_codec_decoder.dart';
import 'webrtc/video_recorder.dart';
import 'widgets/remote_touch_view.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      title: 'WebRTC 控制端',
      theme: const CupertinoThemeData(primaryColor: CupertinoColors.activeBlue),
      home: const ControllerHome(),
    );
  }
}

class ControllerHome extends StatefulWidget {
  const ControllerHome({super.key});

  @override
  State<ControllerHome> createState() => _ControllerHomeState();
}

class _ControllerHomeState extends State<ControllerHome> {
  /// 与 Windows 原生窗口通信的通道（用于按视频比例调整窗口高度）。
  static const MethodChannel _windowChannel = MethodChannel('app/window');

  /// 记录上一次已应用的视频宽高比，避免重复调整窗口。
  double _lastResizedAspect = 0;

  final _serverUrlController = TextEditingController(
    text: kDefaultSignalServer,
  );
  final _deviceIdController = TextEditingController();
  final _targetController = TextEditingController(text: '981964879');

  RemoteController? _controller;
  RTCVideoRenderer? _renderer;

  bool _connected = false;
  /// 是否正在连接信令服务器 / 建立 WebRTC（连接过程中禁用“连接”按钮）。
  bool _connecting = false;
  String _status = '状态: 已停止';
  String _stats = '';
  double _videoAspect = 16 / 9;

  /// 当前串流模式：0=WebRTC 全托管；1=自编码（自建 MediaCodec 解码）。
  int _streamMode = SelfCodecDecoder.streamModeWebRtc;
  int? _selfCodecTextureId;
  bool _selfCodecReady = false;
  bool _selfCodecSupported = true;

  /// 远程视频录制器（基于 flutter_webrtc 的 MediaRecorder）。
  final VideoRecorder _videoRecorder = VideoRecorder();
  bool _recording = false;
  String _recordStatus = '';
  /// 自编码模式下请求录制时，先切回 WebRTC 标准模式、待就绪后再开始录制。
  bool _pendingRecordStart = false;

  /// 分辨率预设：width 为长边像素；0 表示被控端原生分辨率；
  /// height 传 0（由被控端按屏幕宽高比计算），fps 传 0（沿用当前帧率）。
  int _selectedResolution = 0;
  final List<Map<String, Object>> _resolutionOptions = const [
    {'label': '原始', 'width': 0, 'height': 0, 'fps': 0},
    {'label': '1080P', 'width': 1920, 'height': 0, 'fps': 0},
    {'label': '720P', 'width': 1280, 'height': 0, 'fps': 0},
    {'label': '480P', 'width': 854, 'height': 0, 'fps': 0},
  ];

  /// 帧率档位：默认常用档位，收到被控端上报的 supported_fps 后以上报列表为准。
  List<int> _fpsOptions = const [15, 24, 30, 60];

  /// 被控端当前采集帧率（0 表示尚未收到上报）。
  int _currentFps = 0;

  /// 被控端最近上报的实际采集尺寸（仅切帧率时保持分辨率不变，0 表示原生）。
  int _lastReportedWidth = 0;
  int _lastReportedHeight = 0;

  @override
  void initState() {
    super.initState();
    _initDeviceId();
  }

  /// 异步获取设备标识并填入设备ID输入框（非系统签名，使用兜底方案）。
  Future<void> _initDeviceId() async {
    final id = await DeviceUtils.getSerialNumber();
    if (mounted) {
      setState(() => _deviceIdController.text = id);
    }
  }

  @override
  void dispose() {
    _videoRecorder.dispose();
    _controller?.disconnect();
    _serverUrlController.dispose();
    _deviceIdController.dispose();
    _targetController.dispose();
    super.dispose();
  }

  void _setStatus(String status) => setState(() => _status = status);

  /// 以 iOS 风格弹窗提示用户（替代原 Material 的 SnackBar）。
  void _showAlert(String message) {
    if (!mounted) return;
    showCupertinoDialog<void>(
      context: context,
      builder: (ctx) => CupertinoAlertDialog(
        content: Text(message),
        actions: [
          CupertinoDialogAction(
            child: const Text('确定'),
            onPressed: () => Navigator.of(ctx).pop(),
          ),
        ],
      ),
    );
  }

  Future<void> _showAuthDialog() async {
    final serverUrl = _serverUrlController.text.trim();
    final deviceId = _deviceIdController.text.trim();
    final target = _targetController.text.trim();
    if (serverUrl.isEmpty || deviceId.isEmpty || target.isEmpty) {
      _setStatus('请填写所有字段');
      return;
    }

    String selectedType = 'NONE';
    final valueController = TextEditingController();

    // 纵向选项列表，避免分段控件在窄弹窗中把中文选项挤压成两行。
    Widget buildOption(
      String value,
      String title,
      String desc,
      void Function(void Function()) setDialogState,
    ) {
      final selected = selectedType == value;
      return GestureDetector(
        onTap: () => setDialogState(() => selectedType = value),
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
          margin: const EdgeInsets.only(bottom: 8),
          decoration: BoxDecoration(
            border: Border.all(
              color: selected
                  ? CupertinoColors.activeBlue
                  : CupertinoColors.systemGrey4,
            ),
            borderRadius: BorderRadius.circular(10),
            color: selected
                ? CupertinoColors.activeBlue.withValues(alpha: 0.06)
                : null,
          ),
          child: Row(
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      title,
                      style: const TextStyle(
                        fontSize: 15,
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                    const SizedBox(height: 2),
                    Text(
                      desc,
                      style: const TextStyle(
                        fontSize: 12,
                        color: CupertinoColors.systemGrey,
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(width: 8),
              Icon(
                selected
                    ? CupertinoIcons.check_mark_circled_solid
                    : CupertinoIcons.circle,
                color: selected
                    ? CupertinoColors.activeBlue
                    : CupertinoColors.systemGrey,
              ),
            ],
          ),
        ),
      );
    }

    await showCupertinoDialog<void>(
      context: context,
      builder: (ctx) => StatefulBuilder(
        builder: (ctx, setDialogState) => CupertinoAlertDialog(
          title: const Text('连接鉴权'),
          content: Column(
            children: [
              const SizedBox(height: 12),
              buildOption(
                'NONE',
                '免密连接',
                '被控端弹出手动确认框，无需验证码或密码',
                setDialogState,
              ),
              buildOption(
                'CODE',
                '动态验证码',
                '使用一次性动态验证码鉴权',
                setDialogState,
              ),
              buildOption(
                'PASSWORD',
                '固定密码',
                '使用固定连接密码鉴权',
                setDialogState,
              ),
              const SizedBox(height: 4),
              CupertinoTextField(
                controller: valueController,
                enabled: selectedType != 'NONE',
                placeholder: selectedType == 'NONE'
                    ? '免密连接，无需填写'
                    : selectedType == 'PASSWORD'
                        ? '请输入固定密码'
                        : '请输入动态验证码',
                obscureText: true,
                padding:
                    const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
              ),
            ],
          ),
          actions: [
            CupertinoDialogAction(
              child: const Text('取消'),
              onPressed: () => Navigator.of(ctx).pop(),
            ),
            CupertinoDialogAction(
              child: const Text('连接'),
              onPressed: () {
                final val = valueController.text.trim();
                if (selectedType != 'NONE' && val.isEmpty) {
                  _showAlert('请输入验证码或密码');
                  return;
                }
                Navigator.of(ctx).pop();
                _connect(
                  authType: selectedType,
                  authValue: selectedType == 'NONE' ? '' : val,
                );
              },
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _connect({required String authType, required String authValue}) async {
    final serverUrl = _serverUrlController.text.trim();
    final deviceId = _deviceIdController.text.trim();
    final target = _targetController.text.trim();

    if (serverUrl.isEmpty || deviceId.isEmpty || target.isEmpty) {
      _setStatus('请填写所有字段');
      return;
    }

    setState(() => _connecting = true);
    _setStatus('状态: 正在连接信令服务器...');

    _controller = RemoteController(
      serverUrl: serverUrl,
      deviceId: deviceId,
      targetDeviceId: target,
      authType: authType,
      authValue: authValue,
    );
    _controller!.onStatusChanged = _setStatus;
    _controller!.onConnectionEstablished = () {
      setState(() {
        _connected = true;
        _connecting = false;
        _status = '状态: 已连接 - 远程控制中';
      });
    };
    _controller!.onConnectionFailed = (error) {
      if (mounted) setState(() => _connecting = false);
      _showAlert('连接失败：$error');
    };
    _controller!.onDisconnected = () {
      setState(() {
        _connected = false;
        _connecting = false;
      });
      _setStatus('状态: 远端已断开');
    };
    _controller!.onIceDisconnected = (message) {
      _onIceDisconnected(message);
    };
    _controller!.onTargetOffline = (message) {
      _onTargetOffline(message);
    };
    _controller!.onConnectionRejected = (message) {
      _onConnectionRejected(message);
    };
    _controller!.onRemoteStream = (renderer) {
      setState(() => _renderer = renderer);
      renderer.addListener(_onRendererUpdate);
      if (_pendingRecordStart) {
        _pendingRecordStart = false;
        _startRecording();
      }
    };
    _controller!.onStats = (stats) => setState(() => _stats = stats);
    _controller!.onSelfCodecReady = (textureId) {
      if (mounted) {
        setState(() {
          _selfCodecTextureId = textureId;
          _selfCodecReady = true;
        });
      }
    };
    _controller!.onSelfCodecLost = () {
      if (mounted) {
        setState(() {
          _selfCodecReady = false;
          _selfCodecTextureId = null;
        });
      }
    };
    _controller!.onStreamModeReport = (mode) {
      if (mounted) setState(() => _streamMode = mode);
      if (mode == SelfCodecDecoder.streamModeWebRtc && _pendingRecordStart) {
        _pendingRecordStart = false;
        _startRecording();
      }
    };
    _controller!.onResolutionReported = (w, h) {
      if (w > 0 && h > 0 && mounted) {
        final aspect = w / h;
        setState(() => _videoAspect = aspect);
        _resizeWindowToAspect(aspect);
      }
    };
    // 被控端上报当前帧率与支持的帧率档位 -> 同步帧率菜单
    _controller!.onFpsReport = (w, h, fps, supportedFps) {
      if (!mounted) return;
      setState(() {
        if (w > 0) _lastReportedWidth = w;
        if (h > 0) _lastReportedHeight = h;
        if (fps > 0) _currentFps = fps;
        if (supportedFps.isNotEmpty) _fpsOptions = supportedFps;
      });
    };
    _controller!.onSelfCodecNotSupported = () {
      if (mounted) setState(() => _selfCodecSupported = false);
      _showAlert('当前平台不支持自编码硬解，已回退到 WebRTC 媒体流。');
    };

    _controller!.connect(authType: authType, authValue: authValue);
  }

  void _onRendererUpdate() {
    final w = _renderer?.value.width ?? 0;
    final h = _renderer?.value.height ?? 0;
    if (w > 0 && h > 0 && mounted) {
      final aspect = w / h;
      setState(() => _videoAspect = aspect);
      _resizeWindowToAspect(aspect);
    }
  }

  /// Windows 端：保持窗口宽度不变，按视频宽高比调整窗口高度；
  /// 若高度超出屏幕，由原生端改为合适的窗口大小。
  void _resizeWindowToAspect(double aspect) {
    if (kIsWeb || defaultTargetPlatform != TargetPlatform.windows) return;
    if (aspect <= 0) return;
    if ((aspect - _lastResizedAspect).abs() < 0.001) return;
    _lastResizedAspect = aspect;
    _windowChannel.invokeMethod('resizeToVideoAspect', aspect);
  }

  /// ICE 断开：提示用户并自动返回连接设置面板。
  Future<void> _onIceDisconnected(String message) async {
    _showAlert(message);
    await _disconnect();
  }

  /// 目标被控端不在线：提示用户并复位到连接设置面板。
  Future<void> _onTargetOffline(String message) async {
    _showAlert(message);
    setState(() {
      _connected = false;
      _connecting = false;
    });
  }

  /// 被控端拒绝连接请求：提示用户并复位到连接设置面板。
  Future<void> _onConnectionRejected(String message) async {
    _showAlert(message);
    setState(() {
      _connected = false;
      _connecting = false;
    });
  }

  /// 弹出分辨率选择菜单（iOS 风格 ActionSheet）。
  void _showResolutionMenu() {
    showCupertinoModalPopup<void>(
      context: context,
      builder: (ctx) => CupertinoActionSheet(
        title: const Text('切换分辨率'),
        actions: [
          for (int i = 0; i < _resolutionOptions.length; i++)
            CupertinoActionSheetAction(
              onPressed: () {
                Navigator.of(ctx).pop();
                setState(() => _selectedResolution = i);
                final o = _resolutionOptions[i];
                _controller?.sendResolutionChange(
                  o['width'] as int,
                  o['height'] as int,
                  o['fps'] as int,
                );
              },
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  if (i == _selectedResolution) ...[
                    const Icon(CupertinoIcons.check_mark,
                        size: 18, color: CupertinoColors.activeBlue),
                    const SizedBox(width: 8),
                  ],
                  Text(_resolutionOptions[i]['label'] as String),
                ],
              ),
            ),
        ],
        cancelButton: CupertinoActionSheetAction(
          isDefaultAction: true,
          onPressed: () => Navigator.of(ctx).pop(),
          child: const Text('取消'),
        ),
      ),
    );
  }

  /// 弹出帧率选择菜单（iOS 风格 ActionSheet）；仅切帧率，分辨率保持不变。
  void _showFpsMenu() {
    showCupertinoModalPopup<void>(
      context: context,
      builder: (ctx) => CupertinoActionSheet(
        title: const Text('切换帧率'),
        actions: [
          for (final fps in _fpsOptions)
            CupertinoActionSheetAction(
              onPressed: () {
                Navigator.of(ctx).pop();
                if (fps <= 0 || fps == _currentFps) return;
                // 分辨率沿用被控端最近上报的实际采集尺寸（0 表示原生）
                _controller?.sendResolutionChange(
                  _lastReportedWidth,
                  _lastReportedHeight,
                  fps,
                );
              },
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  if (fps == _currentFps) ...[
                    const Icon(CupertinoIcons.check_mark,
                        size: 18, color: CupertinoColors.activeBlue),
                    const SizedBox(width: 8),
                  ],
                  Text('${fps}fps'),
                ],
              ),
            ),
        ],
        cancelButton: CupertinoActionSheetAction(
          isDefaultAction: true,
          onPressed: () => Navigator.of(ctx).pop(),
          child: const Text('取消'),
        ),
      ),
    );
  }

  /// 切换串流模式：WebRTC 全托管 <-> 自编码（自建 MediaCodec 解码）。
  void _toggleStreamMode() {
    if (!_selfCodecSupported) {
      _showAlert('当前平台不支持自编码硬解。');
      return;
    }
    final next = _streamMode == SelfCodecDecoder.streamModeSelfCodec
        ? SelfCodecDecoder.streamModeWebRtc
        : SelfCodecDecoder.streamModeSelfCodec;
    setState(() => _streamMode = next);
    _controller?.sendStreamMode(next);
  }

  /// 切换远程视频录制：开始 / 停止。
  Future<void> _toggleRecord() async {
    if (_recording) {
      await _stopRecording();
      return;
    }
    if (_renderer == null) {
      _showAlert('尚未连接或没有视频画面，无法录制');
      return;
    }
    if (_streamMode == SelfCodecDecoder.streamModeSelfCodec) {
      // 自编码模式下没有 WebRTC 视频轨道，先切回标准模式再开始录制。
      _pendingRecordStart = true;
      setState(() => _recordStatus = '正在切回标准模式以开始录制...');
      _controller?.sendStreamMode(SelfCodecDecoder.streamModeWebRtc);
      return;
    }
    await _startRecording();
  }

  /// 开始录制当前远端视频轨道。
  Future<void> _startRecording() async {
    if (_recording || !mounted) return;
    final stream = _renderer?.srcObject;
    if (stream == null) {
      _showAlert('尚未接收到视频画面，无法录制');
      return;
    }
    try {
      final ok = await _videoRecorder.start(stream);
      if (ok && mounted) {
        setState(() {
          _recording = true;
          _recordStatus = '录制中...';
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() => _recordStatus = '');
        _showAlert('开始录制失败：$e');
      }
    }
  }

  /// 停止录制并提示保存位置。
  Future<void> _stopRecording() async {
    final path = await _videoRecorder.stop();
    if (mounted) {
      setState(() {
        _recording = false;
        _recordStatus = path != null ? '已保存：$path' : '录制已停止';
      });
    }
  }

  Future<void> _disconnect() async {
    await _videoRecorder.dispose();
    await _controller?.disconnect();
    _controller = null;
    _renderer?.removeListener(_onRendererUpdate);
    _lastResizedAspect = 0;
    setState(() {
      _connected = false;
      _connecting = false;
      _renderer = null;
      _status = '状态: 已停止';
      _stats = '';
      _streamMode = SelfCodecDecoder.streamModeWebRtc;
      _selfCodecTextureId = null;
      _selfCodecReady = false;
      _selfCodecSupported = true;
      _recording = false;
      _recordStatus = '';
      _pendingRecordStart = false;
      _currentFps = 0;
      _lastReportedWidth = 0;
      _lastReportedHeight = 0;
      _fpsOptions = const [15, 24, 30, 60];
    });
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      // 控制模式（已连接）下隐藏导航栏，避免其半透明浮层遮挡顶部的
      // 状态/统计信息浮层；连接设置面板再显示标题栏。
      navigationBar: _connected
          ? null
          : const CupertinoNavigationBar(
              middle: Text('WebRTC 控制端'),
            ),
      child: _connected ? _buildControlPanel() : _buildSetupPanel(),
    );
  }

  Widget _buildSetupPanel() {
    return SafeArea(
      child: SingleChildScrollView(
        padding: const EdgeInsets.all(24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              'WebRTC 控制端',
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 24),
            const Text('信令服务器地址:', style: TextStyle(fontSize: 14)),
            const SizedBox(height: 8),
            CupertinoTextField(
              controller: _serverUrlController,
              placeholder: 'wss://www.ttstd.com/signal',
              padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
            ),
            const SizedBox(height: 16),
            const Text('本机设备ID:', style: TextStyle(fontSize: 14)),
            const SizedBox(height: 8),
            CupertinoTextField(
              controller: _deviceIdController,
              placeholder: '设备ID',
              padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
            ),
            const SizedBox(height: 16),
            const Text('目标被控设备ID:', style: TextStyle(fontSize: 14)),
            const SizedBox(height: 8),
            CupertinoTextField(
              controller: _targetController,
              placeholder: '被控端设备ID',
              padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
            ),
            const SizedBox(height: 24),
            Text(
              _status,
              style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 24),
            SizedBox(
              width: double.infinity,
              child: CupertinoButton.filled(
                onPressed: _connecting ? null : _showAuthDialog,
                child: Text(_connecting ? '正在连接...' : '连接被控设备'),
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// 右上角浮动顶部菜单栏：整合「分辨率切换」与「断开连接」。
  Widget _buildTopMenuBar() {
    return Container(
      decoration: BoxDecoration(
        color: Colors.black54,
        borderRadius: BorderRadius.circular(22),
      ),
      padding: const EdgeInsets.symmetric(horizontal: 4),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          // 分辨率菜单按钮：显示当前分辨率标签
          CupertinoButton(
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
            onPressed: _showResolutionMenu,
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Icon(CupertinoIcons.slider_horizontal_3,
                    color: CupertinoColors.white, size: 20),
                const SizedBox(width: 6),
                Text(
                  _resolutionOptions[_selectedResolution]['label'] as String,
                  style: const TextStyle(
                    color: CupertinoColors.white,
                    fontSize: 14,
                  ),
                ),
              ],
            ),
          ),
          // 帧率菜单按钮：显示被控端当前采集帧率
          CupertinoButton(
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
            onPressed: _showFpsMenu,
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Icon(CupertinoIcons.speedometer,
                    color: CupertinoColors.white, size: 20),
                const SizedBox(width: 6),
                Text(
                  _currentFps > 0 ? '${_currentFps}fps' : '帧率',
                  style: const TextStyle(
                    color: CupertinoColors.white,
                    fontSize: 14,
                  ),
                ),
              ],
            ),
          ),
          // 自编码串流开关：仅 Android 等支持原生硬解的平台可用。
          CupertinoButton(
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
            onPressed: _selfCodecSupported ? _toggleStreamMode : null,
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(
                  '自编码',
                  style: TextStyle(
                    color: _selfCodecSupported
                        ? CupertinoColors.white
                        : CupertinoColors.white.withValues(alpha: 0.4),
                    fontSize: 14,
                  ),
                ),
                const SizedBox(width: 6),
                CupertinoSwitch(
                  value: _streamMode == SelfCodecDecoder.streamModeSelfCodec,
                  onChanged: _selfCodecSupported
                      ? (_) => _toggleStreamMode()
                      : null,
                  activeTrackColor: CupertinoColors.activeBlue,
                ),
              ],
            ),
          ),
          // 远程视频录制开关
          CupertinoButton(
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
            onPressed: _toggleRecord,
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(
                  _recording
                      ? CupertinoIcons.stop_circle
                      : CupertinoIcons.video_camera,
                  color: _recording
                      ? CupertinoColors.destructiveRed
                      : CupertinoColors.white,
                  size: 20,
                ),
                const SizedBox(width: 6),
                Text(
                  _recording ? '停止' : '录制',
                  style: const TextStyle(
                    color: CupertinoColors.white,
                    fontSize: 14,
                  ),
                ),
              ],
            ),
          ),
          // 分隔线
          Container(
            width: 1,
            height: 22,
            color: CupertinoColors.white.withValues(alpha: 0.3),
          ),
          // 断开连接按钮
          CupertinoButton(
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
            onPressed: _disconnect,
            child: const Icon(
              CupertinoIcons.xmark_circle_fill,
              color: CupertinoColors.destructiveRed,
              size: 24,
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildControlPanel() {
    return SafeArea(
      // 仅保留顶部安全区（避开系统状态栏），底部/左右保持全屏，
      // 以便右下角的断开按钮贴近屏幕边缘。
      top: true,
      bottom: false,
      left: false,
      right: false,
      child: Stack(
      children: [
        Container(color: Colors.black),
        if (_streamMode == SelfCodecDecoder.streamModeSelfCodec &&
            _selfCodecReady &&
            _selfCodecTextureId != null)
          Center(
            child: AspectRatio(
              aspectRatio: _videoAspect,
              child: Stack(
                fit: StackFit.expand,
                children: [
                  Texture(textureId: _selfCodecTextureId!),
                  RemoteTouchView(
                    onTouch: (x, y) {},
                    onSwipe: (x1, y1, x2, y2, d) {},
                    onLongPress: (x, y) {},
                    onKey: (k, a) =>
                        _controller?.sendControlCommand(ControlCommands.key(k, a)),
                    onMotionEvent: (a, x, y) => _controller?.sendControlCommand(
                      ControlCommands.motionEvent(a, x, y),
                    ),
                  ),
                ],
              ),
            ),
          )
        else if (_renderer != null)
          Center(
            child: AspectRatio(
              aspectRatio: _videoAspect,
              child: Stack(
                fit: StackFit.expand,
                children: [
                  RTCVideoView(
                    _renderer!,
                    objectFit:
                        RTCVideoViewObjectFit.RTCVideoViewObjectFitContain,
                  ),
                  RemoteTouchView(
                    // 禁用离散的 TOUCH/SWIPE/LONG_PRESS 指令，改用实时的 onMotionEvent 以解决重复操作问题。
                    // 原始的动作流已包含完整的触摸过程，被控端系统会自动识别单击、滑动和长按。
                    onTouch: (x, y) {},
                    onSwipe: (x1, y1, x2, y2, d) {},
                    onLongPress: (x, y) {},
                    onKey: (k, a) => _controller?.sendControlCommand(
                      ControlCommands.key(k, a),
                    ),
                    onMotionEvent: (a, x, y) => _controller?.sendControlCommand(
                      ControlCommands.motionEvent(a, x, y),
                    ),
                  ),
                ],
              ),
            ),
          ),
        Positioned(
          top: 0,
          left: 0,
          child: Container(
            color: Colors.black54,
            padding: const EdgeInsets.all(8),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(_status, style: const TextStyle(color: Colors.white)),
                Text(
                  _stats,
                  style: const TextStyle(color: Colors.white, fontSize: 12),
                ),
                if (_recordStatus.isNotEmpty)
                  Text(
                    _recordStatus,
                    style: const TextStyle(
                      color: CupertinoColors.systemOrange,
                      fontSize: 12,
                    ),
                  ),
              ],
            ),
          ),
        ),
        Positioned(
          top: 8,
          right: 8,
          child: _buildTopMenuBar(),
        ),
      ],
      ),
    );
  }
}
