import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:functional_widget_annotation/functional_widget_annotation.dart';
import 'package:get/get.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/original_manuscript_handwriting_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/anti_shake_throttling.dart';
import 'package:making_school_asignment_app/common/utils/cached_network_img.dart';
import 'package:making_school_asignment_app/common/utils/my_time_util.dart';
import 'package:making_school_asignment_app/common/utils/toast_utils.dart';
import 'package:making_school_asignment_app/page/global_widget/my_text.dart';
import 'package:making_school_asignment_app/page/home_page/children/homework_review/components/job_handwriting.dart';

import 'configuration_files/logic.dart';
import 'configuration_files/states.dart';

part 'answer_handwriting_view.g.dart';

/// 学生答题轨迹
class AnswerHandwriting extends Dialog {
  final String homeworkId;
  final int studentId;
  final int? templateId;
  final int? pageNum;
  final String? questionNo;
  final Function closeCall;
  AnswerHandwriting(
      {super.key,
      required this.homeworkId,
      required this.studentId,
      required this.closeCall,
      this.templateId,
      this.pageNum,
      this.questionNo});
  final _handwritingLogic = Get.find<HandwritingLogic>();
  @override
  Widget build(BuildContext context) {
    return OrientationBuilder(
        builder: (BuildContext context, Orientation orientation) {
      var boxHeight = ScreenUtil().screenHeight / 1.168; // 盒子高度
      var boxWidth = ScreenUtil().screenWidth -
          (ScreenUtil().scaleWidth < 1.5 ? 40.r : 40.r); // 盒子宽度

      return Center(
        child: Container(
          height: boxHeight,
          width: boxWidth,
          alignment: Alignment.center,
          child: AnswerHandwritingMainBox(
            handwritingLogic: _handwritingLogic,
            boxHeight: boxHeight,
            boxWidth: boxWidth,
            homeworkId: homeworkId,
            templateId: templateId,
            studentId: studentId,
            pageNum: pageNum,
            questionNo: questionNo,
            closeCall: closeCall,
          ),
        ),
      );
    });
  }
}

Future<void> showAnswerHandwriting(
  BuildContext context, {
  required String homeworkId,
  required int studentId,
  int? templateId,
  int? pageNum,
  String? questionNo,
}) async {
  backCall() {
    Navigator.of(context).pop();
  }

  Get.put(HandwritingLogic(backCall));
  Get.find<HandwritingLogic>().params.value =
      OriginalManuscriptHandwritingParams(
    homeworkId: homeworkId,
    studentId: studentId,
    templateId: templateId,
    pageNum: pageNum,
    questionNo: questionNo,
  );
  await showDialog(
    context: context,
    builder: (BuildContext context) => AnswerHandwriting(
      homeworkId: homeworkId,
      templateId: templateId,
      studentId: studentId,
      pageNum: pageNum,
      questionNo: questionNo,
      closeCall: backCall,
    ),
  ).then((e) => Get.delete<HandwritingLogic>());
}

// 主图
class AnswerHandwritingMainBox extends HookWidget with EventBusMixin {
  AnswerHandwritingMainBox({
    required this.handwritingLogic,
    required this.homeworkId,
    required this.studentId,
    required this.closeCall,
    required this.boxHeight,
    required this.boxWidth,
    this.templateId,
    this.pageNum,
    this.questionNo,
    super.key,
  });

  final HandwritingLogic handwritingLogic;

  final String homeworkId;
  final double boxHeight;
  final double boxWidth;
  final int? templateId;
  final int studentId;
  final int? pageNum;
  final String? questionNo;
  final Function closeCall;

