import uuid

from fastapi import APIRouter, Depends, Request
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.dependencies import ADMIN_ONLY, 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.compte import ChangePasswordRequest, CompteCreate, CompteUpdate, ResetPasswordAdminRequest
from app.schemas.extensions import InvitationCreate
from app.services.compte_service import CompteService
from app.services.invitation_service import InvitationService
from app.core.limiter import limiter

router = APIRouter(prefix="/comptes", tags=["Comptes"])


@router.get("/me")
async def get_me(
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = CompteService(db)
    data = await service.get_me(current_user)
    return api_response(data, message="Profil récupéré")


@router.put("/me")
async def update_me(
    body: CompteUpdate,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = CompteService(db)
    data = await service.update(str(current_user.id), body, current_user)
    return api_response(data, message="Profil mis à jour")


@router.put("/me/password")
@limiter.limit("5/minute")
async def change_my_password(
    request: Request,
    body: ChangePasswordRequest,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = CompteService(db)
    await service.change_password(str(current_user.id), body.ancienMotDePasse, body.nouveauMotDePasse)
    return api_response(None, message="Mot de passe modifié")


@router.post("/", status_code=201)
async def create_compte(
    body: CompteCreate,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(require_role(*ADMIN_ONLY)),
):
    service = CompteService(db)
    data = await service.create(body)
    return api_response(data, message="Compte créé", status_code=201)


@router.get("/")
async def list_comptes(
    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 = CompteService(db)
    items, total = await service.list_all(page=resolved_page, size=size)
    return page_response(items, total=total, page=resolved_page, size=size)


@router.get("/{compte_id}")
async def get_compte(
    compte_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    _current_user=Depends(get_current_user),
):
    service = CompteService(db)
    data = await service.get_by_id(str(compte_id))
    return api_response(data, message="Compte récupéré")


@router.put("/{compte_id}")
async def update_compte(
    compte_id: uuid.UUID,
    body: CompteUpdate,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = CompteService(db)
    data = await service.update(str(compte_id), body, current_user)
    return api_response(data, message="Compte mis à jour")


@router.put("/{compte_id}/reset-password")
async def reset_password_admin(
    compte_id: uuid.UUID,
    body: ResetPasswordAdminRequest,
    db: AsyncSession = Depends(get_async_session),
    _current_user=Depends(require_role(*ADMIN_ONLY)),
):
    service = CompteService(db)
    await service.reset_password(str(compte_id), body.nouveauMotDePasse)
    return api_response(None, message="Mot de passe réinitialisé")


@router.put("/{compte_id}/deactivate")
async def deactivate_compte(
    compte_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    _current_user=Depends(require_role(*ADMIN_ONLY)),
):
    service = CompteService(db)
    await service.deactivate(str(compte_id))
    return api_response(None, message="Compte désactivé")


@router.put("/{compte_id}/reactivate")
async def reactivate_compte(
    compte_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    _current_user=Depends(require_role(*ADMIN_ONLY)),
):
    service = CompteService(db)
    await service.reactivate(str(compte_id))
    return api_response(None, message="Compte réactivé")


@router.post("/invitations", status_code=201)
async def create_invitation(
    body: InvitationCreate,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(require_role(*ADMIN_ONLY)),
):
    service = InvitationService(db)
    data = await service.creer_invitation(body.email, body.typeUtilisateur, current_user)
    return api_response(data, message="Invitation créée", status_code=201)


@router.get("/invitations")
async def list_invitations(
    page: int = 1,
    size: int = 20,
    statut: str | None = None,
    db: AsyncSession = Depends(get_async_session),
    _current_user=Depends(require_role(*ADMIN_ONLY)),
):
    resolved_page = normalize_page_param(page)
    service = InvitationService(db)
    items, total = await service.list_invitations(page=resolved_page, size=size, statut=statut)
    return page_response(items, total=total, page=resolved_page, size=size, message="Invitations récupérées")
