import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'dart:ui' as ui;
import 'dart:math';

//根据数据自定义
// class LineChartByRange extends StatefulWidget {
//   final List<Map<String, dynamic>> showLabel;
//   final int startTime;
//   final int endTime;
//   final int? threshold;

//   const LineChartByRange({
//     Key? key,
//     required this.showLabel,
//     required this.startTime,
//     required this.endTime,
//     this.threshold, // 新增
//   }) : super(key: key);

//   @override
//   State<LineChartByRange> createState() => _LineChartByRangeState();
// }

// class _LineChartByRangeState extends State<LineChartByRange> {
//   Offset? selectedOffset;
//   Map<String, dynamic>? selectedData;

//   @override
//   Widget build(BuildContext context) {
//     if (widget.showLabel.isEmpty) return const SizedBox();

//     int maxTimes = widget.showLabel
//         .map((e) => e['times'] ?? 0)
//         .reduce((a, b) => a > b ? a : b);
//     int yMax = (maxTimes / 10).ceil() * 10;
//     if (yMax == 0) yMax = 10;

//     DateTime minTime = DateTime.fromMillisecondsSinceEpoch(widget.startTime);
//     DateTime maxTime = DateTime.fromMillisecondsSinceEpoch(widget.endTime);

//     return GestureDetector(
//       onTapDown: (details) {
//         RenderBox box = context.findRenderObject() as RenderBox;
//         final localPosition = box.globalToLocal(details.globalPosition);

//         // 查找是否点击到某个点
//         for (var item in widget.showLabel) {
//           int start = item['startTime'];
//           int end = item['endTime'];
//           int times = item['times'];

//           double chartWidth = box.size.width - 40.rpx; // 与 painter 内一致处理
//           double chartHeight = box.size.height - 30.rpx;
//           double xStart = 20.rpx + 12.rpx;

//           int totalDuration =
//               maxTime.millisecondsSinceEpoch - minTime.millisecondsSinceEpoch;

//           double startX = xStart +
//               chartWidth *
//                   (start - minTime.millisecondsSinceEpoch) /
//                   totalDuration;
//           double y = chartHeight * (1 - times / yMax);

//           // 判断点击范围（圆点半径±6.rpx范围）
//           if ((localPosition - Offset(startX, y)).distance < 10.rpx) {
//             setState(() {
//               selectedOffset = Offset(startX, y);
//               selectedData = item;
//             });
//             return;
//           }

//           double endX = xStart +
//               chartWidth *
//                   (end - minTime.millisecondsSinceEpoch) /
//                   totalDuration;
//           if ((localPosition - Offset(endX, y)).distance < 10.rpx) {
//             setState(() {
//               selectedOffset = Offset(endX, y);
//               selectedData = item;
//             });
//             return;
//           }
//         }

//         // 没点到，清除选中
//         setState(() {
//           selectedOffset = null;
//           selectedData = null;
//         });
//       },
//       child: Stack(
//         children: [
//           SizedBox(
//             height: 500.rpx,
//             child: CustomPaint(
//               size: Size(double.infinity, 500.rpx),
//               painter: _LineChartByRangePainter(
//                 data: widget.showLabel,
//                 yMax: yMax,
//                 minTime: minTime,
//                 maxTime: maxTime,
//                 threshold: widget.threshold, // 新增
//               ),
//             ),
//           ),
//           if (selectedOffset != null && selectedData != null)
//             Positioned(
//               left: selectedOffset!.dx - 60.rpx,
//               top: selectedOffset!.dy - 50.rpx,
//               child: Container(
//                 padding:
//                     EdgeInsets.symmetric(horizontal: 12.rpx, vertical: 8.rpx),
//                 decoration: BoxDecoration(
//                   color: Colors.black.withOpacity(0.3),
//                   borderRadius: BorderRadius.circular(10.rpx),
//                 ),
//                 child: Text(
//                   '${DateFormat('HH:mm').format(DateTime.fromMillisecondsSinceEpoch(selectedData!['startTime']))} - '
//                   '${DateFormat('HH:mm').format(DateTime.fromMillisecondsSinceEpoch(selectedData!['endTime']))}\n'
//                   '次数: ${selectedData!['times']}',
//                   style: TextStyle(
//                     fontSize: 18.rpx,
//                     color: Colors.white,
//                   ),
//                 ),
//               ),
//             ),
//         ],
//       ),
//     );
//   }
// }

