from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from typing import List, Optional from backend.database import get_db from backend.models import User, ChoreCompletion, ChoreType from backend.schemas import WeeklyReportOut, UserWeekProgress from backend.routers.auth import get_current_user from backend.config import get_current_week_identifier router = APIRouter(prefix="/api/reports", tags=["reports"]) @router.get("/weeks") def get_available_weeks(db: Session = Depends(get_db), current_user: User = Depends(get_current_user)): # Returns all distinct week_identifiers present in database plus current week weeks = db.query(ChoreCompletion.week_identifier).distinct().all() week_set = {w[0] for w in weeks if w[0]} current_week = get_current_week_identifier() week_set.add(current_week) sorted_weeks = sorted(list(week_set), reverse=True) return {"current_week": current_week, "weeks": sorted_weeks} @router.get("/weekly", response_model=WeeklyReportOut) def get_weekly_report(week: Optional[str] = Query(None), db: Session = Depends(get_db), current_user: User = Depends(get_current_user)): target_week = week if week else get_current_week_identifier() users = db.query(User).filter(User.is_active == True).order_by(User.id.asc()).all() user_progress_list: List[UserWeekProgress] = [] total_stars_earned = 0 total_completions = 0 for user in users: completions = db.query(ChoreCompletion).filter( ChoreCompletion.user_id == user.id, ChoreCompletion.week_identifier == target_week ).all() stars = sum(c.stars_earned for c in completions) comp_count = len(completions) total_stars_earned += stars total_completions += comp_count quota = user.weekly_star_quota if user.weekly_star_quota > 0 else 1 pct = round(min(100.0, (stars / quota) * 100), 1) user_progress_list.append(UserWeekProgress( user_id=user.id, name=user.name, email=user.email, avatar_url=user.avatar_url, role=user.role, weekly_star_quota=user.weekly_star_quota, stars_earned=stars, percentage=pct, completions_count=comp_count )) # Sort users by stars earned descending user_progress_list.sort(key=lambda u: u.stars_earned, reverse=True) return WeeklyReportOut( week_identifier=target_week, user_progress=user_progress_list, total_stars_earned=total_stars_earned, total_completions=total_completions )