  @override
  Widget build(BuildContext context) {
    var _useStateModel = UseMainBoxState.use(
        homeworkId, studentId, pageNum, questionNo, templateId);
    double barHeight = 62.h;
    double imageHeight = boxHeight - barHeight;
    useValueChanged<JobHandwriting?, void>(_useStateModel.handwritingData.value,
        (_, __) {
      var theData = _useStateModel.handwritingData.value;
      _useStateModel.pageNum.value = theData?.pageNum;
      _useStateModel.pageCount.value = theData?.pageCount ?? 0;
      _useStateModel.playPause.value = false;
      _useStateModel.constantFastSpeed.value = false;
      // Future.delayed(Duration.zero, () {
      //   _useStateModel.handwritingKey.currentState?.ref.read(jobHandwritingDrawingTrajectoryProvider.notifier).setVal([]);
      // });
      // _useStateModel.handwritingDetail.value = _useStateModel.getHandwritingDetail(theData);
    });

    useValueChanged<int?, void>(_useStateModel.pageNum.value, (oldVal, __) {
      if (oldVal != null && oldVal != _useStateModel.pageNum.value) {
        _useStateModel.questionNo = null;
        // _useStateModel.getData().catchError((e) => closeCall());
      }
    });

    JobHandwriting? data = _useStateModel.handwritingData.value;
    HandwritingInfo? dataDetail = _useStateModel.handwritingDetail.value;

    // if (data == null || dataDetail == null) return Container();

    return Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        SizedBox(
          height: imageHeight,
          width: boxWidth,
          child: Stack(
            alignment: const FractionalOffset(0, 0.5),
            children: [
              // 图片展示主框
              SingleChildScrollView(
                child: HandwritingDrawBox(
                  boxWidth: boxWidth,
                  boxHeight: boxHeight,
                  key: _useStateModel.handwritingKey,
                ),
              ),
              PageNumberBox(),
              PreviousNutton(), // 上一页按钮
              NextPageButton(), // 下一题按钮
            ],
          ),
        ),
        $BottomPlaybar(barHeight, handwritingLogic),
      ],
    );
  }
}

class UseMainBoxState with RequestToolMixin {
  final String homeworkId;
  final int studentId;
  final int? templateId;
  String? questionNo;
  final ValueNotifier<int?> pageNum;
  final ValueNotifier<int> pageCount;
  final ValueNotifier<JobHandwriting?> handwritingData;
  final ValueNotifier<HandwritingInfo?> handwritingDetail;

  final ValueNotifier<bool> playPause; // 播放暂停
  final ValueNotifier<bool> constantFastSpeed; // 原速、快速  默认原速

  GlobalKey<_HandwritingDrawBoxState> handwritingKey;

  UseMainBoxState._({
    required this.homeworkId,
    required this.templateId,
    required this.studentId,
    required this.pageNum,
    required this.handwritingData,
    required this.questionNo,
    required this.pageCount,
    required this.playPause,
    required this.constantFastSpeed,
    required this.handwritingDetail,
    required this.handwritingKey,
  });

  // 工厂构造函数
  factory UseMainBoxState.use(String homeworkId, int studentId,
      [int? pageNum, String? questionNo, int? templateId]) {
    return UseMainBoxState._(
      homeworkId: homeworkId,
      templateId: templateId,
      studentId: studentId,
      questionNo: questionNo,
      pageNum: useState(pageNum),
      handwritingData: useState(null),
      handwritingDetail: useState(null),
      pageCount: useState(0),
      playPause: useState(false),
      constantFastSpeed: useState(false),
      handwritingKey: GlobalKey(),
    );
  }
}

/// 上一页
class PreviousNutton extends StatelessWidget {
  PreviousNutton({super.key});

  final HandwritingLogic handwritingLogic = Get.find<HandwritingLogic>();

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      if (handwritingLogic.resultData.value?.pageNum != null &&
          handwritingLogic.resultData.value!.pageNum > 1) {
        return Positioned(
          left: 3.w,
          child: FloatingActionButton(
            heroTag: '点击前往上一题',
            tooltip: '点击前往上一题',
            focusColor: Theme.of(context).primaryColor,
            backgroundColor: const Color.fromRGBO(24, 32, 32, 0.1),
            elevation: 6.r,
            onPressed: () => easyThrottle('answer_handwriting_previous', () {
              var resultData = handwritingLogic.resultData.value;
              var params = handwritingLogic.params.value;
              if (resultData == null || params == null) return;
              params.pageNum = resultData.pageNum - 1;
              params.templateId = null;
              params.questionNo = null;
              handwritingLogic.params.value =
                  OriginalManuscriptHandwritingParams.fromJson(params.toJson());
              // handwritingLogic.params.value = params;
            }),
            child: Icon(Icons.arrow_back_ios, color: Colors.white, size: 22.sp),
          ),
        );
      }

      return const SizedBox();
    });
  }
}

/// 下一页
class NextPageButton extends StatelessWidget {
  final HandwritingLogic handwritingLogic = Get.find<HandwritingLogic>();

