import uuid
from datetime import date

from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.dependencies import GESTIONNAIRE_PLUS, get_current_user, require_role
from app.core.responses import api_response, normalize_page_param, page_response
from app.db.database import get_async_session
from app.schemas.calendrier import CalendrierCreate, CalendrierUpdate
from app.schemas.extensions import ParticipantResponse, ParticipantStatutUpdate
from app.services.calendrier_service import CalendrierService

router = APIRouter(prefix="/calendriers", tags=["Calendrier"])


@router.post("/", status_code=201)
async def creer_evenement(
    body: CalendrierCreate,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(require_role(*GESTIONNAIRE_PLUS)),
):
    service = CalendrierService(db)
    data = await service.creer(current_user.id, body)
    return api_response(data, message="Événement créé", status_code=201)


@router.get("/")
async def list_evenements(
    page: int = 0,
    size: int = 20,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    resolved_page = normalize_page_param(page)
    service = CalendrierService(db)
    items, total = await service.list_all(current_user.id, page=resolved_page, size=size)
    return page_response(items, total=total, page=resolved_page, size=size)


@router.get("/date/{target_date}")
async def evenements_par_date(
    target_date: date,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = CalendrierService(db)
    items = await service.get_by_date(current_user.id, target_date)
    return api_response(items, message="Événements récupérés")


@router.get("/range")
async def evenements_range(
    debut: date,
    fin: date,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = CalendrierService(db)
    items = await service.get_range(current_user.id, debut, fin)
    return api_response(items, message="Événements récupérés")


@router.get("/{evenement_id}")
async def get_evenement(
    evenement_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = CalendrierService(db)
    data = await service.get_by_id(str(evenement_id), current_user)
    return api_response(data, message="Événement récupéré")


@router.put("/{evenement_id}")
async def update_evenement(
    evenement_id: uuid.UUID,
    body: CalendrierUpdate,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(require_role(*GESTIONNAIRE_PLUS)),
):
    service = CalendrierService(db)
    data = await service.update(str(evenement_id), body, current_user)
    return api_response(data, message="Événement mis à jour")


@router.delete("/{evenement_id}", status_code=204)
async def delete_evenement(
    evenement_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(require_role(*GESTIONNAIRE_PLUS)),
):
    service = CalendrierService(db)
    await service.delete(str(evenement_id), current_user)


@router.post("/{evenement_id}/inscription", status_code=201)
async def inscrire(
    evenement_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = CalendrierService(db)
    data = await service.inscrire(str(evenement_id), current_user)
    return api_response(data, message="Inscription confirmée", status_code=201)


@router.delete("/{evenement_id}/inscription", status_code=204)
async def desinscrire(
    evenement_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = CalendrierService(db)
    await service.desinscrire(str(evenement_id), current_user)


@router.get("/{evenement_id}/participants")
async def list_participants(
    evenement_id: uuid.UUID,
    page: int = 0,
    size: int = 20,
    db: AsyncSession = Depends(get_async_session),
    _current_user=Depends(require_role(*GESTIONNAIRE_PLUS)),
):
    resolved_page = normalize_page_param(page)
    service = CalendrierService(db)
    items, total = await service.list_participants(str(evenement_id), page=resolved_page, size=size)
    return page_response(items, total=total, page=resolved_page, size=size, message="Participants récupérés")


@router.put("/participants/{participant_id}/statut")
async def update_participant_statut(
    participant_id: uuid.UUID,
    body: ParticipantStatutUpdate,
    db: AsyncSession = Depends(get_async_session),
    _current_user=Depends(require_role(*GESTIONNAIRE_PLUS)),
):
    service = CalendrierService(db)
    data = await service.update_participant_statut(str(participant_id), body.statut)
    return api_response(data, message="Statut du participant mis à jour")
