"""budget_pro.py, M3 solution.

The M2 budget categorizer, grown up:
  • organized into FUNCTIONS (reusable, named blocks)
  • READS the expenses from a file (expenses.txt) instead of hard-coding them
  • uses an installed LIBRARY (rich) to print a nice table
  • SAVES the result as JSON (expenses_categorized.json)
  • survives mistakes with try / except

Run (inside your activated virtual environment, from this folder):
    python budget_pro.py
"""

import json                       # built-in: read/write JSON (no install needed)
from rich.console import Console  # installed library: pretty terminal output
from rich.table import Table

console = Console()


def load_expenses(path):
    """Read 'item, amount' lines from a file into a list of dictionaries.

    Bad lines are skipped with a warning; a missing file is handled gracefully.
    """
    expenses = []
    try:
        with open(path) as f:                 # 'with' closes the file automatically
            for line in f:
                line = line.strip()           # remove the trailing newline / spaces
                if not line or line.startswith("#"):
                    continue                  # skip blank lines and comments
                try:
                    item, amount = line.split(",")        # "Coffee, 4.50" -> two pieces
                    expenses.append({"item": item.strip(), "amount": float(amount)})
                except ValueError:
                    # split() didn't give two pieces, or float() couldn't parse the amount
                    console.print(f"[yellow]Skipping bad line:[/yellow] {line!r}")
    except FileNotFoundError:
        console.print(f"[red]Could not find the file:[/red] {path}")
    return expenses


def categorize(amount):
    """Turn an amount into a size label. (The M2 decision, now a reusable function.)"""
    if amount < 5:
        return "small"
    elif amount < 50:
        return "medium"
    else:
        return "big"


def total_spent(expenses):
    """Add up every amount in the list."""
    total = 0
    for expense in expenses:
        total += expense["amount"]
    return total


def save_json(expenses, path):
    """Write the list of dictionaries to a file as JSON text."""
    with open(path, "w") as f:
        json.dump(expenses, f, indent=2)
    console.print(f"[green]Saved[/green] {path}")


def main():
    expenses = load_expenses("expenses.txt")
    if not expenses:
        console.print("No expenses to show. Add some lines to expenses.txt and try again.")
        return

    table = Table(title="Your budget")
    table.add_column("Item")
    table.add_column("Amount", justify="right")
    table.add_column("Size")

    for expense in expenses:
        expense["size"] = categorize(expense["amount"])   # add the decision into the dict
        table.add_row(expense["item"], f"${expense['amount']:.2f}", expense["size"])

    console.print(table)
    console.print(f"Total: [bold]${total_spent(expenses):.2f}[/bold] across {len(expenses)} items")

    save_json(expenses, "expenses_categorized.json")


if __name__ == "__main__":   # only runs when you launch this file directly
    main()
