from fastapi import APIRouter, HTTPException, Query

from backend.db.database import get_connection
from backend.services.balance_service import get_summary, get_transactions
from pydantic import BaseModel

router = APIRouter(tags=["balance"])


class TransactionExcludedBody(BaseModel):
    excluded_from_balance: bool


def _parse_bank_ids(bank_ids: str | None) -> list[int] | None:
    if not bank_ids or not bank_ids.strip():
        return None
    try:
        return [int(x.strip()) for x in bank_ids.split(",") if x.strip()]
    except ValueError:
        return None


@router.get("/api/balance/summary")
def balance_summary(
    period_start: str | None = Query(None, description="YYYY-MM-DD"),
    period_end: str | None = Query(None, description="YYYY-MM-DD"),
    bank_ids: str | None = Query(None, description="ID банков через запятую, например 1,2"),
):
    return get_summary(
        period_start=period_start,
        period_end=period_end,
        bank_ids=_parse_bank_ids(bank_ids),
    )


@router.get("/api/balance/by-account")
def balance_by_account(
    period_start: str | None = Query(None),
    period_end: str | None = Query(None),
    bank_ids: str | None = Query(None),
):
    data = get_summary(
        period_start=period_start,
        period_end=period_end,
        bank_ids=_parse_bank_ids(bank_ids),
    )
    return {"by_account": data["by_account"]}


@router.get("/api/transactions")
def list_transactions(
    account_id: int | None = Query(None),
    bank_ids: str | None = Query(None),
    period_start: str | None = Query(None),
    period_end: str | None = Query(None),
    limit: int = Query(50, ge=1, le=500),
    offset: int = Query(0, ge=0),
):
    items, total = get_transactions(
        account_id=account_id,
        bank_ids=_parse_bank_ids(bank_ids),
        period_start=period_start,
        period_end=period_end,
        limit=limit,
        offset=offset,
    )
    return {"items": items, "total": total}


@router.patch("/api/transactions/{transaction_id}")
def set_transaction_excluded(transaction_id: int, body: TransactionExcludedBody):
    conn = get_connection()
    try:
        cur = conn.execute(
            "UPDATE transactions SET excluded_from_balance = ? WHERE id = ?",
            (1 if body.excluded_from_balance else 0, transaction_id),
        )
        conn.commit()
        if cur.rowcount == 0:
            raise HTTPException(status_code=404, detail="Transaction not found")
        return {"id": transaction_id, "excluded_from_balance": body.excluded_from_balance}
    finally:
        conn.close()
