import uuid from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.database import get_db from app.models import Mode, Player from app.queue_manager import queue_manager from app.schemas import QueueJoinRequest, QueueJoinResponse, QueueStatusResponse router = APIRouter(prefix="/matchmaking", tags=["matchmaking"]) async def _get_or_create_player(db: AsyncSession, callsign: str) -> Player: player = (await db.execute(select(Player).where(Player.callsign == callsign))).scalars().first() if player is None: player = Player(callsign=callsign) db.add(player) await db.commit() await db.refresh(player) return player @router.post("/queue/join", response_model=QueueJoinResponse) async def join_queue(req: QueueJoinRequest, db: AsyncSession = Depends(get_db)) -> QueueJoinResponse: player = await _get_or_create_player(db, req.callsign) mmr = req.mmr if req.mode == Mode.ranked and req.mmr is not None else player.mmr ticket = await queue_manager.join(player.id, player.callsign, req.mode, mmr) return QueueJoinResponse(ticket_id=ticket.ticket_id, status=ticket.status) @router.post("/queue/leave") async def leave_queue(ticket_id: uuid.UUID) -> dict: ok = await queue_manager.leave(ticket_id) if not ok: raise HTTPException(status_code=404, detail="Ticket not found or already resolved") return {"status": "cancelled"} @router.get("/queue/status/{ticket_id}", response_model=QueueStatusResponse) async def queue_status(ticket_id: uuid.UUID) -> QueueStatusResponse: ticket = queue_manager.get(ticket_id) if ticket is None: raise HTTPException(status_code=404, detail="Ticket not found") return QueueStatusResponse( ticket_id=ticket.ticket_id, status=ticket.status, server_ip=ticket.server_ip, server_port=ticket.server_port, team=ticket.team, )