import 'dart:async';

import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:app/global/config.dart';
import 'package:app/data/models/meeting_room_dto.dart';
import 'package:app/request/dto/room/room_list_item_dto.dart';
import 'package:app/request/dto/room/room_info_dto.dart';
import 'package:app/request/dto/room/room_user_dto.dart';
import 'package:app/request/websocket/room_protocol.dart';
import 'package:app/request/websocket/room_websocket.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:logger/logger.dart';
import 'package:wakelock_plus/wakelock_plus.dart';

Logger log = Logger();

class StuRoomVM extends ChangeNotifier {
  ///房间信息，状态0没开始，1进行中，2已结束
  late MeetingRoomDto roomInfo;

  ///其他学生列表，老师信息，自己信息
  int uid;
  List<RoomUserDto> otherStuList = [];
  RoomUserDto? teacherInfo;
  RoomUserDto? selfInfo;

  // ///老师是否发送请求过来了，0关闭，1摄像头，2麦克风
  // bool cameraReq = false;
  // bool micReq = false;

  ///本人的摄像头、麦克风、扬声器、举手状态是否关闭了
  bool get cameraClose => selfInfo?.cameraStatus == 0;

  bool get micClose => selfInfo?.microphoneStatus == 0;

  bool get speakerClose => selfInfo?.speekerStatus == 0;

  bool get handClose => selfInfo?.handup == 0;

  ///ws管理
  final RoomWebSocket _ws = RoomWebSocket();
  StreamSubscription<RoomMessage>? _sub;

  /// 声网sdk管理
  RtcEngine? _engine;

  RtcEngine? get engine => _engine;

  StuRoomVM({required RoomListItemDto info, required this.uid}) {
    roomInfo = MeetingRoomDto.fromRoomListItem(info);
    _startRoom();
  }

  ///初始化声网
  Future<void> _initRtc() async {
    if (_engine != null) return;
    _engine = createAgoraRtcEngine();
    //初始化 RtcEngine，设置频道场景为 channelProfileLiveBroadcasting（直播场景）
    await _engine!.initialize(
      RtcEngineContext(
        appId: Config.swAppId,
        channelProfile: ChannelProfileType.channelProfileCommunication,
      ),
    );
    _engine!.getUserInfoByUid(1);
    // 启用视频模块
    await _engine!.enableVideo();
    // 开启本地预览
    await _engine!.startPreview();

    WakelockPlus.enable();
    final status = await _engine!.getConnectionState();
    if (status == ConnectionStateType.connectionStateDisconnected) {
      //加入频道
      await _engine!.joinChannel(
        token: _ws.rtcToken!.token,
        channelId: _ws.rtcToken!.channel,
        uid: _ws.rtcToken!.uid,
        options: ChannelMediaOptions(
          // 自动订阅所有视频流
          autoSubscribeVideo: true,
          // 自动订阅所有音频流
          autoSubscribeAudio: true,
          // 发布摄像头采集的视频
          publishCameraTrack: true,
          // 发布麦克风采集的音频
          publishMicrophoneTrack: true,
          // 设置用户角色为 clientRoleBroadcaster（主播）或 clientRoleAudience（观众）
          clientRoleType: ClientRoleType.clientRoleBroadcaster,
        ),
      );
    }
  }

  ///开始链接房间
  Future<void> _startRoom() async {
    //如果socket的token没有，先初始化
    if (_ws.wsToken.isEmpty) {
      await _ws.initToken(roomInfo.id);
    }
    //启动连接
    await _ws.connect();
    //
    _sub?.cancel();
    _sub = _ws.stream.listen((msg) {
      //自习室人员变化，同时也设置房间是否开了
      if (msg.event == RoomEvent.changeUser) {
        final list = RoomUserDto.listFromJson(msg.data['user_list']);
        onStudentChange(list);
        onRoomStartStatus(RoomInfoDto.fromJson(msg.data['room_info']));
      } else if (msg.event == RoomEvent.closeStudentCamera) {
        changeCameraSwitch(fromServer: false, value: false);
      } else if (msg.event == RoomEvent.closeStudentMic) {
        changeMicSwitch(fromServer: false, value: false);
      } else if ([
        RoomEvent.closeStudentSpeaker,
        RoomEvent.openStudentSpeaker,
      ].contains(msg.event)) {
        //控制扬声器
        changeSpeakerSwitch(
          value: msg.event == RoomEvent.openStudentSpeaker,
          fromServer: false,
        );
      } else if (msg.event == RoomEvent.openStudentMic) {
        EasyLoading.showToast("老师请求打开麦克风");
        // 打开麦克风
      } else if (msg.event == RoomEvent.openStudentCamera) {
        EasyLoading.showToast("老师请求打开摄像头");
        // 打开摄像头
      } else if (msg.event == RoomEvent.clearHandUp) {
        changeHandSwitch();
      } else if (msg.event == RoomEvent.closeRoom) {
        _closeRoom();
      }
    });
  }

