from fastapi import APIRouter, Depends from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession from app.core.deps import get_current_active_user, get_db from app.models.comment import Comment from app.models.event import Event, EventRegistration from app.models.favorite import Favorite from app.models.promotion import Promotion from app.models.rating import Rating from app.models.shooting import ShootingRequest, ShootingApplication from app.models.spot import Spot from app.models.user import User router = APIRouter() @router.get("/overview") async def get_stats_overview( current_user: User = Depends(get_current_active_user), db: AsyncSession = Depends(get_db), ): if current_user.role not in ("admin", "moderator"): return {"detail": "Not allowed"} user_count = (await db.execute(select(func.count(User.id)))).scalar() or 0 spot_count = (await db.execute(select(func.count(Spot.id)))).scalar() or 0 approved_spot_count = (await db.execute( select(func.count(Spot.id)).where(Spot.audit_status == "approved") )).scalar() or 0 pending_spot_count = (await db.execute( select(func.count(Spot.id)).where(Spot.audit_status == "pending") )).scalar() or 0 comment_count = (await db.execute(select(func.count(Comment.id)))).scalar() or 0 rating_count = (await db.execute(select(func.count(Rating.id)))).scalar() or 0 favorite_count = (await db.execute(select(func.count(Favorite.id)))).scalar() or 0 shooting_count = (await db.execute(select(func.count(ShootingRequest.id)))).scalar() or 0 event_count = (await db.execute(select(func.count(Event.id)))).scalar() or 0 promo_result = await db.execute( select( func.coalesce(func.sum(Promotion.impressions), 0), func.coalesce(func.sum(Promotion.clicks), 0), ) ) promo_row = promo_result.one() total_impressions = int(promo_row[0]) total_clicks = int(promo_row[1]) return { "user_count": user_count, "spot_count": spot_count, "approved_spot_count": approved_spot_count, "pending_spot_count": pending_spot_count, "comment_count": comment_count, "rating_count": rating_count, "favorite_count": favorite_count, "shooting_count": shooting_count, "event_count": event_count, "promo_impressions": total_impressions, "promo_clicks": total_clicks, "promo_ctr": round(total_clicks / total_impressions * 100, 2) if total_impressions > 0 else 0, }