from datetime import date

from flask import jsonify, request
from sqlalchemy import func

from app.blueprints.api import api_bp
from app.extensions import db
from app.models.budget import Budget
from app.models.category import Category
from app.models.transaction import Transaction


def _parse_month(param):
    today = date.today()
    if param:
        try:
            parts = param.split('-')
            return int(parts[0]), int(parts[1])
        except (AttributeError, IndexError, ValueError):
            pass
    return today.year, today.month


@api_bp.route('/budgets')
def budgets_actuals():
    year, month = _parse_month(request.args.get('month'))
    month_prefix = f'{year}-{month:02d}-%'

    # SQL aggregation — one query, no Python loops over rows
    spent_rows = (
        db.session.query(Transaction.category_id, func.sum(Transaction.amount).label('total'))
        .filter(Transaction.date.like(month_prefix), Transaction.is_credit == False)  # noqa: E712
        .group_by(Transaction.category_id)
        .all()
    )
    spent_map = {row.category_id: float(row.total) for row in spent_rows}

    budgets = Budget.query.filter_by(month=month, year=year).all()
    budget_map = {b.category_id: float(b.amount) for b in budgets}

    categories = Category.query.filter_by(is_active=True).order_by(Category.name).all()
    result = [
        {
            'category': cat.name,
            'budgeted': budget_map.get(cat.id, 0),
            'spent': spent_map.get(cat.id, 0),
        }
        for cat in categories
    ]
    return jsonify(result)
