from flask import jsonify, request
from sqlalchemy import func

from app.blueprints.api import api_bp
from app.extensions import db
from app.models.transaction import Transaction
from app.models.category import Category
from app.models.account import Account


@api_bp.route('/transactions')
def transactions_list():
    """
    GET /api/transactions — paginated transaction list with optional filters.
    Query params: page (int), per_page (int), category_id, account_id,
                  date_from, date_to, q (search)
    """
    page = request.args.get('page', 1, type=int)
    per_page = min(request.args.get('per_page', 50, type=int), 200)

    q = (
        Transaction.query
        .order_by(Transaction.date.desc(), Transaction.id.desc())
    )

    if cat_id := request.args.get('category_id', type=int):
        q = q.filter(Transaction.category_id == cat_id)
    if acct_id := request.args.get('account_id', type=int):
        q = q.filter(Transaction.account_id == acct_id)
    if date_from := request.args.get('date_from'):
        q = q.filter(Transaction.date >= date_from)
    if date_to := request.args.get('date_to'):
        q = q.filter(Transaction.date <= date_to)
    if search := request.args.get('q'):
        like = f"%{search}%"
        q = q.filter(
            Transaction.merchant_normalized.ilike(like) |
            Transaction.notes.ilike(like)
        )

    paginated = q.paginate(page=page, per_page=per_page, error_out=False)

    # Build category and account name maps
    cat_map = {c.id: c.name for c in Category.query.filter_by(is_active=True).all()}
    acct_map = {a.id: a.name for a in Account.query.filter_by(is_active=True).all()}

    return jsonify({
        "transactions": [
            {
                "id": t.id,
                "date": t.date,
                "merchant": t.merchant_normalized,
                "amount": float(t.amount),
                "is_credit": t.is_credit,
                "category": cat_map.get(t.category_id, "Uncategorized"),
                "account": acct_map.get(t.account_id, "Unknown"),
                "notes": t.notes or "",
            }
            for t in paginated.items
        ],
        "total": paginated.total,
        "page": page,
        "pages": paginated.pages,
        "per_page": per_page,
    })


@api_bp.route('/transactions/summary')
def transactions_summary():
    """GET /api/transactions/summary — current month totals by category."""
    from datetime import date
    today = date.today()
    prefix = f"{today.year}-{today.month:02d}-%"

    rows = (
        db.session.query(
            Category.name,
            func.sum(Transaction.amount).label("total"),
            func.count(Transaction.id).label("count"),
        )
        .join(Category, Transaction.category_id == Category.id, isouter=True)
        .filter(Transaction.date.like(prefix), Transaction.is_credit == False)  # noqa: E712
        .group_by(Category.name)
        .order_by(func.sum(Transaction.amount).desc())
        .all()
    )
    return jsonify([
        {"category": r.name or "Uncategorized", "total": float(r.total or 0), "count": r.count}
        for r in rows
    ])
