import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:krezus/domains/category/category_bloc.dart';
import 'package:krezus/domains/charts/models/month_totals.dart';

class MonthlyCategoriesTotalChart extends StatelessWidget {
  final Map<int, MonthTotals> categoriesMonthlyTotals;

  const MonthlyCategoriesTotalChart({super.key, required this.categoriesMonthlyTotals});

  BarChartRodData _computeStack(double barsWidth, Map<String, double> entry, Map<String, Color> categoriesColors) {
    var subcounter = 0.0;
    var items = entry.entries.map((subEntry) => BarChartRodStackItem(
      subcounter, subcounter += subEntry.value,
      categoriesColors[subEntry.key] ?? Colors.red,
    )).toList();
    return BarChartRodData(
      color: Colors.transparent,
      fromY: 0,
      toY: subcounter,
      width: barsWidth,
      borderRadius: BorderRadius.circular(3),
      rodStackItems: items
    );
  }

  List<BarChartGroupData> _computeBarGroups(double barsSpace, double barsWidth, Map<String, Color> categoriesColors, bool smallVerticalScreen) {
    var a = categoriesMonthlyTotals.entries
      .map((entry) {
        return BarChartGroupData(
          x: entry.key,
          barsSpace: barsSpace,
          barRods: [
            _computeStack(barsWidth, entry.value.positives, categoriesColors),
            _computeStack(barsWidth, entry.value.negatives, categoriesColors),
          ],
          showingTooltipIndicators: smallVerticalScreen ? [] : [0, 1]
        );
      })
      .toList();
    return a;
  }

  SideTitleWidget _computeBottomTitles(double value, TitleMeta meta) {
    const titles = ['Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Juin', 'Jui', 'Aou', 'Sep', 'Oct', 'Nov', 'Dec'];
    String title = titles[value.toInt() - 1];

    return SideTitleWidget(
      axisSide: meta.axisSide,
      child: Text(title)
    );
  }

  double _computeMaxValue() {
    double max = 0.0;
    categoriesMonthlyTotals.forEach((monthKey, value) { 
      double localMax = value.maxValue();
      if (localMax > max) {
        max = localMax;
      }
    });
    return max + (max / 10);
  }

  @override
  Widget build(BuildContext context) {
    bool smallVerticalScreen = MediaQuery.sizeOf(context).width < 800;
    return BlocBuilder<CategoryBloc, CategoryState>(
      builder: (context, state) => AspectRatio(
        aspectRatio: 1.66,
        child: LayoutBuilder(
          builder: (context, constraints) {
            final barsSpace = 4.0 * constraints.maxWidth / 300;
            final barsWidth = 8.0 * constraints.maxWidth / 500;

            return BarChart(
              BarChartData(
                maxY: _computeMaxValue(),
                barGroups: _computeBarGroups(barsSpace, barsWidth, state.categoriesColors, smallVerticalScreen),
                titlesData: FlTitlesData(
                  topTitles: const AxisTitles(
                    sideTitles: SideTitles(showTitles: false)
                  ),
                  bottomTitles: AxisTitles(
                    sideTitles: SideTitles(
                      showTitles: true,
                      getTitlesWidget: _computeBottomTitles
                    )
                  )
                ),
                barTouchData: BarTouchData(
                  enabled: true,
                  handleBuiltInTouches: false,
                  touchTooltipData: BarTouchTooltipData(
                    tooltipBgColor: Colors.transparent,
                    tooltipMargin: 0,
                    getTooltipItem:(group, groupIndex, rod, rodIndex) {
                      String value = NumberFormat("#00").format(rod.toY);
                      Color color = Colors.black;
                      if (rodIndex == 0) {
                        value = "+$value";
                        color = Theme.of(context).colorScheme.primary;
                      } else {
                        value = "-$value";
                        color = Theme.of(context).colorScheme.error;
                      }

                      return BarTooltipItem(
                        value,
                        TextStyle(
                          fontWeight: FontWeight.bold,
                          color: color,
                          fontSize: 12,
                          fontFamily: 'NovaMono',
                          shadows: const [
                            Shadow(
                              color: Colors.black26,
                              blurRadius: 12,
                            )
                          ],
                        ),
                      );
                    }
                  )
                )
              )
            );
          },
        )
      )
    );
  }
}