import 'dart:async';
import 'dart:ui' as ui;

import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:making_school_asignment_app/common/job/annotate_list_to_refresh.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/favor_param.dart';
import 'package:making_school_asignment_app/common/job/marking_models/review_submission_params.dart';
import 'package:making_school_asignment_app/common/mixins/event_bus_mixin.dart';
import 'package:making_school_asignment_app/common/mixins/request_tool_mixin.dart';
import 'package:making_school_asignment_app/common/utils/permission_describe_util.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:permission_handler/permission_handler.dart';
import 'package:zoom_widget/zoom_widget.dart' as zoomWidget;

import 'zoom_logic.dart';

// 数据
class HomeworkReviewState {
  HomeworkReviewState();

  // late String homeworkId;
  // late String homeworkName;
  late Rx<DoPaperDetailsParam> param;
  late Rx<DoPaperDetailsResult?> data = Rx<DoPaperDetailsResult?>(null);
  late Rx<List<StudentQuestions>?> studentQuestions = Rx<List<StudentQuestions>?>(null);
  late Rx<double> slide = 0.0.obs; // 滑动位置
  bool? panQuestView;
  // late Rx<TestQuestionsImageInfo?> imageScale;
  // late Rx<TestQuestionsImageInfo?> imageScaleZoom = Rx<TestQuestionsImageInfo?>(null);

  /// 图片放大后的操作存放数据
  List<dynamic> handwritings = [];
  bool needRefresh = false;
  bool lastQuestionPrompt = false; // 最后一题提示
  Rx<bool> getDataError = false.obs; // 获取作业数据报错