// class _LineChartByRangePainter extends CustomPainter {
//   final List<Map<String, dynamic>> data;
//   final int yMax;
//   final DateTime minTime;
//   final DateTime maxTime;
//   final int? threshold;

//   _LineChartByRangePainter({
//     required this.data,
//     required this.yMax,
//     required this.minTime,
//     required this.maxTime,
//     this.threshold,
//   });

//   @override
//   void paint(Canvas canvas, Size size) {
//     double padding = 20.rpx;
//     double labelInset = 12.rpx;

//     final double xStart = padding + labelInset;
//     final double xEnd = size.width - padding - labelInset;
//     final double chartWidth = xEnd - xStart;

//     double chartHeight = size.height - 30.rpx;

//     int totalDuration =
//         maxTime.millisecondsSinceEpoch - minTime.millisecondsSinceEpoch;
//     if (totalDuration <= 0) return;

//     Paint linePaint = Paint()
//       ..style = PaintingStyle.stroke
//       ..strokeWidth = 3.rpx
//       ..color = stringToColor("#00C1AA")
//       ..strokeCap = StrokeCap.round;

//     Paint axisPaint = Paint()
//       ..color = Colors.grey.withOpacity(0.4)
//       ..strokeWidth = 1.rpx;

//     Paint thresholdPaint = Paint()
//       ..color = themeController.currentColor.sc9
//       ..strokeWidth = 1.rpx;

//     // 1. 阈值虚线（红色）
//     if (threshold != null && threshold! >= 0 && threshold! <= yMax) {
//       double yThreshold = chartHeight * (1 - threshold! / yMax);
//       drawDashedLine(
//         canvas,
//         Offset(xStart, yThreshold),
//         Offset(xEnd, yThreshold),
//         thresholdPaint,
//         dashWidth: 8.rpx,
//         dashSpace: 6.rpx,
//       );
//     }

//     // 2. 绘制数据线段和圆点
//     for (var item in data) {
//       int start = item['startTime'];
//       int end = item['endTime'];
//       int times = item['times'];

//       double startX = xStart +
//           chartWidth * (start - minTime.millisecondsSinceEpoch) / totalDuration;
//       double endX = xStart +
//           chartWidth * (end - minTime.millisecondsSinceEpoch) / totalDuration;
//       double y = chartHeight * (1 - times / yMax);

//       // 设置颜色（根据 threshold 判断）
//       Color pointColor;
//       if (threshold != null && times >= threshold!) {
//         pointColor = themeController.currentColor.sc9;
//       } else {
//         pointColor = stringToColor("#00C1AA");
//       }

//       Paint dynamicLinePaint = Paint()
//         ..style = PaintingStyle.stroke
//         ..strokeWidth = 3.rpx
//         ..color = pointColor
//         ..strokeCap = StrokeCap.round;

//       Paint dynamicCirclePaint = Paint()
//         ..style = PaintingStyle.fill
//         ..color = pointColor;

//       // 画线段
//       canvas.drawLine(Offset(startX, y), Offset(endX, y), dynamicLinePaint);

//       // 画起点和终点圆点
//       canvas.drawCircle(Offset(startX, y), 6.rpx, dynamicCirclePaint);
//       canvas.drawCircle(Offset(endX, y), 6.rpx, dynamicCirclePaint);
//     }

//     // 3. Y轴辅助线和文字
//     for (int i = 0; i <= 6; i++) {
//       double y = chartHeight * i / 6;

//       if (i == 6) {
//         canvas.drawLine(Offset(xStart, y), Offset(xEnd, y), axisPaint);
//       } else {
//         drawDashedLine(
//           canvas,
//           Offset(xStart, y),
//           Offset(xEnd, y),
//           axisPaint,
//           dashWidth: 8.rpx,
//           dashSpace: 6.rpx,
//         );
//       }

//       TextPainter tp = TextPainter(
//         text: TextSpan(
//           text: '${yMax - (yMax * i / 6).round()}',
//           style: TextStyle(
//             fontSize: 18.rpx,
//             color: themeController.currentColor.sc4,
//           ),
//         ),
//         textDirection: ui.TextDirection.ltr,
//       );
//       tp.layout();
//       tp.paint(canvas, Offset(0, y - tp.height / 2));
//     }

//     // 4. X轴主线
//     canvas.drawLine(
//       Offset(xStart, chartHeight),
//       Offset(xEnd, chartHeight),
//       axisPaint,
//     );

