import 'dart:async';
import 'dart:convert';
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'dart:ui' as ui;
import 'index.dart';

class EcgViewController extends GetxController {
  EcgViewController({
    required this.initPoints,
  });

  final List<int> initPoints;

  /// 每秒的数据量
  static int get dataPerSecond => 125;

  /// 更新帧率
  static int updateFrameRate = 25;

  /// 更新周期
  static int updatePeriod = 1000 ~/ updateFrameRate;

  /// 画布时间跨度（秒）
  int get timeSpan => 3;

  /// 横坐标数据量
  int get xDataCount => dataPerSecond * timeSpan;

  /// 所有心电数据
  List<int> allPoints = [];

  /// 需绘制的新数据
  List<int> newPointsToDraw = [];

  /// 需绘制的历史数据
  List<int> oldPointsToDraw = [];

  /// 启动时时间戳
  int startTime = DateTime.now().millisecondsSinceEpoch;

  /// 当前数据位（根据时间戳计算）
  int currentDataIndex = 0;

  /// 数据刷新定时器
  Timer timer = Timer(Duration.zero, () {});

  /// 发生错误时暂停了
  bool isPaused = false;

  /// 读取到数据的回调
  void addData(List<int> data) {
    if (allPoints.isEmpty) {
      startTime = DateTime.now().millisecondsSinceEpoch;
      _startTimer();
    }
    allPoints.addAll(data);
    if (isPaused) {
      isPaused = false;
      _startTimer();
    }
  }

  /// 打开全屏心电图弹窗
  void openFullScreenDialog() {
    Get.dialog(
      const FullScreenEcgDataDialog(),
    );
  }

  // 重置
  void reset() {
    timer.cancel();
    isPaused = false;
    allPoints.clear();
    newPointsToDraw.clear();
    oldPointsToDraw.clear();
    startTime = DateTime.now().millisecondsSinceEpoch;
    currentDataIndex = 0;
    update(['ecg_view']);
  }

  /// 获取完整心电图的base64（带base64头）
  Future<String> getFullDataImageBase64() async {
    final painter = EcgPainterForAll(
      allPoints: allPoints,
      yMax: 600,
    );
    final bgPainter = GridBackgroundPainterForAll();
    const size = Size(5000, 650);
    // 使用离屏Canvas绘制
    final Uint8List? bytes =
        await _capturePainterToImage(painter, bgPainter, size);
    if (bytes == null) {
      return "";
    } else {
      return _convertToBase64Url(bytes);
    }
  }

  /// 开启定时器，每隔一定时间添加一次数据，并且更新UI
  void _startTimer() {
    timer = Timer.periodic(
      Duration(milliseconds: updatePeriod),
      (timer) {
        // print("timer: ${timer.tick}");
        _updateData();
      },
    );
  }

  /// 每帧更新数据
  void _updateData() {
    // 计算当前数据位
    currentDataIndex = (DateTime.now().millisecondsSinceEpoch - startTime) ~/
        (1000 ~/ dataPerSecond);

    /// 需显示的数据量
    int needDataCount = currentDataIndex % xDataCount;

    /// 当前周期数
    int currentPeriod = currentDataIndex ~/ xDataCount;
    // 计算新数据
    try {
      newPointsToDraw = allPoints.sublist(
        currentDataIndex - needDataCount,
        currentDataIndex,
      );
      if (currentPeriod > 0) {
        oldPointsToDraw = allPoints.sublist(
          (currentPeriod - 1) * xDataCount,
          currentPeriod * xDataCount,
        );
      }
      if (currentDataIndex >= dataPerSecond * 30) {
        timer.cancel();
        isPaused = true;
      }
      // print(
      //     "update newPointsToDraw: ${currentDataIndex} ${needDataCount} ${newPointsToDraw.length} --currentPeriod ${currentPeriod}");
    } catch (e) {
      timer.cancel();
      isPaused = true;
    }
    update(['ecg_view']);
  }

  /// 将字节数组转换为base64
  String _convertToBase64Url(Uint8List imageData) {
    String base64Image = base64Encode(imageData);
    String base64Url = base64Image;
    return base64Url;
  }

  /// 将CustomPainter绘制的内容转换为图片
  Future<Uint8List?> _capturePainterToImage(
      CustomPainter painter, CustomPainter bgPainter, Size size) async {
    final bounds = Offset.zero & size;
    final picture = PictureRecorder();
    final pictureCanvas = Canvas(picture);

    // 给Canvas设置绘制范围
    pictureCanvas.clipRect(bounds);

    /// 绘制背景(纯白)
    pictureCanvas.drawColor(Colors.white, BlendMode.color);

    // 在Canvas上进行绘制
    bgPainter.paint(pictureCanvas, size);
    painter.paint(pictureCanvas, size);

    /// 绘制一圈边框
    final borderPaint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.0;
    pictureCanvas.drawRect(bounds, borderPaint);

    // 结束绘制
    final recordedPicture = picture.endRecording();
    final image =
        await recordedPicture.toImage(size.width.toInt(), size.height.toInt());

    // 转换为字节数组
    final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    final bytes = byteData?.buffer.asUint8List();

    return bytes;
  }

  // @override
  // void onInit() {
  //   super.onInit();
  // }

  @override
  void onReady() {
    super.onReady();
    if (initPoints.length >= 3750) {
      newPointsToDraw = initPoints.sublist(3375, 3750);
      update(['ecg_view']);
      allPoints = initPoints;
    } else {
      newPointsToDraw = initPoints;
      update(['ecg_view']);
      allPoints = initPoints;
    }
  }

  @override
  void onClose() {
    super.onClose();
    timer.cancel();
  }
}
