import 'package:hmg_patient_app/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:intl/intl.dart';

class DynamicResultChart extends StatelessWidget {
  final List<DataPoint> dataPoints;
  final List<ThresholdRange> thresholds;
  final double? width;
  final double height;
  final double? maxY;
  final double? maxX;

  final Axis scrollDirection;
  final bool showBottomTitleDates;
  final bool isFullScreeGraph;

  DynamicResultChart(
      {super.key, required this.dataPoints, required this.thresholds, this.width, required this.scrollDirection, required this.height, this.maxY,this.maxX, this.showBottomTitleDates = true, this.isFullScreeGraph = false});

  @override
  Widget build(BuildContext context) {
    var minY = 0.0;
    // var maxY = 0.0;
    double interval = 20;
    if((maxY??0)>10 &&(maxY??0)<=20) interval = 2;
    else if((maxY??0)>5 &&(maxY??0)<=10) interval = 1;
    else if((maxY??0)>=0 &&(maxY??0)<=5) interval = .4;
    // else  if((maxY??0)>=100) interval = 20;

    // if (thresholds.isNotEmpty) {
    //   print("the thresholds are $thresholds");
    //   minY = thresholds.first.value;
    //   maxY = thresholds.last.value + 1;
    // } else {
    //   return SizedBox.shrink();
    // }

    final spots = dataPoints.asMap().entries.map((entry) {
      return FlSpot(entry.key.toDouble(), entry.value.value);
    }).toList();
    final widthPerPoint = 30.0; // Customize as needed
    final chartWidth = (dataPoints.length + 1) * widthPerPoint;

    return Material(
        color: Colors.white,
        child: SizedBox(
          width: width,
          height: height,
          child: Padding(
            padding: const EdgeInsets.only(top: 8.0, bottom: 8),
            child: LineChart(
              LineChartData(
                minY: 0,
                maxY: ((maxY?.ceilToDouble()??0.0)+interval ).floorToDouble(),
                // minX: dataPoints.first.labelValue - 1,
                maxX: maxX,
                lineTouchData: LineTouchData(touchTooltipData: LineTouchTooltipData(getTooltipItems: (touchedSpots) {
                  if (touchedSpots.isEmpty) return [];

                  // Only show tooltip for the first touched spot, hide others
                  return touchedSpots.map((spot) {
                    if (spot == touchedSpots.first) {
                      final dataPoint = dataPoints[spot.x.toInt()];

                      if (dataPoint.isStringResource) {
                        return LineTooltipItem(
                          '${double.parse(dataPoint.actualValue).toStringAsFixed(2)}',
                          const TextStyle(color: Colors.white),
                        );
                      }

                      return LineTooltipItem(
                        // '${dataPoint.label} ${spot.y.toStringAsFixed(2)}',
                        '${dataPoint.label} ${double.parse(dataPoint.actualValue).toStringAsFixed(2)}',
                        const TextStyle(color: Colors.white),
                      );
                    }
                    return null; // hides the rest
                  }).toList();
                })),
                titlesData: FlTitlesData(
                  leftTitles: AxisTitles(

                      sideTitles : SideTitles(
                        showTitles: true,
                        reservedSize: 50,
                        interval: interval,
                        getTitlesWidget: (value, meta) {
                          // Skip the last (maxY) label
                          if (value == ((maxY?.ceilToDouble()??0.0)+interval ).floorToDouble()) {
                            return const SizedBox.shrink();
                          }
                          return Text(
                            value.toStringAsFixed(1),
                            style: const TextStyle(fontSize: 10),
                          );
                        },
                      )


                  ),
                  // leftTitles: AxisTitles(
                  //   sideTitles: SideTitles(
                  //     showTitles: true,
                  //     reservedSize: 77,
                  //     interval: .1, // Let fl_chart handle it
                  //     getTitlesWidget: (value, _) {
                  //       // print("the value is ======== ${value}");
                  //
                  //       // Compare with 2-decimal precision to avoid close duplicates
                  //       final matchingThreshold = thresholds.firstWhere(
                  //         (t) => t.value.toStringAsFixed(1) == value.toStringAsFixed(1),
                  //         orElse: () => ThresholdRange(label: '', value: 0, color: Colors.transparent, lineColor: Colors.transparent),
                  //       );
                  //
                  //       var actualValue = (matchingThreshold.actualValue != null)
                  //           ? "${TranslationBase.of(context).getTranslation(matchingThreshold.label)} (${matchingThreshold.actualValue})"
                  //           : '${TranslationBase.of(context).getTranslation(matchingThreshold.label)}';
                  //       if (matchingThreshold.label.isNotEmpty) {
                  //         return Text(
                  //           "${value.toStringAsFixed(0)}",
                  //           style: const TextStyle(fontSize: 10),
                  //         );
                  //       }
                  //       return const SizedBox.shrink();
                  //     },
                  //   ),
                  // ),
                  bottomTitles: AxisTitles(
                    axisNameSize: 60,
                    sideTitles: SideTitles(
                      showTitles: showBottomTitleDates,
                      reservedSize: 50,
                      getTitlesWidget: (value, _) {
                        if (value.toInt() >= 0 && value.toInt() < dataPoints.length) {
                          var label = dataPoints[value.toInt()].label;
                          if (dataPoints[value.toInt()].isStringResource) {
                            label = TranslationBase.of(context).getTranslation(dataPoints[value.toInt()].label);
                          }

                          return Padding(
                            padding: EdgeInsetsDirectional.only(
                              top: 8.0,
                            ),
                            child: Text(
                              label,
                              style: const TextStyle(fontSize: 12),
                            ),
                          );
                        }
                        return const SizedBox.shrink();
                      },
                      interval: 1, // ensures 1:1 mapping with spots
                    ),
                  ),
                  topTitles: AxisTitles(),
                  rightTitles: AxisTitles(),
                ),
                borderData: FlBorderData(show: true,border: const Border(
                  bottom: BorderSide(
                    color: Colors.grey,
                    width: 0.5,
                  ),
                  left: BorderSide(
                      color: Colors.grey,
                      width: .5
                  ),
                  right:BorderSide.none,
                  top: BorderSide.none,
                ),),
                lineBarsData: _buildColoredLineSegments(dataPoints, thresholds),
                gridData: FlGridData(show: true, drawVerticalLine: false, getDrawingHorizontalLine:(value)=> FlLine(color: Colors.grey, strokeWidth: 0.5)),
                // extraLinesData: ExtraLinesData(
                //     horizontalLines: [
                //   HorizontalLine(
                //   color: Colors.black,
                //   strokeWidth: 2,
                //   dashArray: [5, 5], // optional: dashed line
                //   label: HorizontalLineLabel(
                //     show: true,
                //     alignment: Alignment.centerRight,
                //     style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
                //     labelResolver: (line) => 'Threshold ${line.y.toInt()}',
                //   ),
                // ),
                // ],
                // ),
                // rangeAnnotations: RangeAnnotations(
                //   horizontalRangeAnnotations: _buildRangeShades(thresholds),
                // ),
              ),
            ),
          ),
        ));
  }

