import 'dart:async';

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

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

/// Stellt eine filterbare Liste der Transaktionen dar
class TransactionList extends StatefulWidget {
  /// Erstellt eine neue Instanz dieser Klasse
  const TransactionList({
    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() => _TransactionListState();
}

class _TransactionListState extends State<TransactionList> {
  final TransactionController _transactionController = TransactionController();
  final AccountController _accountController = AccountController();

  final TransactionRepository _transactionRepository = TransactionRepository();

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

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

  @override
  Widget build(final BuildContext context) => FutureBuilder(
    future: _transactionRepository.findBy(
      name: widget.name,
      amountMin: widget.amountMin,
      amountMax: widget.amountMax,
      dateFrom: widget.dateFrom,
      dateTo: (widget.dateTo != null) ? widget.dateTo : DateTime.now(),
      account: _accountController.selected.value,
      orderBy: 'dateDesc',
    ),
    builder:
        (
          final BuildContext context,
          final AsyncSnapshot<List<Transaction>> snapshot,
        ) {
          final ThemeData theme = Theme.of(context);

          if (snapshot.hasData) {
            final transactionsByMonth = <String, List<Transaction>>{};
            for (final Transaction transaction in snapshot.data!) {
              final DateTime date = transaction.date!;
              final DateFormat format = DateFormat('MMMM');

              final monthName = '${format.format(date)} ${date.year}';
              transactionsByMonth
                  .putIfAbsent(monthName, () => [])
                  .add(transaction);
            }

            return Expanded(
              child: CustomScrollView(
                slivers: transactionsByMonth.entries
                    .map(
                      (
                        final MapEntry<String, List<Transaction>> entry,
                      ) => SliverStickyHeader(
                        header: Container(
                          color: theme.colorScheme.surface,
                          padding: const EdgeInsets.symmetric(
                            horizontal: 16,
                            vertical: 8,
                          ),
                          alignment: Alignment.centerLeft,
                          child: Text(
                            entry.key,
                            style: const TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: 16,
                            ),
                          ),
                        ),
                        sliver: SliverList(
                          delegate: SliverChildBuilderDelegate((
                            final BuildContext context,
                            final int index,
                          ) {
                            final Transaction transaction = entry.value[index];

                            return ListTile(
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                              onTap: () {
                                unawaited(
                                  _transactionController.editTransactionHandler(
                                    transaction.id,
                                  ),
                                );
                              },
                              contentPadding: EdgeInsets.zero,
                              title: Text(
                                transaction.name,
                                style: (transaction.checked)
                                    ? const TextStyle()
                                    : TextStyle(color: theme.colorScheme.error),
                              ),
                              subtitle: Text(
                                '${transaction.date?.day}'
                                '.${transaction.date?.month}'
                                '.${transaction.date?.year}',
                              ),
                              trailing: Text(
                                '${transaction.amount.abs().toStringAsFixed(2)}'
                                ' €',
                                style: TextStyle(
                                  color: transaction.amount >= 0
                                      ? Colors.red
                                      : Colors.green,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            );
                          }, childCount: entry.value.length),
                        ),
                      ),
                    )
                    .toList(),
              ),
            );
          } else if (snapshot.hasError) {
            return Center(
              child: Column(
                children: [
                  Icon(Icons.error, color: theme.colorScheme.error),
                  const Text('Fehler beim holen der Transaktionen!'),
                ],
              ),
            );
          } else {
            return const Center(child: CircularProgressIndicator());
          }
        },
  );
}
