from datetime import datetime, timedelta from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession from app.models.activity import Activity from app.models.match import Match from app.models.user import User async def get_dashboard_data(session: AsyncSession) -> dict: total_users = int((await session.execute(select(func.count(User.id)))).scalar() or 0) total_matches = int((await session.execute(select(func.count(Match.id)))).scalar() or 0) total_activities = int((await session.execute(select(func.count(Activity.id)))).scalar() or 0) pending_audit = int( (await session.execute(select(func.count(User.id)).where(User.audit_status == 1))).scalar() or 0 ) ongoing_activities = int( (await session.execute(select(func.count(Activity.id)).where(Activity.status.in_([1, 3])))).scalar() or 0 ) seven_days_ago = datetime.now() - timedelta(days=7) active_users_7d = int( (await session.execute(select(func.count(User.id)).where(User.updated_at >= seven_days_ago))).scalar() or 0 ) match_rate = round(total_matches / total_users, 3) if total_users else 0 user_trend = [] match_trend = [] for offset in range(6, -1, -1): day_start = (datetime.now() - timedelta(days=offset)).replace(hour=0, minute=0, second=0, microsecond=0) day_end = day_start + timedelta(days=1) user_count = int( (await session.execute( select(func.count(User.id)).where(User.created_at >= day_start, User.created_at < day_end) )).scalar() or 0 ) match_count = int( (await session.execute( select(func.count(Match.id)).where(Match.matched_at >= day_start, Match.matched_at < day_end) )).scalar() or 0 ) day_label = day_start.strftime('%Y-%m-%d') user_trend.append({"date": day_label, "count": user_count}) match_trend.append({"date": day_label, "count": match_count}) return { "total_users": total_users, "active_users_7d": active_users_7d, "pending_audit": pending_audit, "total_activities": total_activities, "ongoing_activities": ongoing_activities, "total_matches": total_matches, "match_rate": match_rate, "user_trend": user_trend, "match_trend": match_trend, }