  NextPageButton({super.key});

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      if (handwritingLogic.resultData.value?.pageNum != null &&
          handwritingLogic.resultData.value!.pageNum <
              handwritingLogic.resultData.value!.pageCount) {
        return Positioned(
          right: 3.w,
          child: FloatingActionButton(
            heroTag: '点击前往下一题',
            tooltip: '点击前往下一题',
            elevation: 6.r,
            backgroundColor: const Color.fromRGBO(24, 32, 32, 0.1),
            onPressed: () => easyThrottle('answer_handwriting_next', () {
              var resultData = handwritingLogic.resultData.value;
              var params = handwritingLogic.params.value;
              if (resultData == null || params == null) return;
              params.pageNum = resultData.pageNum + 1;
              params.templateId = null;
              params.questionNo = null;
              handwritingLogic.params.value =
                  OriginalManuscriptHandwritingParams.fromJson(params.toJson());
            }),
            child:
                Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp),
          ),
        );
      }

      return const SizedBox();
    });
  }
}

// 笔记还原主框
class HandwritingDrawBox extends StatefulWidget {
  final double boxWidth;
  final double boxHeight;
  const HandwritingDrawBox(
      {required this.boxWidth, required this.boxHeight, super.key});

  @override
  State<HandwritingDrawBox> createState() => _HandwritingDrawBoxState();
}

