import 'dart:async';
import 'dart:io';

import 'dart:ui' as ui;

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:making_school_asignment_app/common/job/marking_models/do_paper_details_param.dart';
import 'package:making_school_asignment_app/common/job/marking_models/do_paper_details_result.dart';
import 'package:making_school_asignment_app/common/job/marking_models/do_test_questions_image_info.dart';
import 'package:making_school_asignment_app/common/job/marking_models/review_submission_params.dart';
import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart';
import 'package:making_school_asignment_app/common/utils/toast_utils.dart';
import 'package:making_school_asignment_app/common/utils/upload_oss_img_utils.dart';
import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
import 'package:making_school_asignment_app/page/home_page/children/job_report/widget/personnel_data_overview.dart';

// 数据
class HomeworkReviewState {
  HomeworkReviewState();

  // late String homeworkId;
  // late String homeworkName;
  late Rx<DoPaperDetailsParam> param;
  late Rx<DoPaperDetailsResult?> data;
  late Rx<List<StudentQuestions>?> studentQuestions;
  late Rx<double> slide; // 滑动位置
  late bool? panQuestView;
  late Rx<TestQuestionsImageInfo?> imageScale;
  List<dynamic> handwritings = [];
  bool needRefresh = false;
  bool lastQuestionPrompt = false; // 最后一题提示
  Rx<bool> getDataError = false.obs; // 获取作业数据报错

  // late String dateEnd = '';
  // late int knowledgeId = 0;
  // late RxList<KnowledgeReportDetail> dataList = RxList();
  // late RxList<Students> studentList = RxList();
  // late RxString knowledgeName = ''.obs;
}

// 批注控制器
class HomeworkReviewAnnotationsControlState {
  HomeworkReviewAnnotationsControlState();
  // late RxBool backStep = false.obs;       // 返回上一步

  RxBool pen = true.obs; // 笔
  RxBool gestureMove = false.obs; // 手势移动
  RxBool clearAll = false.obs; // 清空全部
  RxBool opControl = true.obs; // 批注控制器开关
}

class HomeworkReviewBinding extends Bindings {
  @override
  void dependencies() => Get.lazyPut(() => HomeworkReviewLogic());
}

class HomeworkReviewLogic extends GetxController with RequestToolMixin {
  final GlobalKey pictureOverviewKey = GlobalKey();
  late StreamSubscription<DoPaperDetailsParam> _paramListen;
  late StreamSubscription<DoPaperDetailsResult?> _dataListen;
  final HomeworkReviewState state = HomeworkReviewState();
  final HomeworkReviewAnnotationsControlState annotationState = HomeworkReviewAnnotationsControlState();

  @override
  void onInit() {
    super.onInit();
    state.param = DoPaperDetailsParam(
      homeworkId: Get.arguments['homeworkId'],
      homeworkName: Get.arguments['homeworkName'],
      classId: Get.arguments['classId'],
      subject: Get.arguments['subject'],
    ).obs;
    state.data = Rx<DoPaperDetailsResult?>(null);
    state.studentQuestions = Rx<List<StudentQuestions>?>(null);
    state.imageScale = Rx<TestQuestionsImageInfo?>(null);
    state.slide = 0.0.obs;
    getData();
    // 参数变化更新作业详情
    _paramListen = state.param.listen((e) => getData());
    // 试题数据
    _dataListen = state.data.listen((e) => state.imageScale.value = null);
  }

  @override
  void disposeId(Object id) {
    _dataListen.cancel();
    _paramListen.cancel();
    super.disposeId(id);
  }

  void getData() async {
    var timerControl = Timer(const Duration(milliseconds: 300), () => ToastUtils.showLoading());
    try {
      DoPaperDetailsResult? data = await getClient().getDoPaperDetails(state.param.value);
      // var studentQuestions = data.studentQuestions;
      // // 第0个的下标数据不需要处理
      // for (var i = 0; i < studentQuestions.length; i++) {
      //   var item = studentQuestions[i];

      //   item.topHeight = itemPre.height;
      // }
      state.getDataError.value = false;
      state.data.value = data;
      state.handwritings = [];
      state.studentQuestions.value = data.studentQuestions;
    } catch (e) {
      print('获取数据报错了：$e');
      ToastUtils.showError('获取试题数据出错，请重试');
      state.getDataError.value = true;
    } finally {
      if (timerControl.isActive) timerControl.cancel();

      ToastUtils.dismiss();
    }
  }

  // 取消全部评分
  void cancelAllRatings() {
    var studentQuestions = state.studentQuestions.value;
    if (state.data.value?.studentQuestions.isEmpty ?? true) return;
    List<StudentQuestions> data = [];
    for (var e in studentQuestions!) {
      var newe = StudentQuestions.fromJson(e.toJson());
      newe.studentScore = null;
      data.add(newe);
    }
    state.studentQuestions.value = data;
    state.data.value?.studentQuestions = data;
  }