  List<LineChartBarData> _buildColoredLineSegments(List<DataPoint> dataPoints, List<ThresholdRange> thresholds) {
    List<LineChartBarData> segments = [];
    Color getColor(String value) {
      for (int i = thresholds.length - 1; i >= 0; i--) {
        if (value == thresholds[i].label) {
          return  thresholds[i].lineColor;
        }
      }
      return Colors.grey;
    }

    for (int i = 0; i < dataPoints.length - 1; i++) {
      final dp1 = dataPoints[i];
      final dp2 = dataPoints[i + 1];

      final spot1 = FlSpot(i.toDouble(), dp1.value);
      final spot2 = FlSpot((i + 1).toDouble(), dp2.value);

      final color1 = getColor(dp1.referenceRangeValue);
      final color2 = getColor(dp2.referenceRangeValue);

      segments.add(LineChartBarData(
        spots: [spot1, spot2],
        isCurved: true,
        isStrokeCapRound: true,
        isStrokeJoinRound: true,
        gradient: LinearGradient(
          colors: [color1, color2],
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
        ),
        // dotData: FlDotData(
        //       show: true,
        //       getDotPainter: (spot, _, __, index) {
        //         final value = spot.y;
        //         final color = getColor(value);
        //         return FlDotCirclePainter(
        //           radius: 4,
        //           color: color,
        //           strokeWidth: 1,
        //           strokeColor: Colors.white,
        //         );
        //       },
        //     ),
      )
      );
    }

    // Add dot markers separately so they are on top

    final List<FlSpot> allSpots = dataPoints.asMap().entries.map((entry) {
      return FlSpot(entry.key.toDouble(), entry.value.value);
    }).toList();

    var data = [
      // ...segments
      LineChartBarData(
        spots: allSpots,
        isCurved: true,
        isStrokeCapRound: true,
        isStrokeJoinRound: true,
        barWidth: 2,
        gradient: LinearGradient(
          colors: [Color(0xFF5dc36b), Color(0xFF5dc36b)],
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
        ),
        dotData: FlDotData(
          show: true,
          getDotPainter: (spot, _, __, index) {
            final value = spot.y;
            final color = Color(0xFF5dc36b);
            return FlDotCirclePainter(
              radius: 4,
              color: color,
              strokeWidth: 1,
              strokeColor: Colors.white,
            );
          },
        ),
      )
    ];

    // var max = LineChartHelper.calculateMaxAxisValues(data).maxX;
    // print("the maxX is the -------> $max");
    return data;
  }

