from fastapi import APIRouter
from sqlalchemy import select, func
from sqlalchemy.orm import selectinload

from app.api.deps import DbSession, CurrentUser
from app.models import Activity, Participant, Dispute, ActivityType
from app.models.dispute import DisputeStatus
from app.schemas import FeedResponse, ActivityResponse, UserPublic

router = APIRouter(tags=["feed"])


@router.get("/marathons/{marathon_id}/feed", response_model=FeedResponse)
async def get_feed(
    marathon_id: int,
    current_user: CurrentUser,
    db: DbSession,
    limit: int = 20,
    offset: int = 0,
):
    """Get activity feed for marathon"""
    # Check user is participant
    result = await db.execute(
        select(Participant).where(
            Participant.user_id == current_user.id,
            Participant.marathon_id == marathon_id,
        )
    )
    if not result.scalar_one_or_none():
        return FeedResponse(items=[], total=0, has_more=False)

    # Get total count
    total = await db.scalar(
        select(func.count()).select_from(Activity).where(Activity.marathon_id == marathon_id)
    )

    # Get activities
    result = await db.execute(
        select(Activity)
        .options(selectinload(Activity.user))
        .where(Activity.marathon_id == marathon_id)
        .order_by(Activity.created_at.desc())
        .limit(limit)
        .offset(offset)
    )
    activities = result.scalars().all()

    # Get assignment_ids from complete activities to check for disputes
    complete_assignment_ids = []
    for a in activities:
        if a.type == ActivityType.COMPLETE.value and a.data and a.data.get("assignment_id"):
            complete_assignment_ids.append(a.data["assignment_id"])

    # Get disputes for these assignments
    disputes_map: dict[int, str] = {}
    if complete_assignment_ids:
        result = await db.execute(
            select(Dispute).where(Dispute.assignment_id.in_(complete_assignment_ids))
        )
        for dispute in result.scalars().all():
            disputes_map[dispute.assignment_id] = dispute.status

    items = []
    for a in activities:
        data = dict(a.data) if a.data else {}

        # Add dispute status to complete activities
        if a.type == ActivityType.COMPLETE.value and a.data and a.data.get("assignment_id"):
            assignment_id = a.data["assignment_id"]
            if assignment_id in disputes_map:
                data["dispute_status"] = disputes_map[assignment_id]

        items.append(
            ActivityResponse(
                id=a.id,
                type=a.type,
                user=UserPublic.model_validate(a.user),
                data=data if data else None,
                created_at=a.created_at,
            )
        )

    return FeedResponse(
        items=items,
        total=total,
        has_more=(offset + limit) < total,
    )