class _HandwritingDrawBoxState extends State<HandwritingDrawBox>
    with EventBusMixin {
  HandwritingLogic handwritingLogic = Get.find<HandwritingLogic>(); // 学生答题笔迹逻辑层

  ImageStream? imageStream; // 图片监听数据
  late ImageStreamListener theImageStreamListener; // 试题图片数据

  late ValueNotifier<List<GestureHandwritingRecording>> _vnHandWritings;
  late ValueNotifier<List<GestureHandwritingRecording>> _vnPrimaryHandWritings;

  late StreamSubscription showManuscriptStream;
  late StreamSubscription executionDataStream;

  List<List<GestureHandwritingRecording>> _packagedHandwritingDatas = [];
  List<GestureHandwritingRecording> _packagedHandwritingDataAll = []; // 总数据
  List<GestureHandwritingRecording> pendingData = []; // 待执行数据
  List<Timer> timers = [];
  int handwritingTime = 0;
  int handwritingDuration = 0;
  double speed = 2.0; // 播放速度

  @override
  void initState() {
    super.initState(); /*  */

    theImageStreamListener = ImageStreamListener((ImageInfo info, bool _) {
      // 获取图片的宽高
      WidgetsBinding.instance.addPostFrameCallback((_) {
        //需要创建的小组件
        handwritingLogic.imagInfoModel.value = TestQuestionsImageInfo(
          url: handwritingLogic.resultData.value!.paperPicture,
          boxWidth: widget.boxWidth,
          boxHeight: widget.boxHeight,
          imageWidth: info.image.width.toDouble(),
          imageHeight: info.image.height.toDouble(),
        );
      });
    });

    _vnHandWritings = ValueNotifier<List<GestureHandwritingRecording>>([]);
    _vnPrimaryHandWritings = ValueNotifier<List<GestureHandwritingRecording>>(
        _packagedHandwritingDataAll);

    handwritingLogic.toolbar.initialization.listen((e) {
      // 数据初始化完成赋值数据
      if (e) {
        _packagedHandwritingDatas =
            handwritingLogic.packagedHandwritingDatas.value;
        _packagedHandwritingDataAll =
            handwritingLogic.packagedHandwritingDataAll.value;
      } else {
        _packagedHandwritingDatas = [];
        _packagedHandwritingDataAll = [];
      }

      // _vnPrimaryHandWritings.is
      try {
        _vnPrimaryHandWritings.value = [..._packagedHandwritingDataAll]; // 总体数据
      } catch (e) {
        _vnPrimaryHandWritings =
            ValueNotifier<List<GestureHandwritingRecording>>(
                _packagedHandwritingDataAll);
      }
      // eventFire(model: JobHandwritingPlaybarBus);
    });
    showManuscriptStream = handwritingLogic.toolbar.showManuscript.listen((e) {
      // 查看原稿控制
      if (e) {
        // 查看原稿
        eventFire(model: JobHandwritingPlaybarBus(false)); // 暂停
        _vnPrimaryHandWritings.value = [..._packagedHandwritingDataAll];
      } else {
        // 清空原稿数据
        _vnPrimaryHandWritings.value = [];
      }
    });

    executionDataStream = handwritingLogic.toolbar.executionData.listen((e) {
      try {
        _vnHandWritings.value = e;
      } catch (e1) {
        _vnHandWritings = ValueNotifier<List<GestureHandwritingRecording>>(e);
      }
    });

    eventOn(callback: (e) {
      switch (e.runtimeType) {
        case JobHandwritingRunTimeBus:
          var _model = (e as JobHandwritingRunTimeBus);
          var _runtime = _model.runTimeVal;
          handwritingDuration = _model.totalVal;
          handwritingTime = _runtime;
          if (_runtime <= 0) {
            pendingData.clear();
          }
          break;
        case JobHandwritingDragProgressBarBus:
          var _model = (e as JobHandwritingDragProgressBarBus);
          dragProgressBarInitData(_model.changeVal, _model.totalVal);
          break;
        case JobHandwritingPlaybarBus:
          // 播放 暂停
          var _val = e as JobHandwritingPlaybarBus;
          if (_val.play) {
            // 播放
            toGoPlay();
          } else {
            // 暂停
            toGoPause(_val.recalculate);
          }
          break;
        case PlaybackSpeedBus:
          // 播放速度
          var _model = (e as PlaybackSpeedBus);
          speed = _model.speed;
          dragProgressBarInitData(
              handwritingDuration - handwritingTime, handwritingDuration);
          break;
        default:
      }
    });
  }

  @override
  void dispose() {
    imageStream?.removeListener(theImageStreamListener);
    _vnHandWritings.dispose();
    _vnPrimaryHandWritings.dispose();
    showManuscriptStream.cancel();
    executionDataStream.cancel();
    eventCancel();
    super.dispose();
  }

  // 暂停播放
  Future<void> toGoPause(bool recalculate) async {
    timers.forEach((e) {
      if (e.isActive) e.cancel();
    });
    timers = [];
    // 总时间-剩余时间=已经执行时间
    if (recalculate &&
        pendingData.isNotEmpty &&
        handwritingTime > 0 &&
        (handwritingDuration - handwritingTime > 0)) {
      // 待执行的数据不等于空 每个数据都需要减去当前暂停已经执行的时间
      pendingData = pendingData.map((e) {
        return GestureHandwritingRecording(
          stroke: e.stroke,
          data: e.data,
          usageTime: e.usageTime,
          intervalTime:
              e.intervalTime - (handwritingDuration - handwritingTime) * 1000,
        );
      }).toList();
    }
  }

  /// 开始播放
  Future<void> toGoPlay() async {
    try {
      var executableData = _packagedHandwritingDataAll;
      if (pendingData.isNotEmpty) {
        // 待执行的数据没有执行完成 就继续执行待执行数据
        executableData = pendingData;
      } else {
        // 需要重新添加所有数据进行播放
        pendingData.addAll(_packagedHandwritingDataAll);
        handwritingLogic.toolbar.executionData.value = []; // 重置已经执行的数据
      }
      handwritingLogic.toolbar.showManuscript.value = false;
      executableData.forEach((e) {
        var ter = Timer(Duration(milliseconds: e.intervalTime ~/ speed),
            () => zhixinCall(e));
        timers.add(ter);
      });
    } catch (e) {
      print('播放报错：$e');
    }
  }

  Future<void> zhixinCall(GestureHandwritingRecording e) async {
    if (mounted) {
      List<GestureHandwritingRecording> trajectorys =
          handwritingLogic.toolbar.executionData.value..add(e);
      handwritingLogic.toolbar.executionData.value = List.from(trajectorys);
      pendingData.remove(e); // 执行后删除容器中的当前动作
    }
  }

  /// 拖动进度条后重新初始化数据
  /// @param startTime 起始时间 单位秒
  Future<void> dragProgressBarInitData(int startTime, int totalDuration) async {
    eventFire(model: JobHandwritingPlaybarBus(false, false));
    timers.forEach((e) {
      if (e.isActive) e.cancel();
    });
    timers = [];
    pendingData.clear();

    if (startTime == 0) {
      handwritingLogic.toolbar.executionData.value = []; // 重置已经执行的数据
      pendingData.addAll(_packagedHandwritingDataAll);
    } else {
      // 待执行的数据不等于空 每个数据都需要减去当前暂停已经执行的时间
      startTime = startTime * 1000; // 转为毫秒
      List<GestureHandwritingRecording> executeImmediately = []; // 立即执行数据
      List<GestureHandwritingRecording> waitingExecution = []; // 等待执行数据

      for (var i = 0; i < _packagedHandwritingDataAll.length; i++) {
        var item = _packagedHandwritingDataAll[i];

        if (item.intervalTime < startTime) {
          // 需要直接装配到直接打印的容器
          executeImmediately.add(item);
        } else {
          var intervalTime = item.intervalTime - startTime;
          // 需要等待的数据
          waitingExecution.add(GestureHandwritingRecording(
            stroke: item.stroke,
            data: item.data,
            usageTime: item.usageTime,
            intervalTime: intervalTime,
          ));
        }
      }

      pendingData = waitingExecution;
      handwritingLogic.toolbar.executionData.value = executeImmediately;
    }
    eventFire(model: JobHandwritingPlaybarBus(true));
  }

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      print('进入了....................');
      var paperPicture = handwritingLogic.resultData.value?.paperPicture;
      if (paperPicture == null) return const SizedBox();

      print(
          '显示原稿：${handwritingLogic.toolbar.showManuscript.value} 数据：${_vnPrimaryHandWritings.value.length}');
      return RepaintBoundary(
        child: CustomPaint(
          foregroundPainter: HandWritingDrawingPainter(
            ctrl: handwritingLogic.toolbar.showManuscript.value
                ? _vnPrimaryHandWritings
                : _vnHandWritings,
          ),
          child: $TheCachedNetworkImage(
            imageUrl: paperPicture,
            (context, imageProvider) {
              Image imageWidget =
                  Image(image: imageProvider, fit: BoxFit.contain);
              var imagInfoModel = handwritingLogic.imagInfoModel.value;
              if (imagInfoModel == null ||
                  imagInfoModel.boxWidth != widget.boxWidth) {
                imageStream?.removeListener(theImageStreamListener);
                imageStream =
                    imageWidget.image.resolve(const ImageConfiguration());
                imageStream?.addListener(theImageStreamListener);
              }
              return imageWidget;
            },
          ),
        ),
      );
    });
  }
}