  List<HorizontalRangeAnnotation> _buildRangeShades(List<ThresholdRange> thresholds) {
    List<HorizontalRangeAnnotation> ranges = [];
    for (int i = 0; i < thresholds.length - 1; i++) {
      ranges.add(HorizontalRangeAnnotation(
        y1: thresholds[i].value,
        y2: thresholds[i + 1].value,
        color: thresholds[i].color,
      ));
    }
    return ranges;
  }
}

final List<DataPoint> sampleData = [
  DataPoint(value: 1.4, label: 'Jan 2024', date: DateTime(2024, 1, 1)),
  DataPoint(value: 3.6, label: 'Feb 2024', date: DateTime(2024, 2, 1)),
  DataPoint(value: 1.96, label: 'This result', date: DateTime(2024, 3, 1)),
];
final List<ThresholdRange> thresholdLevels = [
  ThresholdRange(label: 'Critical Low', value: 1.4, color: Color(0xfff6e9e9), lineColor: Color(0xFFe9a2a4)),
  ThresholdRange(label: 'Low', value: 3.6, color: Color(0xFFf2fbf5), lineColor: Color(0xFFeecd94)),
  ThresholdRange(label: 'Normal', value: 5.96, color: Color(0xFFf2fbf5), lineColor: Color(0xFF5dc36b)),
  ThresholdRange(label: 'High', value: 7.15, color: Color(0xfff6e9e9), lineColor: Color(0xFFeecd94)),
  ThresholdRange(label: 'Critical High', value: 10.15, color: Color(0xfff6e9e9), lineColor: Color(0xFFe9a2a4)),
];

class DataPoint {
  final double value;
  double labelValue;
  String label;
  String actualValue;
  final DateTime date;
  bool isStringResource;
  String referenceRangeValue;

  DataPoint({required this.value, required this.label, required this.date, this.isStringResource = false, this.labelValue = 0.0, this.actualValue = "", this.referenceRangeValue= ""});
}

class ThresholdRange {
  final String label;
  final double value;
  final Color color;
  final Color lineColor;
  final String? actualValue;

  ThresholdRange({required this.label, required this.value, required this.color, required this.lineColor, this.actualValue});

  @override
  String toString() {
    return 'ThresholdRange(label: $label, value: $value, color: ${color.value.toRadixString(16)}, lineColor: ${lineColor.value.toRadixString(16)})';
  }
}
