"""Competition & Event Management APIs — Phase 9.7."""
from __future__ import annotations

from uuid import UUID

from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, get_pagination, require_tenant
from app.core.security import get_current_user
from app.schemas.competitions import (
    CompetitionCertificateCreate,
    CompetitionCertificateRead,
    CompetitionCreate,
    CompetitionGroupCreate,
    CompetitionGroupRead,
    CompetitionJudgeCreate,
    CompetitionJudgeRead,
    CompetitionMatchCreate,
    CompetitionMatchRead,
    CompetitionMedalCreate,
    CompetitionMedalRead,
    CompetitionRankingRead,
    CompetitionRead,
    CompetitionRegistrationCreate,
    CompetitionRegistrationRead,
    CompetitionResultCreate,
    CompetitionResultRead,
    CompetitionTeamCreate,
    CompetitionTeamRead,
    CompetitionUpdate,
)
from app.services.competitions import (
    CompetitionCertificateService,
    CompetitionGroupService,
    CompetitionJudgeService,
    CompetitionMatchService,
    CompetitionMedalService,
    CompetitionRegistrationService,
    CompetitionResultService,
    CompetitionService,
    CompetitionTeamService,
)
from shared.pagination import PaginationParams
from shared.security import CurrentUser

competitions_router = APIRouter()
teams_router = APIRouter()
groups_router = APIRouter()
registrations_router = APIRouter()
matches_router = APIRouter()
results_router = APIRouter()
rankings_router = APIRouter()
medals_router = APIRouter()
judges_router = APIRouter()
certificates_router = APIRouter()


@competitions_router.post("", response_model=CompetitionRead, status_code=status.HTTP_201_CREATED)
async def create_competition(body: CompetitionCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionService(db).create(tenant_id, body, actor=user)


@competitions_router.get("", response_model=list[CompetitionRead])
async def list_competitions(tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user)):
    return await CompetitionService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)


@competitions_router.patch("/{competition_id}", response_model=CompetitionRead)
async def update_competition(competition_id: UUID, body: CompetitionUpdate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionService(db).update(tenant_id, competition_id, body, actor=user)


@teams_router.post("", response_model=CompetitionTeamRead, status_code=status.HTTP_201_CREATED)
async def create_team(body: CompetitionTeamCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionTeamService(db).create(tenant_id, body, actor=user)


@teams_router.get("", response_model=list[CompetitionTeamRead])
async def list_teams(competition_id: UUID = Query(...), tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user)):
    return await CompetitionTeamService(db).list(tenant_id, competition_id, offset=pagination.offset, limit=pagination.page_size)


@groups_router.post("", response_model=CompetitionGroupRead, status_code=status.HTTP_201_CREATED)
async def create_group(body: CompetitionGroupCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionGroupService(db).create(tenant_id, body, actor=user)


@registrations_router.post("", response_model=CompetitionRegistrationRead, status_code=status.HTTP_201_CREATED)
async def register_member(body: CompetitionRegistrationCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionRegistrationService(db).create(tenant_id, body, actor=user)


@registrations_router.post("/{registration_id}/confirm", response_model=CompetitionRegistrationRead)
async def confirm_registration(registration_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionRegistrationService(db).confirm(tenant_id, registration_id, actor=user)


@matches_router.post("", response_model=CompetitionMatchRead, status_code=status.HTTP_201_CREATED)
async def schedule_match(body: CompetitionMatchCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionMatchService(db).create(tenant_id, body, actor=user)


@results_router.post("", response_model=CompetitionResultRead, status_code=status.HTTP_201_CREATED)
async def record_result(body: CompetitionResultCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionResultService(db).create(tenant_id, body, actor=user)


@rankings_router.get("", response_model=list[CompetitionRankingRead])
async def list_rankings(competition_id: UUID = Query(...), tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(get_current_user)):
    return await CompetitionResultService(db).list_rankings(tenant_id, competition_id, offset=pagination.offset, limit=pagination.page_size)


@medals_router.post("", response_model=CompetitionMedalRead, status_code=status.HTTP_201_CREATED)
async def award_medal(body: CompetitionMedalCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionMedalService(db).create(tenant_id, body, actor=user)


@judges_router.post("", response_model=CompetitionJudgeRead, status_code=status.HTTP_201_CREATED)
async def assign_judge(body: CompetitionJudgeCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionJudgeService(db).create(tenant_id, body, actor=user)


@certificates_router.post("", response_model=CompetitionCertificateRead, status_code=status.HTTP_201_CREATED)
async def issue_certificate(body: CompetitionCertificateCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(get_current_user)):
    return await CompetitionCertificateService(db).create(tenant_id, body, actor=user)