  ///学生人员变化事件，（如加入、退出、掉线）
  void onStudentChange(List<RoomUserDto> list) {
    final lineList = list.where((t) => t.online == 1);
    List<RoomUserDto> newList = [];
    for (var t in lineList) {
      //设置老师
      if (t.userType == 2) {
        teacherInfo = t;
      } else {
        //要过滤自己,只要其他学生
        if (t.userId != uid) {
          newList.add(t);
        } else {
          selfInfo = t;
          //同步声网的状态
          changeCameraSwitch(value: selfInfo!.cameraStatus == 1, fromServer: false);
          changeMicSwitch(value: selfInfo!.microphoneStatus == 1, fromServer: false);
          changeSpeakerSwitch(value: selfInfo!.speekerStatus == 1, fromServer: false);
        }
      }
    }
    otherStuList = newList;
    notifyListeners();
  }

  ///设置房间开启状态
  void onRoomStartStatus(RoomInfoDto info) {
    roomInfo = roomInfo.copyWith(
      roomStatus: info.roomStatus,
      actualStartTime: info.roomStartTime,
      boardUuid: info.boardUuid,
    );
    //开启摄像头
    if (roomInfo.roomStatus == 1) {
      _initRtc();
    }
    notifyListeners();
  }

  ///控制摄像头开关
  /// - [value] 摄像头状态，true为开启，false为关闭
  /// - [fromServer] 发送指令给服务器，默认true
  void changeCameraSwitch({
    required bool value,
    bool fromServer = true,
  }) {
    //改变后的操作状态,true表示开，false关
    selfInfo!.cameraStatus = value ? 1 : 0;
    // //发送指令
    if (fromServer) {
      _ws.send(RoomCommand.studentActon, {
        "mute_type": "camera",
        "is_mute": value ? 0 : 1,
      });
    }
    _engine?.enableLocalVideo(value);
    notifyListeners();
  }

  ///控制麦克风开关
  /// - [value] 麦克风状态，true为开启，false为关闭
  /// - [fromServer] 默认为true，发送指令给服务器
  void changeMicSwitch({required bool value, bool fromServer = true}) {
    selfInfo!.microphoneStatus = value ? 1 : 0;
    //发送指令
    if (fromServer) {
      _ws.send(RoomCommand.studentActon, {
        "mute_type": "microphone",
        "is_mute": value ? 0 : 1,
      });
    }
    _engine?.enableLocalAudio(value);
    notifyListeners();
  }

  /// 控制扬声器开关
  /// - [value] 扬声器状态，true为开启，false为关闭
  /// - [fromServer] 默认为true，发送指令给服务器
  void changeSpeakerSwitch({required bool value, bool fromServer = true}) {
    //操作后是否是开启状态
    selfInfo!.speekerStatus = value ? 1 : 0;
    //发送指令
    if (fromServer) {
      _ws.send(RoomCommand.studentActon, {
        "mute_type": "speeker",
        "is_mute": value ? 0 : 1,
      });
    }
    _engine?.muteAllRemoteAudioStreams(!value);
    notifyListeners();
  }

  ///控制举手
  void changeHandSwitch({bool fromServer = true}) {
    bool nextOpen = handClose;
    selfInfo!.handup = nextOpen ? 1 : 0;
    if (fromServer) {
      _ws.send(RoomCommand.handUp, {
        'is_handup': nextOpen ? 1 : 0,
      });
    }
    notifyListeners();
  }

  ///上传文件
  void uploadFile(List<String> files) {
    selfInfo?.filesList.addAll(files);
    _ws.send(RoomCommand.uploadFile, {
      "files": selfInfo!.filesList,
    });
  }

  ///自习室关闭
  void _closeRoom() {
    roomInfo.roomStatus = 2;
    _dispose();
    notifyListeners();
  }

  ///销毁
  void _dispose() {
    _engine?.leaveChannel();
    _engine?.release();
    _sub?.cancel();
    _ws.dispose();
    WakelockPlus.disable();
  }

  @override
  void dispose() {
    super.dispose();
    _dispose();
  }
}
