import uuid from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from app.crud import crud_championship, crud_registration from app.database import get_db from app.dependencies import get_approved_user, get_organizer from app.models.user import User from app.schemas.registration import ( RegistrationCreate, RegistrationListItem, RegistrationOut, RegistrationUpdate, RegistrationWithUser, ) router = APIRouter() @router.post("", response_model=RegistrationOut, status_code=status.HTTP_201_CREATED) async def register_for_championship( data: RegistrationCreate, current_user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): champ = await crud_championship.get(db, data.championship_id) if not champ: raise HTTPException(status_code=404, detail="Championship not found") if champ.status != "open": raise HTTPException(status_code=400, detail="Registration is not open for this championship") existing = await crud_registration.get_by_user_and_championship(db, current_user.id, data.championship_id) if existing: raise HTTPException(status_code=409, detail="Already registered for this championship") return await crud_registration.create(db, current_user.id, data) @router.get("/my", response_model=list[RegistrationListItem]) async def my_registrations( current_user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): return await crud_registration.list_for_user(db, current_user.id) @router.get("/{reg_id}", response_model=RegistrationOut) async def get_registration( reg_id: uuid.UUID, current_user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): reg = await crud_registration.get(db, reg_id) if not reg: raise HTTPException(status_code=404, detail="Registration not found") if reg.user_id != current_user.id and current_user.role not in ("organizer", "admin"): raise HTTPException(status_code=403, detail="Access denied") return reg @router.patch("/{reg_id}", response_model=RegistrationOut) async def update_registration( reg_id: uuid.UUID, data: RegistrationUpdate, current_user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): reg = await crud_registration.get(db, reg_id) if not reg: raise HTTPException(status_code=404, detail="Registration not found") # Members can only update their own registration (video_url, notes) if current_user.role == "member": if reg.user_id != current_user.id: raise HTTPException(status_code=403, detail="Access denied") allowed_fields = {"video_url", "notes"} update_data = data.model_dump(exclude_none=True) if not set(update_data.keys()).issubset(allowed_fields): raise HTTPException(status_code=403, detail="Members can only update video_url and notes") return await crud_registration.update(db, reg, data) @router.delete("/{reg_id}", status_code=status.HTTP_204_NO_CONTENT) async def cancel_registration( reg_id: uuid.UUID, current_user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): reg = await crud_registration.get(db, reg_id) if not reg: raise HTTPException(status_code=404, detail="Registration not found") if reg.user_id != current_user.id and current_user.role not in ("organizer", "admin"): raise HTTPException(status_code=403, detail="Access denied") await crud_registration.delete(db, reg) # Organizer: list all registrations for a championship @router.get("/championship/{champ_id}", response_model=list[RegistrationWithUser]) async def list_registrations_for_championship( champ_id: uuid.UUID, _user: User = Depends(get_organizer), db: AsyncSession = Depends(get_db), skip: int = 0, limit: int = 100, ): return await crud_registration.list_for_championship(db, champ_id, skip=skip, limit=limit)