  // 全部统一打分
  void allRating(int score) {
    var studentQuestions = state.studentQuestions.value;
    if (state.data.value?.studentQuestions.isEmpty ?? true) return;
    List<StudentQuestions> data = [];
    for (var e in studentQuestions!) {
      var newe = StudentQuestions.fromJson(e.toJson());
      newe.studentScore = score;
      data.add(newe);
    }
    state.studentQuestions.value = data;
    state.data.value?.studentQuestions = data;
  }

  // 全对评分
  void allPairs(BuildContext context, [int score = 2]) async {
    allRating(score);
    await submit(context);
  }

  // 全错评分
  void allWrongRating(BuildContext context, [int score = 0]) async {
    allRating(score);
    await submit(context);
  }

  // 上传图片
  Future<String?> saveImage(context) async {
    if (state.handwritings.isEmpty) return null;
    try {
      var data = state.data.value;
      var param = state.param.value;
      if (data == null) return null;

      // 获取OSS 图片url
      String imgKey = UploadOssImgUtils.getInstance().setImgKey(param.homeworkId, data.studentId.toString(), data.templateId.toString());
      var resUrl = await getClient().getOssPresignedUri(imgKey);
      if (resUrl == null) return null;

      // 没有图片就上传图片
      RenderRepaintBoundary? boundary = pictureOverviewKey.currentContext!.findRenderObject() as RenderRepaintBoundary?;
      if (boundary == null) return null;
      // double dpr = MediaQuery.of(context).devicePixelRatio;

      double pixelRatio = MediaQuery.of(context).devicePixelRatio;
      var imageScale = state.imageScale.value;
      if (imageScale != null) {
        // 还原图片原始比例
        pixelRatio = imageScale.imageWidth / imageScale.boxWidth;
      }

      ui.Image image = await boundary.toImage(pixelRatio: pixelRatio);
      ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);
      if (byteData == null) return null;

      Dio dio = Dio();
      dio.options.contentType = null;
      List<int> bytes = byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes);
      await dio.put(
        resUrl,
        data: Stream.fromIterable(bytes.map((e) => [e])),
        options: Options(contentType: null, headers: {Headers.contentLengthHeader: bytes.length}),
      );

      return imgKey;
    } catch (e) {
      print('图片上传失败');
      print(e.toString());
      ToastUtils.getFluttertoast(msg: '图片上传失败', context: context);
    } finally {
      // ToastUtils.dismiss();
    }
    return null;
  }

  // 提交打分
  /// allPairs
  Future<void> submit(BuildContext context) async {
    var data = state.data.value;
    if (data == null) return;

    if (state.data.value?.studentQuestions.isEmpty ?? true) return;
    var studentQuestions = state.data.value!.studentQuestions;
    var noRatingElement = studentQuestions.firstWhereOrNull((e) => e.studentScore == null);
    if (noRatingElement != null) {
      ToastUtils.showInfo('${noRatingElement.questionNo}题请评分');
      return;
    }

    // 图片上传
    String? zgtAnnotate = state.data.value?.zgtAnnotate;
    String? newzgtAnnotate = await saveImage(context);
    if (newzgtAnnotate != null) zgtAnnotate = newzgtAnnotate;

    // TODO 请求提交加载框是否需要 如何防止重复提交
    await getClient()
        .reviewSubmission(ReviewSubmissionParams(
            homeworkId: state.param.value.homeworkId,
            templateId: data.templateId,
            studentId: data.studentId,
            zgtAnnotate: zgtAnnotate,
            studentScores: studentQuestions.map((e) {
              var studentScore = e.studentScore!;
              return StudentScores(
                isCorrect: studentScore == 2,
                questionNo: e.questionNo,
                studentScore: studentScore,
              );
            }).toList()))
        .then((e) async {
      state.needRefresh = true;
      var totalUnAnnotateCount = data.totalUnAnnotateCount;
      if (data.annotateTime == null) totalUnAnnotateCount -= 1;

      if (totalUnAnnotateCount <= 0 && !state.lastQuestionPrompt) {
        // 批阅完成
        showDialog(
          context: context,
          builder: (BuildContext context1) {
            return AlertDialog(
              title: quickText('批阅已完成'),
              content: const Text('暂无更多待批阅项'),
              actions: <Widget>[
                TextButton(
                  child: const Text('继续'),
                  onPressed: () {
                    state.lastQuestionPrompt = true;
                    Navigator.of(context1).pop();
                  },
                ),
                TextButton(
                    child: const Text('退出批阅'),
                    onPressed: () {
                      Navigator.of(context1).pop();
                      Get.back();
                    }),
              ],
            );
          },
        );
        return;
      }
      var newParams = DoPaperDetailsParam.fromJson(state.param.value.toJson());
      if (totalUnAnnotateCount > 0) {
        // 当前批阅任务完成 重复提交后 停留在当前数据位置
        newParams.templateId = null;
        newParams.studentId = null;
      }
      state.param.value = newParams;
    });
  }
}