//     // 5. X轴时间文字（左右两侧）
//     String leftLabel = DateFormat('HH:mm').format(minTime);
//     TextPainter leftTp = TextPainter(
//       text: TextSpan(
//         text: leftLabel,
//         style: TextStyle(
//           fontSize: 18.rpx,
//           color: themeController.currentColor.sc4,
//         ),
//       ),
//       textDirection: ui.TextDirection.ltr,
//     );
//     leftTp.layout();
//     leftTp.paint(canvas,
//         Offset(padding + labelInset - leftTp.width / 2, chartHeight + 8.rpx));

//     String rightLabel = DateFormat('HH:mm').format(maxTime);
//     TextPainter rightTp = TextPainter(
//       text: TextSpan(
//         text: rightLabel,
//         style: TextStyle(
//           fontSize: 18.rpx,
//           color: themeController.currentColor.sc4,
//         ),
//       ),
//       textDirection: ui.TextDirection.ltr,
//     );
//     rightTp.layout();
//     rightTp.paint(
//         canvas,
//         Offset(size.width - padding - labelInset - rightTp.width / 2,
//             chartHeight + 8.rpx));

//     // 6. 中间小时刻度
//     int totalHours = maxTime.difference(minTime).inHours + 1;
//     int startHour = minTime.hour;

//     for (int i = 1; i < totalHours; i++) {
//       double x = xStart + chartWidth * i / totalHours;

//       int hourLabelNum = (startHour + i) % 24;
//       String hourLabel = '$hourLabelNum';

//       TextPainter tp = TextPainter(
//         text: TextSpan(
//           text: hourLabel,
//           style: TextStyle(
//             fontSize: 18.rpx,
//             color: themeController.currentColor.sc4,
//           ),
//         ),
//         textDirection: ui.TextDirection.ltr,
//       );
//       tp.layout();
//       tp.paint(canvas, Offset(x - tp.width / 2, chartHeight + 8.rpx));
//     }
//   }

//   @override
//   bool shouldRepaint(covariant CustomPainter oldDelegate) => true;

//   void drawDashedLine(
//     Canvas canvas,
//     Offset start,
//     Offset end,
//     Paint paint, {
//     required double dashWidth,
//     required double dashSpace,
//   }) {
//     final dx = end.dx - start.dx;
//     final dy = end.dy - start.dy;
//     final distance = sqrt(dx * dx + dy * dy);
//     final direction = Offset(dx / distance, dy / distance);

//     double drawn = 0;
//     while (drawn < distance) {
//       final from = start + direction * drawn;
//       final to = start + direction * (drawn + dashWidth).clamp(0, distance);
//       canvas.drawLine(from, to, paint);
//       drawn += dashWidth + dashSpace;
//     }
//   }
// }


import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'dart:ui' as ui;
import 'dart:math';

class LineChartByRange extends StatefulWidget {
  final List<Map<String, dynamic>> showLabel;
  final int startTime;
  final int endTime;
  final int? threshold;

  /// 新增外部指定的 Y 轴最大值
  final int maxY;

  /// Y 轴分段数，默认6段
  final int ySegments;

  const LineChartByRange({
    Key? key,
    required this.showLabel,
    required this.startTime,
    required this.endTime,
    required this.maxY,
    this.threshold,
    this.ySegments = 6,
  }) : super(key: key);

  @override
  State<LineChartByRange> createState() => _LineChartByRangeState();
}

class _LineChartByRangeState extends State<LineChartByRange> {
  Offset? selectedOffset;
  Map<String, dynamic>? selectedData;

