import uuid from fastapi import APIRouter, Depends, Query, status from sqlalchemy.ext.asyncio import AsyncSession from app.auth.dependencies import get_current_user from app.database import get_session from app.models.user import User from app.schemas.budget import BudgetCreate, BudgetResponse, BudgetUpdate from app.services import budget_service from app.utils import utcnow router = APIRouter(prefix="/budgets", tags=["budgets"]) def _current_month() -> str: now = utcnow() return f"{now.year}-{now.month:02d}" @router.get("", response_model=list[BudgetResponse]) async def list_budgets( month: str = Query(default=None, description="Month YYYY-MM (defaults to current month)"), session: AsyncSession = Depends(get_session), current_user: User = Depends(get_current_user), ) -> list[BudgetResponse]: if month is None: month = _current_month() return await budget_service.list_budgets(session, current_user.id, month) @router.post("", response_model=BudgetResponse, status_code=status.HTTP_201_CREATED) async def create_budget( data: BudgetCreate, session: AsyncSession = Depends(get_session), current_user: User = Depends(get_current_user), ) -> BudgetResponse: return await budget_service.create_budget(session, current_user.id, data) @router.put("/{budget_id}", response_model=BudgetResponse) async def update_budget( budget_id: uuid.UUID, data: BudgetUpdate, session: AsyncSession = Depends(get_session), current_user: User = Depends(get_current_user), ) -> BudgetResponse: return await budget_service.update_budget(session, current_user.id, budget_id, data) @router.delete("/{budget_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_budget( budget_id: uuid.UUID, session: AsyncSession = Depends(get_session), current_user: User = Depends(get_current_user), ) -> None: await budget_service.delete_budget(session, current_user.id, budget_id) @router.post("/rollover", response_model=list[BudgetResponse], status_code=status.HTTP_201_CREATED) async def rollover_budgets( month: str = Query(..., description="Target month YYYY-MM to copy budgets into"), session: AsyncSession = Depends(get_session), current_user: User = Depends(get_current_user), ) -> list[BudgetResponse]: """Copy budgets from month-1 into the given month (skips existing ones).""" return await budget_service.rollover_budgets(session, current_user.id, month)