  Offset? zoomOffset;
  RxBool favorite = false.obs; // 初始化数据
  RxBool submitLoading = 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, EventBusMixin<AnnotateListToRefresh> {
  final zoomLogic = Get.find<ZoomLogic>();
  final GlobalKey pictureOverviewKey = GlobalKey();
  late StreamSubscription<DoPaperDetailsParam> _paramListen;
  late StreamSubscription<DoPaperDetailsResult?> _dataListen;
  final HomeworkReviewState state = HomeworkReviewState();
  final HomeworkReviewAnnotationsControlState annotationState = HomeworkReviewAnnotationsControlState();
  double appBarHeight = kToolbarHeight;

  StreamSubscription<TestQuestionsImageInfo?>? imageScaleZoomStream;

  zoomWidget.TransformationController? zoomController;

  @override
  void onInit() {
    appBarHeight = MediaQuery.of(Get.context!).padding.top;
    // WidgetsFlutterBinding.ensureInitialized();

    // SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); // 屏幕刘海
    zoomController = zoomWidget.TransformationController();
    state.param = DoPaperDetailsParam(
      homeworkId: Get.arguments['homeworkId'],
      homeworkName: Get.arguments['homeworkName'],
      classId: Get.arguments['classId'],
      subject: Get.arguments['subject'],
    ).obs;
    // state.imageScale = Rx<TestQuestionsImageInfo?>(null);

    // 参数变化更新作业详情
    _paramListen = state.param.listen((e) => getData());
    // 试题数据
    _dataListen = state.data.listen((e) {
      if (e == null) return;
      if (state.favorite.value != e.isFav) state.favorite.value = !state.favorite.value;
    });

    // imageScaleZoomStream = state.imageScale.listen((e) {
    //   // state.imageScaleZoom.value = theImageScale;
    //   var theImageScaleZoom = state.imageScaleZoom.value;
    //   if (theImageScaleZoom == null || theImageScaleZoom.url != e?.url) state.imageScaleZoom.value = e;
    // });

    WidgetsBinding.instance.addPostFrameCallback((_) => getData());
    super.onInit();
  }

  @override
  void onReady() {
    Future.delayed(Duration.zero, () {
      DeviceInfoPlugin().androidInfo.then((androidInfo) {
        Permission storagePermission =
            androidInfo.version.sdkInt >= 33 ? Permission.manageExternalStorage : Permission.storage;
        PermissionDescribeUtil.instance.toLaunchPermissionRequest(
          Get.context!,
          title: '储存权限请求',
          describe: "为了提供更好的服务，需要获取到存储权限用于保存批阅痕迹并上传",
          permissions: [storagePermission],
        );
      });
    });

    super.onReady();
  }

  @override
  void onClose() {
    zoomController?.dispose();
    // SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top]); // 屏幕刘海
    eventCancel();
    _dataListen.cancel();
    _paramListen.cancel();
    imageScaleZoomStream?.cancel();
    super.onClose();
  }

  void getData() async {
    // 防止重复请求
    if (state.submitLoading.value) return;

    var timerControl = Timer(const Duration(milliseconds: 300), () => ToastUtils.showLoading());
    try {
      DoPaperDetailsResult data = await getClient().getDoPaperDetails(state.param.value);

      state.getDataError.value = false;
      state.handwritings = [];

      state.param.value.templateId ??= data.templateId;
      state.param.value.studentId ??= data.studentId;

      state.studentQuestions.value = data.studentQuestions; // 赋值试题集合
      state.data.value = data;
    } catch (e) {
      // 移除冗余打印，使用提示替代
      state.getDataError.value = true;
      ToastUtils.showError('获取试题数据失败，请检查网络连接后重试');
    } finally {
      if (timerControl.isActive) timerControl.cancel();
      ToastUtils.dismiss();
    }
  }

  // 取消全部评分
  void cancelAllRatings() {
    var studentQuestions = state.studentQuestions.value;
    if (state.data.value?.studentQuestions.isEmpty ?? true) return;
    for (var e in studentQuestions!) {
      if (e.studentScore != null) {
        e.studentScore = null;
      }
    }
    // state.studentQuestions.value = data;
    // state.data.value?.studentQuestions = data;
    state.studentQuestions.update((_) {});
  }

  // 全部统一打分
  void allRating(int score) {
    var studentQuestions = state.studentQuestions.value;
    if (state.data.value?.studentQuestions.isEmpty ?? true) return;
    for (var e in studentQuestions!) {
      e.studentScore = score;
    }
    // state.studentQuestions.value = data;
    // state.data.value?.studentQuestions = data;
    state.studentQuestions.update((_) {});
  }

  // 全对评分
  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;

      /// 此图片在设备中的像素比例
      var pixelRatio = zoomLogic.zoomState.zoomFile.value?.pixelRatio;
      ui.Image image = await boundary.toImage(pixelRatio: pixelRatio ?? dpr);
      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) {
      // 图片上传失败日志移除，统一提示
      ToastUtils.getFluttertoast(msg: '图片上传失败', context: context);
    } finally {
      // ToastUtils.dismiss();
    }
    return null;
  }

  // 提交打分
  /// allPairs
  Future<void> submit(BuildContext context) async {
    try {
      if (state.submitLoading.value) {
        ToastUtils.showInfo("正在提交批阅数据，请勿重复操作");
        return;
      }

      state.submitLoading.value = true;
      var data = state.data.value;
      if (data == null) {
        ToastUtils.showError('数据异常，请重新加载');
        return;
      }

      if ((state.data.value?.studentQuestions.isEmpty ?? true) || (state.studentQuestions.value?.isEmpty ?? true)) {
        ToastUtils.showError('没有可批阅的试题');
        return;
      }

      var studentQuestions = state.studentQuestions.value!.where((e) => e.useTime != null && e.useTime! > 0).toList();
      // 跳过学生未作答的题
      try {
        var noRatingElement = studentQuestions.firstWhere((e) => e.studentScore == null);
        ToastUtils.showInfo('第${noRatingElement.questionNo}题请评分');
        return;
      } catch (e) {
        // 所有题目都已评分
      }

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

      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.needAnnotate) totalUnAnnotateCount -= 1; // 是否需要批阅

        if (totalUnAnnotateCount <= 0) {
          // 批阅完成
          if (!state.lastQuestionPrompt) {
            await _showCompletionDialog(context);
          } else {
            ToastUtils.showSuccess("批阅已提交", duration: const Duration(milliseconds: 800));
          }
          return;
        }

        var newParams = DoPaperDetailsParam.fromJson(state.param.value.toJson());
        if (totalUnAnnotateCount > 0) {
          // 当前批阅任务完成 重复提交后 停留在当前数据位置
          newParams.templateId = null;
          newParams.studentId = null;
        }
        state.param.value = newParams;
        ToastUtils.showSuccess("批阅已提交");
      });
    } catch (e) {
      // 提交异常日志移除，统一提示
      ToastUtils.showError('提交失败，请检查网络连接后重试');
    } finally {
      state.submitLoading.value = false;
    }
  }

  Future<void> _showCompletionDialog(BuildContext context) async {
    await showDialog(
      context: Get.context ?? context,
      barrierDismissible: false,
      builder: (BuildContext context1) {
        return AlertDialog(
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.r)),
          title: Row(
            children: [
              Icon(Icons.check_circle, color: Colors.green, size: 24.sp),
              SizedBox(width: 8.w),
              Text('批阅已完成', style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.w600)),
            ],
          ),
          content: Text('暂无更多批阅项，是否继续？', style: TextStyle(fontSize: 14.sp)),
          actions: <Widget>[
            TextButton(
              child: Text('退出批阅', style: TextStyle(color: Colors.grey[600])),
              onPressed: () {
                Navigator.of(context1).pop();
                Get.back();
              },
            ),
            TextButton(
              child: Text('继续', style: TextStyle(color: Theme.of(context).primaryColor)),
              onPressed: () {
                state.lastQuestionPrompt = true;
                Navigator.of(context1).pop();
              },
            ),
          ],
        );
      },
    );
  }

  Future<void> toFavorite() async {
    try {
      var data = state.data.value!;
      var param = state.param.value;
      await getClient().toFavStudent(FavorParam(
        homeworkId: param.homeworkId,
        studentId: data.studentId,
        templateId: data.templateId,
        questionNo: data.studentQuestions[0].questionNo,
        isFav: !data.isFav,
      ));
      state.favorite.value = !data.isFav;
      data.isFav = state.favorite.value;
    } catch (e) {
      ToastUtils.showError('操作失败，请重试');
    }
  }
}
