import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:hmg_patient_app_new/core/common_models/data_points.dart';
import 'package:hmg_patient_app_new/core/utils/size_utils.dart';
import 'package:hmg_patient_app_new/theme/colors.dart';
///
/// CustomGraph(dataPoints: sampleData, scrollDirection: Axis.horizontal,height: 200,maxY: 100, maxX:2.5,
///               leftLabelFormatter: (value){
///                 Widget buildLabel(String label) {
///                   return Padding(
///                     padding: const EdgeInsets.only(right: 8),
///                     child: Text(
///                       label,
///                       style: TextStyle(
///                           fontSize: 8.fSize, color: AppColors.textColor,
///                       fontFamily:
///                       FontUtils.getFontFamilyForLanguage(false)
///                       ),
///                       textAlign: TextAlign.right,
///                     ),
///                   );
///                 }
///                 switch (value.toInt()) {
///
///                   case 20:
///                     return buildLabel("Critical Low");
///                   case 40:
///                     return buildLabel("Low");
///                   case 60:
///                     return buildLabel("Normal");
///                   case 80:
///                     return buildLabel("High");
///                   case 100:
///                     return buildLabel("Critical High");
///                 }
///                 return const SizedBox.shrink();
///               },
///
///             ),
class CustomGraph extends StatelessWidget {
  final List<DataPoint> dataPoints;
  final double? width;
  final double height;
  final double? maxY;
  final double? maxX;
  final Color spotColor;
  final Color graphColor;
  final Color graphShadowColor;
  final Color graphGridColor;
  final Color bottomLabelColor;
  final double? bottomLabelSize;
  final FontWeight? bottomLabelFontWeight;

  ///creates the left label and provide it to the chart as it will be used  by other part of the application so the label will be different for every chart
  final Widget Function(double value) leftLabelFormatter;

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

  const CustomGraph({
    super.key,
    required this.dataPoints,
    required this.leftLabelFormatter,
    this.width,
    required this.scrollDirection,
    required this.height,
    this.maxY,
    this.maxX,
    this.showBottomTitleDates = true,
    this.isFullScreeGraph = false,
    this.spotColor = AppColors.bgGreenColor,
    this.graphColor = AppColors.bgGreenColor,
    this.graphShadowColor = AppColors.graphGridColor,
    this.graphGridColor = AppColors.graphGridColor,
    this.bottomLabelColor = AppColors.textColor,
    this.bottomLabelFontWeight = FontWeight.w500,
    this.bottomLabelSize,
  });

  @override
  Widget build(BuildContext context) {
    // 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;
    }
    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,
                minX: -0.2,
                lineTouchData: LineTouchData(
                  getTouchLineEnd: (_, __) => 0,
                  getTouchedSpotIndicator: (barData, indicators) {
                    // Only show custom marker for touched spot
                    return indicators.map((int index) {
                      return TouchedSpotIndicatorData(
                        FlLine(color: Colors.transparent),
                        FlDotData(
                          show: true,
                          getDotPainter: (spot, percent, barData, idx) {
                            return FlDotCirclePainter(
                              radius: 8,
                              color: spotColor,
                              strokeWidth: 2,
                              strokeColor: Colors.white,
                            );
                          },
                        ),
                      );
                    }).toList();
                  },
                  enabled: true,
                  touchTooltipData: LineTouchTooltipData(
                    getTooltipColor: (_) => Colors.white,
                    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()];

                          return LineTooltipItem(
                            // '${dataPoint.label} ${spot.y.toStringAsFixed(2)}',
                            '${dataPoint.value} ',
                            TextStyle(
                                color: Colors.black,
                                fontSize: 12.fSize,
                                fontWeight: FontWeight.w500),
                          );
                        }
                        return null; // hides the rest
                      }).toList();
                    },
                  ),
                ),
                titlesData: FlTitlesData(
                  leftTitles: AxisTitles(
                    sideTitles: SideTitles(
                      showTitles: true,
                      reservedSize: 77,
                      interval: .1, // Let fl_chart handle it
                      getTitlesWidget: (value, _) {
                        return leftLabelFormatter(value);
                      },
                    ),
                  ),
                  bottomTitles: AxisTitles(
                    axisNameSize: 60,
                    sideTitles: SideTitles(
                      showTitles: showBottomTitleDates,
                      reservedSize: 50,
                      getTitlesWidget: (value, _) {
                        if ((value.toDouble() >= 0) &&
                            (value.toDouble() < (maxX ?? dataPoints.length))) {
                          var label = dataPoints[value.toInt()].label;

                          return buildBottomLabel(label);
                        }
                        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.none,
                    left: BorderSide(color: Colors.grey, width: .5),
                    right: BorderSide.none,
                    top: BorderSide.none,
                  ),
                ),
                lineBarsData: _buildColoredLineSegments(dataPoints),
                gridData: FlGridData(
                  show: true,
                  drawVerticalLine: false,
                  horizontalInterval: 20,
                  checkToShowHorizontalLine: (value) =>
                      value >= 0 && value <= 100,
                  getDrawingHorizontalLine: (value) {
                    return FlLine(
                      color: AppColors.graphGridColor,
                      strokeWidth: 1,
                      dashArray: [5, 5],
                    );
                  },
                ),
              ),
            ),
          ),
        ));
  }

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

    var data = [
      LineChartBarData(
        spots: allSpots,
        isCurved: true,
        isStrokeCapRound: true,
        isStrokeJoinRound: true,
        barWidth: 4,
        gradient: LinearGradient(
          colors: [graphColor, graphColor],
          begin: Alignment.centerLeft,
          end: Alignment.centerRight,
        ),
        dotData: FlDotData(
          show: false,
        ),
        belowBarData: BarAreaData(
          show: true,
          gradient: LinearGradient(
            colors: [
              graphShadowColor,
              Colors.transparent,
            ],
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
          ),
        ),
      )
    ];

    return data;
  }

  // Widget buildLabel(String label) {
  //   return Padding(
  //     padding: const EdgeInsets.only(right: 8),
  //     child: Text(
  //       label,
  //       style: TextStyle(
  //           fontSize: leftLabelSize ?? 8.fSize, color: leftLabelColor),
  //       textAlign: TextAlign.right,
  //     ),
  //   );
  // }

  Widget buildBottomLabel(String label) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Text(
        label,
        style: TextStyle(
            fontSize: bottomLabelSize ?? 8.fSize, color: bottomLabelColor),
      ),
    );
  }
}

final List<DataPoint> sampleData = [
  DataPoint(
    value: 20,
    label: 'Jan 2024',
  ),
  DataPoint(
    value: 36,
    label: 'Feb 2024',
  ),
  DataPoint(
    value: 80,
    label: 'This result',
  ),
];