class HandWritingDrawingPainter extends CustomPainter {
  final ValueNotifier<List<GestureHandwritingRecording>> ctrl;
  HandWritingDrawingPainter({required this.ctrl}) : super(repaint: ctrl);
  //[定义画笔]
  final Paint paintBrush = Paint()
    //画笔颜色
    ..color = Colors.black
    //画笔笔触类型
    ..strokeCap = StrokeCap.round
    //是否启动抗锯齿
    ..isAntiAlias = true
    //绘画风格，默认为填充
    // ..style = PaintingStyle.fill
    //画笔的宽度
    ..style = PaintingStyle.stroke
    ..strokeWidth = 0.5.r;

  @override
  void paint(Canvas canvas, Size size) {
    // canvas.drawPoints(PointMode.points, thePoints, paintBrush);
    canvas.save();

    var points = ctrl.value;
    var _length = points.length;
    for (int i = 0; i < _length; i++) {
      GestureHandwritingRecording item = points[i];
      GestureHandwritingRecording? nextItem =
          i + 1 < _length ? points[i + 1] : null;

      Offset offsetData = item.data;
      Offset? nextOffsetData = nextItem?.data;
      if (nextOffsetData != null && item.stroke == nextItem?.stroke) {
        canvas.drawLine(offsetData, nextOffsetData, paintBrush);
      }
    }
    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    if (oldDelegate is HandWritingDrawingPainter) {
      var repaint = ctrl.value.length != oldDelegate.ctrl.value.length ||
          oldDelegate.ctrl.value != ctrl.value;
      print('调用是否绘制：$repaint');
      return repaint;
    }
    return true; // 如果 oldDelegate 不是 MyCustomPainter 的实例，则总是重绘
  }
}

// 页码
class PageNumberBox extends StatelessWidget {
  PageNumberBox({super.key});

  final HandwritingLogic handwritingLogic =
      Get.find<HandwritingLogic>(); // 学生答题笔迹逻辑层

  @override
  Widget build(BuildContext context) {
    return Positioned(
      top: 6.h,
      right: 4.w,
      child: Container(
          padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 2.h),
          decoration: BoxDecoration(
            color: const Color.fromRGBO(0, 0, 0, 0.47),
            borderRadius: BorderRadius.circular(5.r),
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              Obx(() {
                return quickText(
                    '${handwritingLogic.resultData.value?.pageNum ?? 0}',
                    color: Colors.white,
                    size: 11.sp,
                    align: TextAlign.end);
              }),
              quickText('/',
                  color: Colors.white, size: 10.sp, align: TextAlign.end),
              Obx(() {
                return quickText(
                    '${handwritingLogic.resultData.value?.pageCount ?? 0}',
                    color: Colors.white,
                    size: 8.sp,
                    align: TextAlign.end);
              }),
            ],
          )),
    );
  }
}

