// Flutter
import 'package:flutter/material.dart';
import '/models/item_type.dart';

// Local
import '/db.dart';
import '/widgets/cards.dart';
import '/models/tracked_item.dart';

/// TODO:
/// - Projected Assets:
///   - Allow customization?
///   - Fix bug where editing an item does not reflect immediately when returning to Reports page.
///     - Currently reflects after going back to Reports the 2nd time.

double _assetTotal = 0,
    _expenseMonthly = 0,
    _expenseYearly = 0,
    _incomeMonthly = 0,
    _incomeYearly = 0;

class ProjectionPage extends StatefulWidget {
  const ProjectionPage({
    super.key,
  });

  @override
  State<ProjectionPage> createState() => _ProjectionPageState();
}

class _ProjectionPageState extends State<ProjectionPage> {
  @override
  Widget build(BuildContext context) {
    // Summaries for display as well as calculation of totals for projections.
    Widget expenseSummary = SummaryCardForTotals(
      list: DatabaseHelper.instance.getExpenses(),
      summaryTypeLabel: ItemType.expense.title,
    );
    Widget incomeSummary = SummaryCardForTotals(
      list: DatabaseHelper.instance.getIncomes(),
      summaryTypeLabel: ItemType.income.title,
    );
    Widget assetSummary = SummaryCardForTotals(
      list: DatabaseHelper.instance.getAssets(),
      summaryTypeLabel: ItemType.asset.title,
    );

    // Calculations for the projections.
    double oneMonth = _assetTotal + _incomeMonthly - _expenseMonthly,
        threeMonths = _assetTotal + (3 * (_incomeMonthly - _expenseMonthly)),
        sixMonths = _assetTotal + (6 * (_incomeMonthly - _expenseMonthly)),
        oneYear = _assetTotal + (_incomeYearly - _expenseYearly),
        twoYears = _assetTotal + (2 * (_incomeYearly - _expenseYearly)),
        fiveYears = _assetTotal + (5 * (_incomeYearly - _expenseYearly));

    // Widgets to show the projections.
    Widget proj1 = SummaryCard(
      name: "One month from now...",
      leftText: "",
      middleText: oneMonth.toStringAsFixed(2),
      rightText: "",
    );
    Widget proj2 = SummaryCard(
      name: "Three months from now...",
      leftText: "",
      middleText: threeMonths.toStringAsFixed(2),
      rightText: "",
    );
    Widget proj3 = SummaryCard(
      name: "Half a year from now...",
      leftText: "",
      middleText: sixMonths.toStringAsFixed(2),
      rightText: "",
    );
    Widget proj4 = SummaryCard(
      name: "One year from now...",
      leftText: "",
      middleText: oneYear.toStringAsFixed(2),
      rightText: "",
    );
    Widget proj5 = SummaryCard(
      name: "Two years from now...",
      leftText: "",
      middleText: twoYears.toStringAsFixed(2),
      rightText: "",
    );
    Widget proj6 = SummaryCard(
      name: "Five years from now...",
      leftText: "",
      middleText: fiveYears.toStringAsFixed(2),
      rightText: "",
    );

    // Return all of the UI elements.
    return ListView(
      children: [
        TitleCard(title: "Summaries"),
        expenseSummary,
        incomeSummary,
        assetSummary,
        TitleCard(title: "Projections"),
        proj1,
        proj2,
        proj3,
        proj4,
        proj5,
        proj6,
      ],
    );
  }
}

class SummaryCardForTotals extends StatelessWidget {
  const SummaryCardForTotals({
    super.key,
    required this.list,
    required this.summaryTypeLabel,
  });

  final Future<List<TrackedItem>> list;
  final String summaryTypeLabel;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<TrackedItem>>(
        future: list,
        builder: (
          BuildContext context,
          AsyncSnapshot<List<TrackedItem>> snapshot,
        ) {
          if (!snapshot.hasData) {
            return Text('Loading $summaryTypeLabel Section...');
          }

          // Calculate the total fields based on item type.
          double dailyTotal = 0, monthlyTotal = 0, yearlyTotal = 0;
          ItemType? itemType;
          for (TrackedItem e in snapshot.data!) {
            if (itemType == null) {
              itemType = e.type!;
            } else if (itemType != e.type) {
              throw "List in SummaryCardForTotals has multiple item types, abort!";
            }

            if (e.type == ItemType.asset) {
              monthlyTotal += e.amount;
            } else {
              dailyTotal += e.calcComparableAmountDaily();
              monthlyTotal += e.calcComparableAmountYearly() / 12;
              yearlyTotal += e.calcComparableAmountYearly();
            }
          }

          /* Load page variables based on calculated totals. */
          switch (itemType) {
            case null:
              break;

            case ItemType.asset:
              _assetTotal = monthlyTotal;
              break;

            case ItemType.expense:
              _expenseMonthly = monthlyTotal;
              _expenseYearly = yearlyTotal;
              break;

            case ItemType.income:
              _incomeMonthly = monthlyTotal;
              _incomeYearly = yearlyTotal;
              break;

            default:
              throw UnimplementedError(
                "Item type ${itemType!.title} not handled in SummaryCardForTotals!",
              );
          }

          /* Determine what needs displayed for the item type. */
          // Header
          String plural = snapshot.data!.length == 1 ? "" : "s";
          String header = "$summaryTypeLabel Total";
          header += itemType == ItemType.asset ? "" : "s";
          header += " (${snapshot.data!.length} Item$plural)";

          // Total Fields
          String dailyEstimate =
                  dailyTotal.toStringAsFixed(3).endsWith("0") ? "" : "~",
              monthlyEstimate =
                  monthlyTotal.toStringAsFixed(3).endsWith("0") ? "" : "~",
              yearlyEstimate =
                  yearlyTotal.toStringAsFixed(3).endsWith("0") ? "" : "~";
          String leftText = "", middleText = "", rightText = "";
          if (itemType == ItemType.asset) {
            middleText = "$monthlyEstimate${monthlyTotal.toStringAsFixed(2)}";
          } else {
            leftText = "$dailyEstimate${dailyTotal.toStringAsFixed(2)} Daily";
            middleText =
                "$monthlyEstimate${monthlyTotal.toStringAsFixed(2)} Monthly";
            rightText =
                "$yearlyEstimate${yearlyTotal.toStringAsFixed(2)} Yearly";
          }

          // Return the UI element.
          return SummaryCard(
            name: header,
            leftText: leftText,
            middleText: middleText,
            rightText: rightText,
          );
        });
  }
}