import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get_it/get_it.dart';
import 'package:okane/database/collections/budget.dart';
import 'package:okane/database/database.dart';
import 'package:okane/ui/pages/account/breakdown_card.dart';
import 'package:okane/ui/pages/budgets/add_budget_item.dart';
import 'package:okane/ui/state/core.dart';
import 'package:okane/ui/utils.dart';
import 'package:okane/ui/widgets/piechart.dart';
import 'package:okane/ui/widgets/piechart_card.dart';

class BudgetDetailsPage extends StatelessWidget {
  final bool isPage;

  const BudgetDetailsPage({this.isPage = false, super.key});

  static MaterialPageRoute<void> get mobileRoute =>
      MaterialPageRoute(builder: (_) => BudgetDetailsPage(isPage: true));

  void _addBudgetItem(BuildContext context, CoreState state) {
    showDialogOrModal(
      context: context,
      builder:
          (_) => AddBudgetItemPopup(
            budget: state.activeBudget!,
            onDone: () {
              Navigator.of(context).pop();
            },
          ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        children: [
          if (isPage)
            SizedBox(
              height: 50,
              child: Row(
                children: [
                  IconButton(
                    icon: Icon(Icons.arrow_back),
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                  ),
                ],
              ),
            ),

          BlocBuilder<CoreCubit, CoreState>(
            builder: (context, state) {
              if (state.activeBudget == null) {
                return Text("No budget selected");
              }

              if (state.activeBudget!.items.isEmpty) {
                return Row(
                  children: [
                    Text("No budget items added"),
                    Padding(
                      padding: EdgeInsets.only(left: 16),
                      child: IconButton(
                        onPressed: () => _addBudgetItem(context, state),
                        icon: Icon(Icons.add),
                      ),
                    ),
                  ],
                );
              }

              final bloc = GetIt.I.get<CoreCubit>();
              final today = DateTime.now();
              return FutureBuilder(
                future: getTransactionsInTimeframe(
                  bloc.activeAccount!,
                  today,
                  TransactionQueryDateOption.thisMonth,
                ),
                builder: (context, snapshot) {
                  final daysLeft = switch (state.activeBudget!.period) {
                    BudgetPeriod.month =>
                      monthEnding(today).difference(today).inDays,
                  };

                  if (!snapshot.hasData) {
                    return Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Text(
                          "Budget items",
                          style: Theme.of(context).textTheme.titleMedium,
                        ),
                        ListView.builder(
                          shrinkWrap: true,
                          itemCount: state.activeBudget!.items.length,
                          itemBuilder: (context, index) {
                            final item = state.activeBudget!.items.elementAt(
                              index,
                            );
                            final amount = formatCurrency(item.amount);
                            return ListTile(
                              title: Text(
                                "${item.expenseCategory.value!.name} ($amount)",
                              ),
                              subtitle: Text("..."),
                            );
                          },
                        ),
                      ],
                    );
                  }

                  final categories =
                      state.activeBudget!.items
                          .map((i) => i.expenseCategory.value!.name)
                          .toList();
                  final spending = <String, double>{};
                  for (final t in snapshot.data!) {
                    String categoryName;
                    if (!categories.contains(t.expenseCategory.value?.name)) {
                      if (!state.activeBudget!.includeOtherSpendings) {
                        continue;
                      }

                      categoryName = "Other";
                    } else {
                      categoryName = t.expenseCategory.value!.name;
                    }

                    spending.update(
                      categoryName,
                      (value) => value + t.amount,
                      ifAbsent: () => t.amount,
                    );
                  }

                  final totalSpent =
                      spending.isEmpty
                          ? 0
                          : spending.values.reduce((acc, val) => acc + val);
                  final budgetTotal = state.activeBudget!.items
                      .map((i) => i.amount)
                      .reduce((acc, val) => acc + val);
                  return Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      SizedBox(
                        height: 100,
                        child: ListView(
                          scrollDirection: Axis.horizontal,
                          children: [
                            Padding(
                              padding: EdgeInsets.all(8),
                              child: SizedBox(
                                height: 100,
                                width: 150,
                                child: Card(
                                  child: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.center,
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: [
                                      Text(
                                        "Days left",
                                        textAlign: TextAlign.center,
                                        style:
                                            Theme.of(
                                              context,
                                            ).textTheme.titleLarge,
                                      ),
                                      Text(
                                        daysLeft.toString(),
                                        textAlign: TextAlign.center,
                                        style:
                                            Theme.of(
                                              context,
                                            ).textTheme.bodyLarge,
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                            Padding(
                              padding: EdgeInsets.all(8),
                              child: SizedBox(
                                height: 100,
                                width: 150,
                                child: Card(
                                  child: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.center,
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: [
                                      Text(
                                        "Budget left",
                                        textAlign: TextAlign.center,
                                        style:
                                            Theme.of(
                                              context,
                                            ).textTheme.titleLarge,
                                      ),
                                      Text(
                                        formatCurrency(
                                          budgetTotal + totalSpent,
                                        ),
                                        textAlign: TextAlign.center,
                                        style:
                                            Theme.of(
                                              context,
                                            ).textTheme.bodyLarge,
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                            Padding(
                              padding: EdgeInsets.all(8),
                              child: SizedBox(
                                height: 100,
                                width: 150,
                                child: Card(
                                  child: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.center,
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: [
                                      Text(
                                        "Budget total",
                                        textAlign: TextAlign.center,
                                        style:
                                            Theme.of(
                                              context,
                                            ).textTheme.titleLarge,
                                      ),
                                      Text(
                                        formatCurrency(budgetTotal),
                                        textAlign: TextAlign.center,
                                        style:
                                            Theme.of(
                                              context,
                                            ).textTheme.bodyLarge,
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),

                      Wrap(
                        children: [
                          Padding(
                            padding: EdgeInsets.symmetric(horizontal: 8),
                            child: PieChartCard(
                              fallbackText: "",
                              valueConverter: formatCurrency,
                              items:
                                  state.activeBudget!.items
                                      .map(
                                        (i) => (
                                          title: i.expenseCategory.value!.name,
                                          value: i.amount,
                                          color: colorHash(
                                            i.expenseCategory.value!.name,
                                          ),
                                        ),
                                      )
                                      .toList(),
                              titleText: "Budget breakdown",
                            ),
                          ),

                          Padding(
                            padding: EdgeInsets.symmetric(horizontal: 8),
                            child: PieChartCard(
                              fallbackText: "No spending available",
                              valueConverter: formatCurrency,
                              items:
                                  spending.entries
                                      .map(
                                        (e) => (
                                          title: e.key,
                                          value: e.value.abs(),
                                          color: colorHash(e.key),
                                        ),
                                      )
                                      .toList(),
                              titleText: "Spending Breakdown",
                            ),
                          ),
                        ],
                      ),

                      Padding(
                        padding: EdgeInsets.all(8),
                        child: Row(
                          children: [
                            Text(
                              "Budget items",
                              style: Theme.of(context).textTheme.titleMedium,
                            ),
                            Padding(
                              padding: EdgeInsets.only(left: 16),
                              child: IconButton(
                                icon: Icon(Icons.add),
                                onPressed: () => _addBudgetItem(context, state),
                              ),
                            ),
                          ],
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.all(8),
                        child: ListView.builder(
                          shrinkWrap: true,
                          itemCount: state.activeBudget!.items.length,
                          itemBuilder: (context, index) {
                            final item = state.activeBudget!.items.elementAt(
                              index,
                            );
                            final amount = formatCurrency(item.amount);
                            final spent =
                                spending[item.expenseCategory.value!.name];
                            final left =
                                spent == null
                                    ? item.amount
                                    : item.amount + spent;
                            final subtitleText =
                                left < 0
                                    ? "${formatCurrency(left)} over"
                                    : "${formatCurrency(left)} left";
                            return ListTile(
                              title: Text(
                                "${item.expenseCategory.value!.name} ($amount)",
                              ),
                              subtitle: Text(
                                subtitleText,
                                style: TextStyle(
                                  color: left < 0 ? Colors.red : Colors.green,
                                ),
                              ),
                              trailing: IconButton(
                                icon: Icon(Icons.delete),
                                onPressed: () {},
                              ),
                            );
                          },
                        ),
                      ),
                    ],
                  );
                },
              );
            },
          ),
        ],
      ),
    );
  }
}