@hwidget
Widget $bottomPlaybar(
    BuildContext context, double barHeight, HandwritingLogic handwritingLogic) {
  var timeConsuming = useState(0);
  var handwritingInfo = useState<HandwritingInfo?>(null);

  var usePlaybar = UseBottomPlaybar.use(timeConsuming.value);
  useValueChanged<int, void>(timeConsuming.value, (_, __) {
    usePlaybar.playTimingSuspend();
    usePlaybar.playPause.value = false;
    var seds = timeConsuming.value ~/ 1000;
    if ((timeConsuming.value % 1000) > 500) seds += 1;
    usePlaybar.handwritingDuration.value = seds;
    usePlaybar.constantFastSpeed.value = PlaybackSpeed.DOUBLE_SPEED;
  });

  useValueChanged<int, void>(usePlaybar.handwritingDuration.value, (_, __) {
    usePlaybar.useTime.value = usePlaybar.handwritingDuration.value;
  });
  // 播放速度
  useValueChanged<PlaybackSpeed, void>(usePlaybar.constantFastSpeed.value,
      (_, __) {
    usePlaybar.eventFire(
        model: PlaybackSpeedBus(usePlaybar.constantFastSpeed.value.speed));
    // 播放速度变化
    usePlaybar.playTimingSuspend();
    usePlaybar.playTimingStarts();
  });
  // 计时结束监听
  useValueChanged<int, void>(usePlaybar.useTime.value, (_, __) {
    var _runtime = usePlaybar.useTime.value;
    if (_runtime <= 0 || usePlaybar.handwritingDuration.value == _runtime) {
      Future.delayed(
          Duration.zero, () => (usePlaybar.playPause.value = false)); // 初始化播放按钮
    }
    usePlaybar.eventFire(
        model: JobHandwritingRunTimeBus(
            _runtime, usePlaybar.handwritingDuration.value));
  });

  useEffect(() {
    // 初始化
    var initialization = handwritingLogic.toolbar.initialization.listen((e) {
      usePlaybar.handWritingReady.value = e;
    });
    var handwritingInfoStream = handwritingLogic.handwritingInfo.listen((e) {
      // 笔迹数据
      if (e == null) return;
      handwritingInfo.value = e;
      timeConsuming.value = e.timeConsuming;
    });
    usePlaybar.eventOn(callback: (e) {
      switch (e.runtimeType) {
        case JobHandwritingPlaybarBus:
          // 出发播放暂停
          var _val = e as JobHandwritingPlaybarBus;
          if (_val.play) {
            // 开始播放
            usePlaybar.playTimingStarts();
            if (!usePlaybar.playPause.value) usePlaybar.playPause.value = true;
          } else {
            // 暂停播放
            usePlaybar.playTimingSuspend();
            if (usePlaybar.playPause.value) usePlaybar.playPause.value = false;
          }
          break;
        case JobHandwritingGetReadyBus:
          // 作业笔迹已经计算好坐标 可以开始播放
          Future.delayed(
              Duration.zero, () => (usePlaybar.handWritingReady.value = true));
          break;
        default:
      }
    });

    return () {
      try {
        initialization.cancel();
        usePlaybar.eventCancel();
        handwritingInfoStream.cancel();
        usePlaybar.timer.value?.cancel();
      } catch (e) {
        print(e);
      }
    };
  }, []);

  return Container(
    height: barHeight,
    padding: EdgeInsets.symmetric(horizontal: 10.w),
    alignment: Alignment.center,
    color: const Color.fromRGBO(0, 0, 0, 0.4),
    child: Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        if (usePlaybar.handWritingReady.value)
          InkWell(
            onTap: () => easyThrottle('job_handwriting_play_pause', () {
              if (usePlaybar.handwritingDuration.value == 0)
                return ToastUtils.showInfo('没有笔迹');

              usePlaybar.playPause.value = !usePlaybar.playPause.value;
              usePlaybar.eventFire(
                  model: JobHandwritingPlaybarBus(usePlaybar.playPause.value));
            }),
            child: Icon(
              !usePlaybar.playPause.value
                  ? Icons.play_circle_outline
                  : Icons.pause_circle_outline,
              color: Colors.white,
              size: 28.r,
            ),
          )
        else
          SpinKitPouringHourGlassRefined(size: 40.sp, color: Colors.white),
        SizedBox(width: 6.w),
        Expanded(
          child: LayoutBuilder(builder: (context, constraints) {
            final double containerWidth = constraints.maxWidth; // 展示区域总宽度
            var unitScale = containerWidth / timeConsuming.value; // 单位刻度
            var pauseIntervalsLength =
                handwritingInfo.value?.pauseInterval.length ?? 0;

            List<Widget> pauseTickMarks =
                handwritingInfo.value?.pauseInterval.asMap().keys.map((e) {
                      bool isLast = e == pauseIntervalsLength - 1;
                      bool isFirst = e == 0;
                      var item = handwritingInfo.value!.pauseInterval[e];
                      return Positioned(
                        top: 0,
                        left: unitScale * item.startTime,
                        child: Container(
                          width: unitScale * (item.apart ?? 0),
                          height: 10.h,
                          decoration: BoxDecoration(
                            color: Color.fromRGBO(202, 201, 201, 1),
                            borderRadius: isFirst
                                ? BorderRadius.only(
                                    topLeft: Radius.circular(8.r),
                                    bottomLeft: Radius.circular(10.r))
                                : (isLast
                                    ? BorderRadius.only(
                                        topRight: Radius.circular(8.r),
                                        bottomRight: Radius.circular(10.r))
                                    : null),
                          ),
                        ),
                      );
                    }).toList() ??
                    [];

            return Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Stack(
                  children: [
                    Container(
                      height: 10.h,
                      width: containerWidth,
                      decoration: BoxDecoration(
                        // color: Color.fromRGBO(146, 146, 146, 1),
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(50.r),
                      ),
                    ),
                    ...pauseTickMarks,
                    Container(
                      height: 10.h,
                      width: containerWidth,
                      // color: Theme.of(context).primaryColor,
                      child: SliderTheme(
                        data: SliderTheme.of(context).copyWith(
                          trackHeight: 10.h, // 轨道高度
                          trackShape:
                              RoundedRectSliderTrackShape(), // 轨道形状，可以自定义
                          activeTrackColor:
                              Theme.of(context).primaryColor, // 激活的轨道颜色
                          inactiveTrackColor: Colors.transparent, // 未激活的轨道颜色
                          thumbShape: RoundSliderThumbShape(
                              enabledThumbRadius: 0, disabledThumbRadius: 0),
                          thumbColor: Colors.white, // 滑块颜色
                          overlayShape:
                              RoundSliderOverlayShape(overlayRadius: 0),
                          overlayColor: Colors.black54, // 滑块外圈颜色
                          // valueIndicatorShape: PaddleSliderValueIndicatorShape(), // 标签形状，可以自定义
                        ),
                        child: Slider(
                          value: (usePlaybar.handwritingDuration.value -
                                  usePlaybar.useTime.value)
                              .toDouble(),
                          min: 0.0,
                          max: usePlaybar.handwritingDuration.value.toDouble(),
                          inactiveColor: Colors.transparent,
                          onChangeEnd: (value) {
                            if (!usePlaybar.handWritingReady.value) return;
                            usePlaybar.playTimingSuspend(); // 暂停计时器得暂停
                            usePlaybar.eventFire(
                                model: JobHandwritingDragProgressBarBus(
                                    value.toInt(),
                                    usePlaybar.handwritingDuration.value));
                            usePlaybar.useTime.value =
                                usePlaybar.handwritingDuration.value -
                                    value.toInt();
                          },
                          onChanged: (double value) {
                            if (!usePlaybar.handWritingReady.value) return;
                            usePlaybar.useTime.value =
                                usePlaybar.handwritingDuration.value -
                                    value.toInt();
                          },
                        ),
                      ),
                    ),
                  ],
                ),
                SizedBox(height: 8.h),
                SizedBox(
                  width: containerWidth,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      quickText(
                          '累计停顿：${handwritingInfo.value?.pauseCount ?? 0}次',
                          color: Colors.white,
                          size: 7.sp),
                      quickText(
                          convertSeconds(usePlaybar.useTime.value)
                                  ?.toString() ??
                              '',
                          color: Colors.white,
                          size: 7.sp),
                    ],
                  ),
                )
              ],
            );
          }),
        ),
        SizedBox(width: 16.w),
        Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            InkWell(
              onTap: () => easyThrottle('job_handwriting_speed', () {
                var theIndex = PlaybackSpeed.values
                    .indexOf(usePlaybar.constantFastSpeed.value);
                if (theIndex == PlaybackSpeed.values.length - 1) {
                  theIndex = -1;
                }
                usePlaybar.constantFastSpeed.value =
                    PlaybackSpeed.values[theIndex + 1];
              }, duration: Duration(milliseconds: 500)),
              child: Container(
                // alignment: Alignment.,
                padding: EdgeInsets.symmetric(horizontal: 3.w, vertical: 1.5.h),
                decoration: BoxDecoration(
                    color: Color.fromRGBO(182, 197, 250, 1),
                    borderRadius: BorderRadius.circular(4.r)),
                child: quickText(
                  '${usePlaybar.constantFastSpeed.value.name}',
                  color: Color.fromRGBO(79, 114, 244, 1),
                  size: 8.sp,
                  align: TextAlign.center,
                ),
              ),
            ),
            SizedBox(height: 7.h),
            StudentManuscriptBtn(handwritingLogic),
          ],
        ),
      ],
    ),
  );
}

