import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:vsdk/app_player.dart';
import 'package:vsdk/camera_device/camera_device.dart';
import 'package:vsdk/camera_device/commands/video_command.dart';

/// P2P 视频服务连接状态
enum P2pServiceState {
  /// 未连接
  disconnected,

  /// 正在连接（含 P2P 穿透 + 设备登录 + 视频流启动）
  connecting,

  /// 已连接，视频流播放中
  connected,

  /// 连接失败
  failed,
}

/// P2P 视频服务层
///
/// 职责：
/// - 封装 [CameraDevice] 的 P2P 连接生命周期
/// - 管理 [AppPlayerController] 实例（视频解码 + Texture 渲染）
/// - 向上层暴露连接状态流和播放控制器
///
/// 涉及页面：首页监护舱 - 监控画面
class P2pVideoService {
  /// P2P 摄像头设备实例
  CameraDevice? _cameraDevice;

  /// 视频播放控制器（供 [AppPlayerView] 使用）
  /// stop() 只停止播放不 dispose，保持 Texture widget 存活
  AppPlayerController? _playerController;

  /// 连接状态广播流
  final StreamController<P2pServiceState> _stateController =
      StreamController<P2pServiceState>.broadcast();

  /// 连接状态流（供 UI 层订阅）
  Stream<P2pServiceState> get stateStream => _stateController.stream;

  P2pServiceState _currentState = P2pServiceState.disconnected;

  /// 当前连接状态
  P2pServiceState get currentState => _currentState;

  /// 获取视频播放控制器
  AppPlayerController? get playerController => _playerController;

  // ==================== 公共接口 ====================

  /// 初始化 P2P 连接并启动视频流
  ///
  /// [deviceId] 设备序列号（与 WebRTC 使用相同的 deviceNo）
  /// [username] 设备登录用户名，默认 'admin'
  /// [password] 设备登录密码
  /// [model] 设备型号，默认 'wifi'
  Future<void> connect({
    required String deviceId,
    String username = 'admin',
    required String password,
    String model = 'wifi',
  }) async {
    _updateState(P2pServiceState.connecting);

    try {
      // 1. 清理上一次 CameraDevice 残留
      await _cleanupCamera();

      // 2. 创建 CameraDevice 并监听连接状态
      _cameraDevice = CameraDevice(deviceId, 'camera', username, password, model);
      _cameraDevice!.addListener<CameraConnectChanged>(_onConnectChanged);

      // 3. 发起 P2P 连接（内部完成：创建客户端 → P2P 穿透 → 登录）
      final result = await _cameraDevice!.connect();
      debugPrint('[P2pVideoService] P2P connect 结果: $result');

      if (result != CameraConnectState.connected) {
        debugPrint('[P2pVideoService] 连接失败: $result');
        _updateState(P2pServiceState.failed);
        return;
      }

      // 4. 复用现有播放器或创建新播放器
      final bool needCreate = _playerController == null;
      if (needCreate) {
        _playerController = AppPlayerController();
        final created = await _playerController!.create(
          audioRate: 8000,
          hardware: 1,
        );
        if (!created) {
          debugPrint('[P2pVideoService] 播放器创建失败');
          _updateState(P2pServiceState.failed);
          return;
        }
      }

      // 5. 获取 clientPtr 并绑定视频源
      final clientPtr = await _cameraDevice!.getClientPtr();
      if (clientPtr == 0) {
        debugPrint('[P2pVideoService] clientPtr 无效: $clientPtr');
        _updateState(P2pServiceState.failed);
        return;
      }

      final sourceSet = await _playerController!.setVideoSource(
        LiveVideoSource(clientPtr),
      );
      if (!sourceSet) {
        debugPrint('[P2pVideoService] 视频源绑定失败');
        _updateState(P2pServiceState.failed);
        return;
      }

      // 6. 开启直播流
      final streamStarted = await _cameraDevice!.startStream(
        resolution: VideoResolution.general,
      );
      if (!streamStarted) {
        debugPrint('[P2pVideoService] 直播流启动失败');
        _updateState(P2pServiceState.failed);
        return;
      }

      // 7. 启动播放
      final started = await _playerController!.start();
      if (!started) {
        debugPrint('[P2pVideoService] 播放器启动失败');
        _updateState(P2pServiceState.failed);
        return;
      }

      _updateState(P2pServiceState.connected);
      debugPrint('[P2pVideoService] P2P 视频连接建立完成');
    } catch (e) {
      debugPrint('[P2pVideoService] 连接异常: $e');
      _updateState(P2pServiceState.failed);
    }
  }

  /// 停止当前连接（不关闭 StreamController，不销毁播放器）
  ///
  /// 用于模式切换场景：停掉 P2P 连接资源（CameraDevice、直播流），
  /// 但保持 AppPlayerController 存活（Texture widget 不会访问已销毁纹理）
  /// 且保持 StreamController 存活。
  Future<void> stop() async {
    debugPrint('[P2pVideoService] 停止连接...');
    await _cleanupCamera();
    // 播放器保持存活 —— stop() 后 connect() 可复用
    _updateState(P2pServiceState.disconnected);
  }

  /// 释放所有资源（含播放器 + StreamController）
  ///
  /// 调用后此实例不可再复用 [connect]。
  Future<void> dispose() async {
    debugPrint('[P2pVideoService] 释放资源...');
    await _cleanupCamera();
    await _cleanupPlayer();
    await _stateController.close();
  }

  // ==================== 内部实现 ====================

  /// P2P 连接状态变化回调
  void _onConnectChanged(CameraDevice device, CameraConnectState state) {
    debugPrint('[P2pVideoService] CameraConnectState 变化: $state');
    if (state == CameraConnectState.disconnect ||
        state == CameraConnectState.offline) {
      if (_currentState == P2pServiceState.connected) {
        _updateState(P2pServiceState.failed);
      }
    }
  }

  /// 清理 CameraDevice（停流 + 移除监听 + 销毁设备）
  Future<void> _cleanupCamera() async {
    if (_cameraDevice != null) {
      try {
        await _cameraDevice!.stopStream();
      } catch (_) {}
      try {
        _cameraDevice!.removeListener<CameraConnectChanged>(_onConnectChanged);
      } catch (_) {}
      try {
        await _cameraDevice!.deviceDestroy();
      } catch (_) {}
      _cameraDevice = null;
    }
  }

  /// 清理播放器（仅在最终 dispose 时调用）
  Future<void> _cleanupPlayer() async {
    if (_playerController != null) {
      try {
        await _playerController!.dispose();
      } catch (_) {}
      _playerController = null;
    }
  }

  /// 更新连接状态并广播
  void _updateState(P2pServiceState state) {
    if (_currentState == state) return;
    _currentState = state;
    if (!_stateController.isClosed) {
      _stateController.add(state);
    }
  }
}
