import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_measure/utils/prompt_box.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/services/entity/local_setting.dart';
import 'package:flyinsono/architecture/services/modules/local_setting_configurations.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/keyboard.dart';
import 'package:flyinsono/managers/interfaces/entities/classInfo.dart';
import 'package:flyinsono/managers/interfaces/entities/media_library.dart';
import 'package:flyinsono/managers/interfaces/flyinsono_college.dart';
import 'package:flyinsono/managers/interfaces/webview_controller.dart';
import 'package:flyinsono/pages/college/state.dart';
import 'package:flyinsono/pages/college/widgets/record_setting_dialog.dart';
import 'package:flyinsono/pages/main/home/widgets/dialog_page.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';
import 'package:fis_common/index.dart';

import 'package:flyinsono/architecture/define.dart';
import 'package:webviewx/webviewx.dart';

class FlyinsonoCollegeController extends FControllerBase
    with EnterPressListenOnControllerMixin {
  final state = FlyinsonoCollegeState();
  final flyinsonoCollegeManager = Get.find<IFlyinsonoCollegeManager>();
  final TextEditingController searchController = TextEditingController();
  WebViewXController? kActiveWebViewController; // 当前激活的webview控制器

  ///获取所有素材
  Future<void> getMediaLibrarys({
    String? keyword,
    int pageIndex = 1,
    int pageCount = 100,
  }) async {
    var result = await flyinsonoCollegeManager.getMediaLibrarys(
      keyword: keyword,
      pageCount: pageCount,
      pageIndex: pageIndex,
    );
    state.mediaLibrarys = result;
  }

  @override
  void onEnterPressed() {
    getMediaLibrarys(keyword: searchController.text);
  }

  Future<int> getClassInfos({
    ClassRoleType? roleType,
    String? keyword,
    int pageIndex = 1,
    int pageCount = 20,
    bool isMobileAndNoNeedPagination = false,
  }) async {
    UserGroupList result = await flyinsonoCollegeManager.getClassInfos(
      roleType: roleType,
      keyword: keyword,
      pageIndex: pageIndex,
      pageCount: pageCount,
    );
    if (isMobileAndNoNeedPagination) {
      state.classInfos.addAll(result.userGroup ?? []);
    } else {
      state.classInfos = result.userGroup ?? [];
    }
    update([
      'class_table',
      'class_tabs',
      'class_top_operate_button',
    ]);

    return result.totalCount ?? 0;
  }

  void updateClassTablePagination() {
    update(['class_table_pagination']);
  }

  ///添加素材
  Future<bool> addMediaLibrary(
    String name,
    String token, [
    String? vodFileId,
  ]) async {
    state.mediaLibrarys.add(MediaLibrary(
      fileType: getFileTypeEnum(name),
      name: name.split('.').sublist(0, name.split('.').length - 1).join('.'),
      fileToken: token,
      fileId: vodFileId,
    ));
    return true;
  }

  /// 提交素材
  Future<bool> submitMediaLibrary(List<MediaLibrary> mediaLibraryList) async {
    List<SaveVideoRequest> saveVideoList = [];
    mediaLibraryList.forEach((element) {
      saveVideoList.add(SaveVideoRequest(
        name: element.name,
        videoToken: element.fileToken,
        vodFileId: element.fileId,
        fodderType: getFileTypeEnum(element.name),

        /// TODO BAKA server要改
        creatorCode: Store.user.code,
        creatorName: Store.user.userName,
      ));
    });
    final result = await flyinsonoCollegeManager.createVideosAsync(
      videoList: saveVideoList,
    );
    getMediaLibrarys();
    return result;
  }

  UploadFileTypeEnum getFileTypeEnum(String fileName) {
    final fileExtension = fileName.split('.').last.toUpperCase();

    return UploadFileTypeEnum.values.firstWhere(
      (element) =>
          element.toString().toUpperCase() ==
          'UPLOADFILETYPEENUM.$fileExtension',
      orElse: () => UploadFileTypeEnum.Unknown,
    );
  }

  /// 退出班级
  void quitClass(String userGroupCode) async {
    final result = await rpc.education.studentLeaveCourseUserGroupAsync(
      StudentLeaveCourseUserGroupRequest(
        token: Store.user.token,
        userGroupCode: userGroupCode,
      ),
    );
    if (result) {
      PromptBox.toast(
        i18nBook.college.exitClassSuccess.t,
      );
    } else {
      PromptBox.toast(i18nBook.college.exitClassFailed.t);
    }
    getClassInfos(roleType: ClassRoleType.Student);
  }

  /// 新建班级 老师端
  Future<bool> createClass(String name) async {
    final result = await rpc.education.addUserGroupAsync(
      UserGroupRequest(
        name: name,
        token: Store.user.token,
        // ui未体现
        maxPeople: 50,
      ),
    );
    if (result) {
      PromptBox.toast(i18nBook.college.createClassSuccess.t);
    } else {
      PromptBox.toast(i18nBook.college.createClassFailed.t);
    }
    getClassInfos(roleType: ClassRoleType.Teacher);

    return result;
  }

  Future<bool> joinClass(String code) async {
    final result = await rpc.education.addStudentInCourseUserGroupAsync(
      AddStudentInCourseUserGroupRequest(
        shortCode: code,
        token: Store.user.token,
      ),
    );
    if (result) {
      PromptBox.toast(i18nBook.college.applyJoinClassSuccess.t);
    } else {
      PromptBox.toast(i18nBook.college.applyJoinClassFailed.t);
    }
    return result;
  }

  /// 申请同意
  Future<bool> agreeApply(String userCode, String userGroupCode) async {
    final result = await rpc.education.joinClassApprovedAsync(
      JoinClassApprovedRequest(
        token: Store.user.token,
        students: [userCode],
        userGroupCode: userGroupCode,
      ),
    );
    if (result) {
      getClassInfos(roleType: ClassRoleType.Teacher);
    } else {
      PromptBox.toast(i18nBook.college.applyAgreeFailed.t);
    }
    return result;
  }

  /// 申请拒绝
  Future<bool> refuseApply(String userCode, String userGroupCode) async {
    final result = await rpc.education.joinClassRejectedAsync(
      JoinClassRejectedRequest(
        token: Store.user.token,
        students: [userCode],
        userGroupCode: userGroupCode,
      ),
    );
    return result;
  }

  /// 移除学生
  Future<bool> removeStudent(String userCode, String userGroupCode) async {
    return await rpc.education.removeStudentsByGroupCodeAsync(
      UserGroupFilterRequest(
        token: Store.user.token,
        userGroupCode: userGroupCode,
        studentCodes: [userCode],
      ),
    );
  }

  /// 添加学生
  Future<bool> addStudents(
      List<String> selectedUsers, String userGroupCode) async {
    final result = await rpc.education.addUserGroupsStudentByTeacherAsync(
      TeacherAddStudentsInUserGroupsRequest(
        token: Store.user.token,
        userGroupCode: userGroupCode,
        studentCodes: selectedUsers,
      ),
    );
    return result;
  }

  /// 添加老师
  Future<bool> addTeachers(List<String> selectedUsers) async {
    PromptBox.toast(i18nBook.remedical.addSuccess.t);
    return true;
  }

  ///获取学生集合
  Future<PageResult<UserExtendDTO>> getStudents({
    String? keyword,
    int pageIndex = 1,
  }) async {
    busy = true;
    var result = flyinsonoCollegeManager.getStudents(
      keyword: keyword,
      pageIndex: pageIndex,
    );
    busy = false;
    return result;
  }

  ///获取讲师集合
  Future<List<UserExtendDTO>> getTeachers({
    String? keyword,
  }) async {
    return flyinsonoCollegeManager.getTeachers(keyword: keyword);
  }

  ///获取申请中的学生集合
  Future<void> getApplyStudents(String code) async {
    var result = await flyinsonoCollegeManager.getApplyStudent(
      classCode: code,
    );
    state.applayStudents = result;
  }

  ///获取班级内的学生集合
  Future<void> getClassStudents(String code) async {
    var result = await flyinsonoCollegeManager.getClassStudents(
      classCode: code,
      learnerStatus: LearnerStatusEnum.Accept,
    );
    state.students = result;
  }

  /// 检查录屏路径配置，如果不存在或者为空则向shell获取默认地址
  void checkRecordPath() async {
    if (FPlatform.isMacOS || FPlatform.isWindows) {
      print(LocalSetting.ins.liveRecordPath);
      if (LocalSetting.ins.liveRecordPath == null ||
          LocalSetting.ins.liveRecordPath == "") {
        String defaultPath = await rpc.platform.getDesktopPath();
        print("liveRecordPath is null set defaultPath:" + defaultPath);
        LocalSetting.ins.liveRecordPath = defaultPath;
        var localSettingService = Get.find<LocalSettingService>();
        localSettingService.save();
      } else {
        print("liveRecordPath exist! ${LocalSetting.ins.liveRecordPath}");
      }
    }
  }

  /// 打开录屏路径
  void openRecordPath() async {
    if (FPlatform.isMacOS || FPlatform.isWindows) {
      print(LocalSetting.ins.liveRecordPath);
      if (LocalSetting.ins.liveRecordPath == null ||
          LocalSetting.ins.liveRecordPath == "") {
        String defaultPath = await rpc.platform.getDesktopPath();
        print("liveRecordPath is null set defaultPath:" + defaultPath);
        LocalSetting.ins.liveRecordPath = defaultPath;
        var localSettingService = Get.find<LocalSettingService>();
        localSettingService.save();
      }
      if (LocalSetting.ins.liveRecordPath != null &&
          LocalSetting.ins.liveRecordPath!.isNotEmpty) {
        rpc.platform.openSpecifiedPath(LocalSetting.ins.liveRecordPath!);
      }
    }
  }

  /// 打开录屏设置弹窗
  void openRecordSettingDialog() async {
    if (FPlatform.isMacOS || FPlatform.isWindows) {
      await reconnectWebviewInteractiveController();
      Get.find<FWebviewInteractiveController>().onDialogCreate();
      await Get.dialog(
        RecordSettingDialog(),
      );
      Get.find<FWebviewInteractiveController>().onDialogDispose();
    }
  }

  /// 重连接 Webview 互斥控制器
  Future<void> reconnectWebviewInteractiveController() async {
    if (kActiveWebViewController == null) {
      return;
    }
    final webviewControllerManager = Get.find<IWebviewControllerManager>();

    /// 如果是同一个webview控制器则不需要重连接
    if (webviewControllerManager.webViewXController.hashCode ==
        kActiveWebViewController.hashCode) {
      return;
    }
    webviewControllerManager.disposeWebviewController();
    webviewControllerManager.initWebviewController(kActiveWebViewController!);
    // 等待300ms
    await Future.delayed(Duration(milliseconds: 300));
  }

  /// 打开壳子的路径选择器
  void openFolderPicker(String startPath) async {
    if (FPlatform.isMacOS || FPlatform.isWindows) {
      await rpc.platform.openFolderPicker(startPath);
    }
  }
}