// 学生原稿按钮视图
class StudentManuscriptBtn extends StatelessWidget {
  final HandwritingLogic handwritingLogic;
  const StudentManuscriptBtn(this.handwritingLogic, {super.key});

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      return InkWell(
        onTap: () => easyThrottle('job_handwriting_udent_manuscript', () {
          var showManuscript = handwritingLogic.toolbar.showManuscript.value;
          handwritingLogic.toolbar.showManuscript.value = !showManuscript;
        }),
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 3.w, vertical: 1.5.h),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(4.r),
            color: handwritingLogic.toolbar.showManuscript.value
                ? Theme.of(context).primaryColor
                : Colors.grey,
          ),
          child: quickText('学生原稿',
              color: Colors.white, size: 8.sp, align: TextAlign.center),
        ),
      );
    });
  }
}

class SysjTime extends StatefulWidget {
  const SysjTime({super.key});

  @override
  State<SysjTime> createState() => _SysjTimeState();
}

class _SysjTimeState extends State<SysjTime>
    with EventBusMixin<JobHandwritingRunTimeBus> {
  int useTime = 0;
  @override
  void initState() {
    super.initState();
    // eventOn(callback: (JobHandwritingRunTimeBus e) {
    //   useTime = e.runTimeVal;
    //   toUpState(setState, () {}, mounted);
    // });
  }

  @override
  void dispose() {
    eventCancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return quickText(convertSeconds(useTime)?.toString() ?? '',
        color: Colors.white, size: 7.sp);
  }
}

