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

import '../../Controller/account_controller.dart';
import '../../Controller/transaction_controller.dart';
import '../../Repositories/transaction_repository.dart';

/// Stellt einen Chart des Monats-Kontostands dar
class MonthlyBalanceChart extends StatefulWidget {
  /// Erstellt eine neue Instanz dieser Klasse
  const MonthlyBalanceChart({
    super.key,
    this.amountMax,
    this.amountMin,
    this.dateFrom,
    this.dateTo,
    this.name,
  });

  /// Der Name der Transaktion, nach der gesucht werden soll
  final String? name;

  /// Der Mindestbetrag der Transaktion, nach der gesucht werden soll
  final double? amountMin;

  /// Der Maximalbetrag der Transaktion, nach der gesucht werden soll
  final double? amountMax;

  /// Das Datum der Transaktionen, ab dem gestartet wurde
  final DateTime? dateFrom;

  ///Das Datum der Transaktionen, bis zu welchen beendet wurde
  final DateTime? dateTo;

  @override
  State<StatefulWidget> createState() => _MonthlyBalanceChart();
}

class _MonthlyBalanceChart extends State<MonthlyBalanceChart> {
  final TransactionRepository _transactionRepository = TransactionRepository();

  final AccountController _accountController = AccountController();
  final TransactionController _transactionController = TransactionController();

  @override
  void initState() {
    super.initState();

    _transactionController.transactions.addListener(() {
      if (mounted) {
        setState(() {});
      }
    });
  }

  @override
  Widget build(final BuildContext context) => FutureBuilder(
    future: _transactionRepository.monthlyBalances(
      account: _accountController.selected.value,
      name: widget.name,
      amountMin: widget.amountMin,
      amountMax: widget.amountMax,
      dateFrom: widget.dateFrom,
      dateTo: (widget.dateTo != null) ? widget.dateTo : DateTime.now(),
    ),
    builder:
        (
          final BuildContext context,
          final AsyncSnapshot<List<Map<String, dynamic>>> snapshot,
        ) {
          final ThemeData theme = Theme.of(context);
          final MediaQueryData mediaQuery = MediaQuery.of(context);

          if (snapshot.hasData) {
            final List<Map<String, dynamic>> monthlyBalances = snapshot.data!;

            double maxBalance = 0;
            double minBalance = 0;

            for (final value in monthlyBalances) {
              if (maxBalance < value['balance']) {
                maxBalance = value['balance'];
              }

              if (minBalance > value['balance']) {
                minBalance = value['balance'];
              }
            }

            return SizedBox(
              height: 180,
              child: LineChart(
                LineChartData(
                  minY: minBalance,
                  maxY: maxBalance,
                  titlesData: FlTitlesData(
                    topTitles: const AxisTitles(),
                    rightTitles: const AxisTitles(),
                    bottomTitles: AxisTitles(
                      sideTitles: SideTitles(
                        showTitles: true,
                        reservedSize: 28,
                        interval: 1,
                        getTitlesWidget:
                            (final double value, final TitleMeta meta) {
                              final List<String> months = monthlyBalances.map((
                                final value,
                              ) {
                                final DateTime date = value['date'];
                                final DateFormat format = DateFormat('MMMM');

                                String month = format.format(date);

                                if (mediaQuery.size.width < 470) {
                                  month = month.substring(0, 1);
                                } else if (mediaQuery.size.width < 920) {
                                  month = month.substring(0, 3);
                                }

                                return month;
                              }).toList();

                              if (value.toInt() >= 0 &&
                                  value.toInt() < months.length) {
                                return Text(months[value.toInt()]);
                              }
                              return const Text('');
                            },
                      ),
                    ),
                    leftTitles: AxisTitles(
                      sideTitles: SideTitles(
                        showTitles: true,
                        reservedSize: 50,
                        getTitlesWidget:
                            (final double value, final TitleMeta meta) => Text(
                              '${value.toInt()} €',
                              style: const TextStyle(fontSize: 12),
                            ),
                      ),
                    ),
                  ),
                  lineBarsData: <LineChartBarData>[
                    LineChartBarData(
                      spots: List<FlSpot>.generate(
                        monthlyBalances.length,
                        (final int index) => FlSpot(
                          index.toDouble(),
                          monthlyBalances[index]['balance'],
                        ),
                      ),
                      isCurved: true,
                      barWidth: 3,
                      color: theme.colorScheme.primary,
                    ),
                  ],
                ),
              ),
            );
          } else if (snapshot.hasError) {
            return Center(
              child: Column(
                children: [
                  Icon(Icons.error, color: theme.colorScheme.error),
                  const Text('Fehler beim holen der Monatsübersicht!'),
                ],
              ),
            );
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        },
  );
}
