from uuid import UUID

from fastapi import APIRouter, Depends, Query
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload

from app.auth.demo_auth import get_current_user
from app.database import get_db
from app.models.activity import Activity, ActivityCompletion
from app.models.anti_cheat import AnomalyFlag, VerificationRequest
from app.models.gamification import ActivityFeed, Level
from app.models.sync import DataSourceConfig
from app.models.user import Department, User
from app.services.leaderboard import get_department_summary, get_leaderboard

router = APIRouter(prefix="/dashboard", tags=["dashboard"])


@router.get("/stats")
async def dashboard_stats(db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
    users_count = (await db.execute(select(func.count(User.id)).where(User.is_active == True))).scalar()  # noqa
    activities_count = (await db.execute(select(func.count(Activity.id)).where(Activity.is_active == True))).scalar()  # noqa
    completions_count = (await db.execute(select(func.count(ActivityCompletion.id)).where(ActivityCompletion.status == "completed"))).scalar()
    total_xp = (await db.execute(select(func.coalesce(func.sum(User.total_xp), 0)).where(User.is_active == True))).scalar()  # noqa
    total_verified = (await db.execute(select(func.coalesce(func.sum(User.verified_xp), 0)).where(User.is_active == True))).scalar()  # noqa
    dept_count = (await db.execute(select(func.count(Department.id)))).scalar()
    pending = (await db.execute(select(func.count(VerificationRequest.id)).where(VerificationRequest.status == "pending"))).scalar()
    anomalies = (await db.execute(select(func.count(AnomalyFlag.id)).where(AnomalyFlag.resolved == False))).scalar()  # noqa

    return {
        "total_employees": users_count,
        "active_employees": users_count,
        "total_activities": activities_count,
        "total_completions": completions_count,
        "total_xp_earned": total_xp,
        "total_verified_xp": total_verified,
        "avg_xp_per_employee": round(total_xp / max(users_count, 1)),
        "department_count": dept_count,
        "pending_verifications": pending,
        "unresolved_anomalies": anomalies,
    }


@router.get("/leaderboard")
async def dashboard_leaderboard(
    limit: int = Query(10, le=50),
    department_id: str | None = None,
    db: AsyncSession = Depends(get_db),
    _=Depends(get_current_user),
):
    dept_uuid = UUID(department_id) if department_id else None
    entries = await get_leaderboard(db, limit=limit, department_id=dept_uuid)
    return [
        {
            "rank": e["rank"],
            "user": {
                "id": str(e["user"].id),
                "full_name": e["user"].full_name,
                "email": e["user"].email,
                "department": e["user"].department.name if e["user"].department else None,
                "total_xp": e["user"].total_xp,
                "verified_xp": e["user"].verified_xp,
                "current_level": e["user"].current_level,
            },
            "total_xp": e["total_xp"],
            "level": {"name": e["level"].name, "color": e["level"].color} if e["level"] else None,
            "completed_count": e["completed_count"],
            "badge_count": e["badge_count"],
        }
        for e in entries
    ]


@router.get("/department-summary")
async def dashboard_departments(db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
    summaries = await get_department_summary(db)
    return [
        {
            "department": {"id": str(s["department"].id), "name": s["department"].name},
            "member_count": s["member_count"],
            "total_xp": s["total_xp"],
            "avg_xp": s["avg_xp"],
            "total_completions": s["total_completions"],
            "top_performer": {
                "id": str(s["top_performer"].id),
                "full_name": s["top_performer"].full_name,
                "total_xp": s["top_performer"].total_xp,
            } if s["top_performer"] else None,
        }
        for s in summaries
    ]


@router.get("/recent-activity")
async def dashboard_recent_activity(
    limit: int = Query(20, le=100),
    db: AsyncSession = Depends(get_db),
    _=Depends(get_current_user),
):
    result = await db.execute(
        select(ActivityFeed)
        .options(selectinload(ActivityFeed.user_id))  # This won't work directly; see note
        .order_by(ActivityFeed.created_at.desc())
        .limit(limit)
    )
    # Simplified: just return raw feed
    result = await db.execute(
        select(ActivityFeed).order_by(ActivityFeed.created_at.desc()).limit(limit)
    )
    feeds = result.scalars().all()

    items = []
    for f in feeds:
        user = await db.get(User, f.user_id) if f.user_id else None
        items.append({
            "id": str(f.id),
            "event_type": f.event_type,
            "event_data": f.event_data,
            "user": {"id": str(user.id), "full_name": user.full_name} if user else None,
            "created_at": f.created_at.isoformat(),
        })
    return items


@router.get("/sync-status")
async def dashboard_sync_status(db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
    result = await db.execute(select(DataSourceConfig).order_by(DataSourceConfig.display_name))
    sources = result.scalars().all()
    return [
        {
            "id": str(s.id),
            "name": s.name,
            "display_name": s.display_name,
            "sync_type": s.sync_type,
            "is_enabled": s.is_enabled,
            "last_sync_at": s.last_sync_at.isoformat() if s.last_sync_at else None,
            "last_sync_status": s.last_sync_status or "never",
            "last_sync_records": s.last_sync_records,
        }
        for s in sources
    ]


@router.get("/trust-breakdown")
async def dashboard_trust_breakdown(db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
    result = await db.execute(
        select(
            ActivityCompletion.trust_tier,
            func.count(ActivityCompletion.id),
            func.coalesce(func.sum(ActivityCompletion.xp_awarded), 0),
        )
        .where(ActivityCompletion.status == "completed")
        .group_by(ActivityCompletion.trust_tier)
    )
    rows = result.all()
    breakdown = {1: {"completions": 0, "xp": 0}, 2: {"completions": 0, "xp": 0}, 3: {"completions": 0, "xp": 0}}
    for tier, count, xp in rows:
        if tier in breakdown:
            breakdown[tier] = {"completions": count, "xp": xp}
    return {
        "tier_1_completions": breakdown[1]["completions"],
        "tier_1_xp": breakdown[1]["xp"],
        "tier_2_completions": breakdown[2]["completions"],
        "tier_2_xp": breakdown[2]["xp"],
        "tier_3_completions": breakdown[3]["completions"],
        "tier_3_xp": breakdown[3]["xp"],
    }
