import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:marking_app/common/mixin/common.dart';
import 'package:marking_app/common/model/common/base_structure_result.dart';
import 'package:marking_app/common/model/event_bus/jobs/job_do_papers_student_bus.dart';
import 'package:marking_app/common/model/job/job_concerned_with_student.dart';
import 'package:marking_app/common/model/job/job_concerned_with_student_params.dart';
import 'package:marking_app/common/model/job/job_page_tab.dart';
import 'package:marking_app/pages/common/event_bus_mixin.dart';
import 'package:marking_app/utils/index.dart';
import 'package:marking_app/utils/my_text.dart';
import 'package:marking_app/utils/request/rest_client.dart';

class UseSwitchStudentAndType with CommonMixin, EventBusMixin {
  ValueNotifier<bool> exitPromptFlag; // 退出提示
  ValueNotifier<bool> isFirst;
  ValueNotifier<bool> isFinish;

  ValueNotifier<List<JobConcernedWithStudent>> studentData; // 学生集合数据
  ValueNotifier<List<JobPageTab>> tabs; // 学生集合数据

  ValueNotifier<List<ExamStatus>> examStatusData; // 试卷状态数据

  ValueNotifier<JobConcernedWithStudent?> currentStudent; // 当前学生
  ValueNotifier<ExamStatus> currentExamStatus; // 当前状态
  ValueNotifier<JobPageTab?> currentTab; // 当前tab页码

  ValueNotifier<JobDoPapersStudentBus?> studentBusInfo; // 接收到值后重新赋值当前选中学生和当前选中题型页码

  UseSwitchStudentAndType._({
    required this.studentData,
    required this.currentStudent,
    required this.tabs,
    required this.examStatusData,
    required this.currentExamStatus,
    required this.currentTab,
    required this.studentBusInfo,
    required this.exitPromptFlag,
    required this.isFirst,
    required this.isFinish,
  });

  // 工厂构造函数
  factory UseSwitchStudentAndType.use() {
    var examStatusData = useState([ExamStatus(0, '未完成'), ExamStatus(1, '已完成')]);
    var currentExamStatus = useState(examStatusData.value[0]);
    var studentData = useState<List<JobConcernedWithStudent>>([]);
    var currentStudent = useState<JobConcernedWithStudent?>(null);

    var tabList = useState<List<JobPageTab>>([]);
    var currentTab = useState<JobPageTab?>(null);

    var theStudentBus = useState<JobDoPapersStudentBus?>(null);

    return UseSwitchStudentAndType._(
      examStatusData: examStatusData,
      currentExamStatus: currentExamStatus,
      currentStudent: currentStudent,
      studentData: studentData,
      tabs: tabList,
      currentTab: currentTab,
      studentBusInfo: theStudentBus,
      exitPromptFlag: useState<bool>(false),
      isFirst: useState<bool>(false),
      isFinish: useState<bool>(false),
    );
  }

  // 获取学生集合
  getDataForStudents({required int taskId, int? pageIndex}) async {
    RestClient client = await getClient();
    if (pageIndex == null) {
      pageIndex = currentTab.value?.pageIndex;
    }
    BaseStructureResult<List<JobConcernedWithStudent>> result =
        await client.getJobWithStudents(JobConcernedWithStudentParams([taskId], isCommit: true, pageIndex: pageIndex));
    if (result.success && result.data != null) studentData.value = result.data!;
  }

  Future<List<JobPageTab>?> getDataForTestpaper({required int taskId, bool synchronization = true}) async {
    RestClient client = await getClient();
    BaseStructureResult<List<JobPageTab>> result = await client.getJobOfTabs(taskId);
    if (result.success && result.data != null) {
      tabs.value = result.data!;
      if (synchronization) {
        currentTab.value = tabs.value.firstWhere((e) => e.finishCount < e.total, orElse: () => tabs.value[0]);
      }
    } else {
      // TODO 获取数据失败 之后如何处理
      ToastUtils.showError(result.message ?? '获取体型数据失败');
    }
    return result.data;
  }

  getData({required int taskId}) {
    getDataForStudents(taskId: taskId);
    getDataForTestpaper(taskId: taskId);
  }

  /// 属性tab类型数据
  Future<JobPageTab?> refreshQuestionTypeData(BuildContext context, {required int taskId, required Function() exitCallback}) async {
    List<JobPageTab>? tabDatas = await getDataForTestpaper(taskId: taskId, synchronization: false);
    if (tabDatas?.isNotEmpty ?? false) {
      JobPageTab? tabJob = tabDatas!.firstWhereOrNull((e) => e.finishCount < e.total);
      if (tabJob == null && !exitPromptFlag.value) {
        var exitFlag = await showDialog<bool>(
          context: context,
          builder: (BuildContext context1) {
            return AlertDialog(
              title: quickText('完成批阅提示'),
              content: Text('暂无更多待批阅项，是否返回主页？'),
              actions: <Widget>[
                TextButton(child: Text('否'), onPressed: () => Navigator.of(context1).pop(false)),
                TextButton(child: Text('是'), onPressed: () => Navigator.of(context1).pop(true)),
              ],
            );
          },
        );
        if (exitFlag == null || !exitFlag) {
          exitPromptFlag.value = true;
          return tabJob; // 不跳转
        }
        exitCallback();
      } else {
        // 跳转到对于位置
        tabs.value = tabDatas;
        if (tabJob != null) currentTab.value = tabJob;
        if (tabJob == null && exitPromptFlag.value) ToastUtils.showSuccess('最后一题提交成功');
        return tabJob;
      }
    }
    return null;
  }

  /// 优先批阅 ==> 取消优先批阅
  Future<void> jobPriorityReviewCancel(int jobId) async {
    RestClient _client = await getClient();
    var studentId = currentStudent.value?.studentId;
    if (studentId == null) return ToastUtils.showInfo('无法获取到学生ID，请重试');
    BaseStructureResult result = await _client.jobPriorityReviewCancel(jobId, studentId);
    if (result.success) {
      isFirst.value = !isFirst.value;
    }
  }

  /// 优先批阅 ==> 添加优先批阅
  Future<void> jobPriorityReviewJoin(int jobId) async {
    RestClient _client = await getClient();
    var studentId = currentStudent.value?.studentId;
    if (studentId == null) return ToastUtils.showInfo('无法获取到学生ID，请重试');
    BaseStructureResult result = await _client.jobPriorityReviewJoin(jobId, studentId);
    if (result.success) {
      isFirst.value = !isFirst.value;
    }
  }
}

class ExamStatus extends Object {
  int id;
  String name;
  ExamStatus(this.id, this.name);
}