  @override
  Widget build(BuildContext context) {
    if (widget.showLabel.isEmpty) return const SizedBox();

    DateTime minTime = DateTime.fromMillisecondsSinceEpoch(widget.startTime);
    DateTime maxTime = DateTime.fromMillisecondsSinceEpoch(widget.endTime);

    return GestureDetector(
      onTapDown: (details) {
        RenderBox box = context.findRenderObject() as RenderBox;
        final localPosition = box.globalToLocal(details.globalPosition);

        // 查找是否点击到某个点
        for (var item in widget.showLabel) {
          int start = item['startTime'];
          int end = item['endTime'];
          int times = item['times'];

          double chartWidth = box.size.width - 40.rpx; // 与 painter 内一致处理
          double chartHeight = box.size.height - 30.rpx;
          double xStart = 20.rpx + 12.rpx;

          int totalDuration =
              maxTime.millisecondsSinceEpoch - minTime.millisecondsSinceEpoch;

          double startX = xStart +
              chartWidth *
                  (start - minTime.millisecondsSinceEpoch) /
                  totalDuration;
          double y = chartHeight * (1 - times / widget.maxY);

          // 判断点击范围（圆点半径±6.rpx范围）
          if ((localPosition - Offset(startX, y)).distance < 10.rpx) {
            setState(() {
              selectedOffset = Offset(startX, y);
              selectedData = item;
            });
            return;
          }

          double endX = xStart +
              chartWidth *
                  (end - minTime.millisecondsSinceEpoch) /
                  totalDuration;
          if ((localPosition - Offset(endX, y)).distance < 10.rpx) {
            setState(() {
              selectedOffset = Offset(endX, y);
              selectedData = item;
            });
            return;
          }
        }

        // 没点到，清除选中
        setState(() {
          selectedOffset = null;
          selectedData = null;
        });
      },
      child: Stack(
        children: [
          SizedBox(
            height: 500.rpx,
            child: CustomPaint(
              size: Size(double.infinity, 500.rpx),
              painter: _LineChartByRangePainter(
                data: widget.showLabel,
                maxY: widget.maxY,
                minTime: minTime,
                maxTime: maxTime,
                threshold: widget.threshold,
                ySegments: widget.ySegments,
              ),
            ),
          ),
          if (selectedOffset != null && selectedData != null)
            Positioned(
              left: selectedOffset!.dx - 60.rpx,
              top: selectedOffset!.dy - 50.rpx,
              child: Container(
                padding:
                    EdgeInsets.symmetric(horizontal: 12.rpx, vertical: 8.rpx),
                decoration: BoxDecoration(
                  color: Colors.black.withOpacity(0.3),
                  borderRadius: BorderRadius.circular(10.rpx),
                ),
                child: Text(
                  '${DateFormat('HH:mm').format(DateTime.fromMillisecondsSinceEpoch(selectedData!['startTime']))} - '
                  '${DateFormat('HH:mm').format(DateTime.fromMillisecondsSinceEpoch(selectedData!['endTime']))}\n'
                  "时长".tr+ ' ${selectedData!['times']}',
                  style: TextStyle(
                    fontSize: 18.rpx,
                    color: Colors.white,
                  ),
                ),
              ),
            ),
        ],
      ),
    );
  }
}

class _LineChartByRangePainter extends CustomPainter {
  final List<Map<String, dynamic>> data;
  final int maxY;
  final DateTime minTime;
  final DateTime maxTime;
  final int? threshold;
  final int ySegments;

  _LineChartByRangePainter({
    required this.data,
    required this.maxY,
    required this.minTime,
    required this.maxTime,
    this.threshold,
    this.ySegments = 6,
  });

