List<String> _mockInputQueue = [
  '1', // Add Income
  'Salary',
  '2000',
  '2', // Add Expense
  'Rent',
  '800',
  '2', // Add Expense
  'Groceries',
  '-300', // *** Invalid amount (Input Validation Test) ***
  '300', // Valid amount (Accepted after rejection)
  '1', // Add Income
  'Bonus',
  '500',
  '3', // View Summary
  '4', // Exit
];

// Mock function to simulate reading user input from the queue
String? _mockReadLineSync() {
  if (_mockInputQueue.isEmpty) {
    // If the queue is empty, simulate an exit or provide a default to prevent infinite loops.
    print('No more mock inputs. Simulating exit.');
    return '4'; // Simulate exit if no more inputs are available
  }
  String nextInput = _mockInputQueue.removeAt(0);
  // Print the simulated input to the console for traceability
  print('(Mock Input Received: "$nextInput")');
  return nextInput;
}

// Mock function to replace stdout.write for printing prompts
void _mockWrite(String message) {
  print(message);
}

// 3. Data Storage: Use separate Lists of Maps for Income and Expenses (Refactored)
// Note: Using Map<String, dynamic> here to hold both String description and double amount.
List<Map<String, dynamic>> incomeList = [];
List<Map<String, dynamic>> expenseList = [];

// 1. Main Method - Program Entry Point
void main() {
  print('Welcome to the Budget Management Application!');

  // 5. Control Flow & Loops: Main loop to keep asking the user for actions
  var isRunning = true;
  while (isRunning) {
    print('\nPlease choose an option:');
    print('1. Add Income');
    print('2. Add Expense');
    print('3. View Summary');
    print('4. Exit');

    _mockWrite('Your choice: ');
    final choice = _mockReadLineSync();

    // 5. Control Flow & Loops: if/else statements to handle menu options
    if (choice == '1') {
      addTransaction('Income', incomeList); // Pass incomeList
    } else if (choice == '2') {
      addTransaction('Expense', expenseList); // Pass expenseList
    } else if (choice == '3') {
      viewSummary();
    } else if (choice == '4') {
      isRunning = false;
      print('Exiting the application. Goodbye!');
    } else {
      print('Invalid choice. Please select an option from the menu (1-4).');
    }
  }
}

// Function to handle adding an Income or Expense to the correct list (Refactored)
void addTransaction(String type, List<Map<String, dynamic>> list) {
  _mockWrite('Enter $type description: ');
  final description =
      _mockReadLineSync() ?? 'N/A'; // Null-coalescing operator

  double? amount;
  // 4. Input Validation loop (Ensures amount is a positive number)
  while (amount == null || amount <= 0) {
    _mockWrite('Enter $type amount: ');
    final amountInput = _mockReadLineSync();
    amount = double.tryParse(amountInput ?? '');

    // 4. Input Validation: Use logical operators (|| and <=)
    if (amount == null || amount <= 0) {
      print('Invalid amount. Please enter a positive number.');
    }
  }

  list.add({
    'description': description,
    'amount': amount,
  });

  print('$type added!');
}

// Function to calculate and display the summary (Refactored)
void viewSummary() {
  // 7. Arithmetic Operations: Calculate total income
  double totalIncome = 0;
  for (final transaction in incomeList) {
    totalIncome += transaction['amount'] as double;
  }

  // 7. Arithmetic Operations: Calculate total expenses
  double totalExpenses = 0;
  for (final transaction in expenseList) {
    totalExpenses += transaction['amount'] as double;
  }

  final netProfit = totalIncome - totalExpenses;

  print('\n--- Summary ---');
  // 6. String Interpolation: Displaying Income and Expenses
  print('Total Income: \$${totalIncome.toStringAsFixed(2)}');
  print('Total Expenses: \$${totalExpenses.toStringAsFixed(2)}');

  // 6. String Interpolation & Operations: Displaying the net result
  if (netProfit > 0) {
    print('Your net profit is \$${netProfit.toStringAsFixed(2)}');
  } else if (netProfit < 0) {
    final netLoss = netProfit.abs();
    print('Your net loss is \$${netLoss.toStringAsFixed(2)}');
  } else {
    print('You broke even.');
  }

  // 8. Exercise: Tax Calculation
  const taxRate = 0.15; // 15% tax rate

  // 8. Ternary operator: tax is only calculated if netProfit > 0
  final taxAmount = (netProfit > 0) ? (netProfit * taxRate) : 0.0;

  if (taxAmount > 0) {
    print('Tax to be paid (15% of profit): \$${taxAmount.toStringAsFixed(2)}');
  }
  print('-------------------\n');
}