import 'dart:async';

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/dto/room/rtc_token_dto.dart';
import 'package:app/request/websocket/room_protocol.dart';
import 'package:app/request/websocket/room_websocket.dart';
import 'package:app/utils/time.dart';
import 'package:flutter/cupertino.dart';

import 'type.dart';

class TchRoomVM extends ChangeNotifier {
  TchRoomVM({
    required RoomListItemDto info,
  }) {
    roomInfo = MeetingRoomDto.fromRoomListItem(info).copyWith(roomStatus: -1);
    _startRoom();
  }

  ///学生摄像头列表
  List<RoomUserDto> _students = [];

  ///房间的基础信息，其中状态-1加载中，0没开始，1进行中，2关闭
  late MeetingRoomDto roomInfo;

  ///老师选中的学生id
  int activeSId = 0;

  List<RoomUserDto> get students => _students;

  ///是否能开始自习室
  bool get canEnterRoom {
    final now = DateTime.now();
    if (now.isAfter(parseTime(roomInfo.startTime))) {
      return true;
    }
    return false;
  }

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

  RtcTokenDto? get rtcToken => _ws.rtcToken;

  ///开始链接房间
  void _startRoom() async {
    //如果socket的token没有，先初始化
    if (_ws.wsToken.isEmpty) {
      await _ws.initToken(roomInfo.id);
    }
    //启动连接
    await _ws.connect();
    //监听各种ws事件
    _sub = _ws.stream.listen((msg) {
      // 自习室人员变化
      if (msg.event == RoomEvent.changeUser) {
        final list = RoomUserDto.listFromJson(msg.data['user_list']);
        final room = RoomInfoDto.fromJson(msg.data['room_info']);
        _updateRoomInfo(room);
        onStudentChange(list);
      } else if ([
        RoomEvent.openSpeaker,
        RoomEvent.closeSpeaker,
        RoomEvent.openMic,
        RoomEvent.closeMic,
        RoomEvent.openCamera,
        RoomEvent.closeCamera,
        RoomEvent.handUp,
      ].contains(msg.event)) {
        onSyncStudentItem(RoomUserDto.fromJson(msg.data));
      } else if (msg.event == RoomEvent.fileUploadComplete) {
        updateStudentFile(
          msg.data['user_id'],
          (msg.data['flies'] as List).map((e) => e.toString()).toList(),
        );
      }
    });
    notifyListeners();
  }

  ///更新房间信息
  void _updateRoomInfo(RoomInfoDto info) {
    roomInfo = roomInfo.copyWith(
      roomStatus: info.roomStatus,
      actualStartTime: info.roomStartTime,
      boardUuid: info.boardUuid,
    );
    notifyListeners();
  }

  ///自习室的开关
  /// - [isOpen]: 是否开启
  void toggleRoom({required bool isOpen}) {
    if (isOpen) {
      _ws.send(RoomCommand.openRoom);
    } else {
      _ws.send(RoomCommand.closeRoom);
    }
  }

  ///学生选择
  void selectStudent(int id) {
    activeSId = id;
    clearHandUp(id);
    notifyListeners();
  }

  ///手动关闭学生扬声器、摄像头、麦克风等操作
  /// - [uId]: 学生id
  /// - [action]: 操作类型
  void closeStudentAction({
    required int uId,
    required StudentAction action,
  }) {
    final student = _students.firstWhere((t) => t.userId == uId);

    Map<String, dynamic> data = {
      'target_user_id': uId,
      "mute_type": action.value,
    };
    //如果是控制扬声器
    if (action == StudentAction.speaker) {
      bool isOpen = student.speekerStatus == 1;
      student.speekerStatus = isOpen ? 0 : 1;
      data['is_mute'] = isOpen ? 1 : 0;
    } else if (action == StudentAction.camera) {
      //如果是摄像头
      bool isOpen = student.cameraStatus == 1;
      student.cameraStatus = 0;
      data['is_mute'] = isOpen ? 1 : 0;
    } else if (action == StudentAction.microphone) {
      //如果是麦克风
      bool isOpen = student.microphoneStatus == 1;
      student.microphoneStatus = 0;
      data['is_mute'] = isOpen ? 1 : 0;
    }
    notifyListeners();
    _ws.send(RoomCommand.switchStudentCamera, data);
  }

  ///关闭全部学生的摄像头或者扬声器
  void closeAllStudentAction(StudentAction action) {
    _students.forEach((item) {
      if (action == StudentAction.speaker) {
        item.speekerStatus = 0;
      } else if (action == StudentAction.camera) {
        item.cameraStatus = 0;
      }
    });
    notifyListeners();
    Map<String, dynamic> data = {
      'target_user_id': "all",
      "mute_type": action.value,
      "is_mute": 1,
    };
    _ws.send(RoomCommand.switchStudentCamera, data);
  }

  //清除全部学生举手，或者是指定
  void clearHandUp(int? id) {
    Map<String, dynamic> data = {};
    if (id == null) {
      data['target_user_id'] = "all";
      _students.forEach((t) => t.handup = 0);
    } else {
      data['target_user_id'] = id;
      _students.firstWhere((t) => t.userId == id).handup = 0;
    }
    notifyListeners();
    _ws.send(RoomCommand.clearHandUp, data);
  }

  ///学生人员变化事件，（如加入、退出、掉线）
  void onStudentChange(List<RoomUserDto> list) {
    _students = list.where((t) => t.userType != 2 && t.online == 1).toList();
    if (activeSId != 0) {
      final it = _students.where((t) => t.userId == activeSId).firstOrNull;
      if (it == null) {
        activeSId = 0;
      }
    }
    // 如果当前没有学生，则选择第一个
    if (activeSId == 0 && _students.isNotEmpty) {
      activeSId = _students.first.userId;
    }
    notifyListeners();
  }

  /// 同步单个学生的最新状态
  void onSyncStudentItem(RoomUserDto userInfo) {
    final index = _students.indexWhere((t) => t.userId == userInfo.userId);
    if (index != -1) {
      _students[index] = userInfo;
      notifyListeners();
    }
  }

  ///更新学生的文件
  void updateStudentFile(int uId, List<String> files) {
    final index = _students.indexWhere((t) => t.userId == uId);
    if (index != -1) {
      _students[index].filesList = files;
      notifyListeners();
    }
  }

  ///结束会议
  void endRoom() {
    roomInfo = roomInfo.copyWith(roomStatus: 2);
    _ws.send(RoomCommand.closeRoom);
    notifyListeners();
  }

  //销毁
  @override
  void dispose() {
    super.dispose();
    _sub?.cancel();
    _ws.dispose();
  }
}