  @override
  void paint(Canvas canvas, Size size) {
    double padding = 20.rpx;
    double labelInset = 12.rpx;

    final double xStart = padding + labelInset;
    final double xEnd = size.width - padding - labelInset;
    final double chartWidth = xEnd - xStart;

    double chartHeight = size.height - 30.rpx;

    int totalDuration =
        maxTime.millisecondsSinceEpoch - minTime.millisecondsSinceEpoch;
    if (totalDuration <= 0) return;

    Paint axisPaint = Paint()
      ..color = Colors.grey.withOpacity(0.4)
      ..strokeWidth = 1.rpx;

    Paint thresholdPaint = Paint()
      ..color = themeController.currentColor.sc9
      ..strokeWidth = 1.rpx;

    // 阈值虚线（红色）
    if (threshold != null && threshold! >= 0 && threshold! <= maxY) {
      double yThreshold = chartHeight * (1 - threshold! / maxY);
      drawDashedLine(
        canvas,
        Offset(xStart, yThreshold),
        Offset(xEnd, yThreshold),
        thresholdPaint,
        dashWidth: 8.rpx,
        dashSpace: 6.rpx,
      );
    }

    // 绘制数据线段和圆点
    for (var item in data) {
      int start = item['startTime'];
      int end = item['endTime'];
      int times = item['times'];

      double startX = xStart +
          chartWidth * (start - minTime.millisecondsSinceEpoch) / totalDuration;
      double endX = xStart +
          chartWidth * (end - minTime.millisecondsSinceEpoch) / totalDuration;
      double y = chartHeight * (1 - times / maxY);

      // 设置颜色（根据 threshold 判断）
      Color pointColor;
      if (threshold != null && times >= threshold!) {
        pointColor = themeController.currentColor.sc9;
      } else {
        pointColor = stringToColor("#00C1AA");
      }

      Paint dynamicLinePaint = Paint()
        ..style = PaintingStyle.stroke
        ..strokeWidth = 3.rpx
        ..color = pointColor
        ..strokeCap = StrokeCap.round;

      Paint dynamicCirclePaint = Paint()
        ..style = PaintingStyle.fill
        ..color = pointColor;

      // 画线段
      canvas.drawLine(Offset(startX, y), Offset(endX, y), dynamicLinePaint);

      // 画起点和终点圆点
      canvas.drawCircle(Offset(startX, y), 6.rpx, dynamicCirclePaint);
      canvas.drawCircle(Offset(endX, y), 6.rpx, dynamicCirclePaint);
    }

    // Y轴辅助线和文字
    for (int i = 0; i <= ySegments; i++) {
      double y = chartHeight * i / ySegments;

      if (i == ySegments) {
        canvas.drawLine(Offset(xStart, y), Offset(xEnd, y), axisPaint);
      } else {
        drawDashedLine(
          canvas,
          Offset(xStart, y),
          Offset(xEnd, y),
          axisPaint,
          dashWidth: 8.rpx,
          dashSpace: 6.rpx,
        );
      }

      TextPainter tp = TextPainter(
        text: TextSpan(
          text: '${maxY - (maxY * i / ySegments).round()}',
          style: TextStyle(
            fontSize: 18.rpx,
            color: themeController.currentColor.sc4,
          ),
        ),
        textDirection: ui.TextDirection.ltr,
      );
      tp.layout();
      tp.paint(canvas, Offset(0, y - tp.height / 2));
    }

    // X轴主线
    canvas.drawLine(
      Offset(xStart, chartHeight),
      Offset(xEnd, chartHeight),
      axisPaint,
    );

    // X轴时间文字（左右两侧）
    String leftLabel = DateFormat('HH:mm').format(minTime);
    TextPainter leftTp = TextPainter(
      text: TextSpan(
        text: leftLabel,
        style: TextStyle(
          fontSize: 18.rpx,
          color: themeController.currentColor.sc4,
        ),
      ),
      textDirection: ui.TextDirection.ltr,
    );
    leftTp.layout();
    leftTp.paint(canvas,
        Offset(padding + labelInset - leftTp.width / 2, chartHeight + 8.rpx));

    String rightLabel = DateFormat('HH:mm').format(maxTime);
    TextPainter rightTp = TextPainter(
      text: TextSpan(
        text: rightLabel,
        style: TextStyle(
          fontSize: 18.rpx,
          color: themeController.currentColor.sc4,
        ),
      ),
      textDirection: ui.TextDirection.ltr,
    );
    rightTp.layout();
    rightTp.paint(
        canvas,
        Offset(size.width - padding - labelInset - rightTp.width / 2,
            chartHeight + 8.rpx));

    // 中间小时刻度
    int totalHours = maxTime.difference(minTime).inHours + 1;
    int startHour = minTime.hour;

    for (int i = 1; i < totalHours; i++) {
      double x = xStart + chartWidth * i / totalHours;

      int hourLabelNum = (startHour + i) % 24;
      String hourLabel = '$hourLabelNum';

      TextPainter tp = TextPainter(
        text: TextSpan(
          text: hourLabel,
          style: TextStyle(
            fontSize: 18.rpx,
            color: themeController.currentColor.sc4,
          ),
        ),
        textDirection: ui.TextDirection.ltr,
      );
      tp.layout();
      tp.paint(canvas, Offset(x - tp.width / 2, chartHeight + 8.rpx));
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;

  void drawDashedLine(
    Canvas canvas,
    Offset start,
    Offset end,
    Paint paint, {
    required double dashWidth,
    required double dashSpace,
  }) {
    final dx = end.dx - start.dx;
    final dy = end.dy - start.dy;
    final distance = sqrt(dx * dx + dy * dy);
    final direction = Offset(dx / distance, dy / distance);

    double drawn = 0;
    while (drawn < distance) {
      final from = start + direction * drawn;
      final to = start + direction * (drawn + dashWidth).clamp(0, distance);
      canvas.drawLine(from, to, paint);
      drawn += dashWidth + dashSpace;
    }
  }
}