class UseBottomPlaybar with EventBusMixin {
  final ValueNotifier<int> handwritingDuration; // 笔迹总时长
  final ValueNotifier<bool> playPause; // 播放暂停
  final ValueNotifier<PlaybackSpeed> constantFastSpeed; // 播放速度
  final ValueNotifier<bool> handWritingReady;

  final ValueNotifier<int> useTime; // 耗时 单位：（秒）

  final ValueNotifier<Timer?> timer;

  UseBottomPlaybar._(
      {required this.handWritingReady,
      required this.handwritingDuration,
      required this.playPause,
      required this.constantFastSpeed,
      required this.useTime,
      required this.timer});

  // 工厂构造函数
  factory UseBottomPlaybar.use(int milliseconds) {
    int handwritingDuration = milliseconds ~/ 1000;
    if ((milliseconds % 1000) > 500) handwritingDuration += 1;
    return UseBottomPlaybar._(
      playPause: useState(false),
      constantFastSpeed: useState(PlaybackSpeed.DOUBLE_SPEED), // 默认两倍速
      useTime: useState(handwritingDuration),
      timer: useState(null),
      handwritingDuration: useState(handwritingDuration),
      handWritingReady: useState(false),
    );
  }

  /// 开始计时
  void playTimingStarts() {
    if (useTime.value > 0) {
      timer.value?.cancel();

      timer.value = Timer.periodic(
          Duration(milliseconds: 1000 ~/ constantFastSpeed.value.speed),
          (theTime) {
        useTime.value -= 1;
        if (useTime.value < 0) {
          theTime.cancel();
          timer.value?.cancel();
          timer.value = null;
          useTime.value = handwritingDuration.value;
        }
      });
    }
  }

  /// 暂停
  void playTimingSuspend() {
    timer.value?.cancel();
    timer.value = null;
  }
}
