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

from app.core.dependencies import get_current_user
from app.core.responses import api_response
from app.db.database import get_async_session
from app.models.utilisateur import Utilisateur
from app.schemas.auth import (
    ForgotPasswordRequest,
    LoginRequest,
    RefreshRequest,
    ResetPasswordRequest,
    SignupRequest,
)
from app.services.auth_service import AuthService
from app.core.limiter import limiter

router = APIRouter(prefix="/auth", tags=["auth"])


@router.post(
    "/signup",
    status_code=status.HTTP_201_CREATED,
    summary="Créer un nouveau compte utilisateur",
)
@limiter.limit("3/minute")
async def signup(
    request: Request,
    data: SignupRequest,
    db: AsyncSession = Depends(get_async_session),
) -> dict:
    service = AuthService(db)
    user = await service.signup(data)
    return api_response(
        {
            "id": str(user.id),
            "email": user.email,
            "nom": user.nom,
            "prenom": user.prenom,
            "typeUtilisateur": user.type_utilisateur,
        },
        message="Compte créé avec succès",
        status_code=201,
    )


@router.post(
    "/login",
    summary="Authentifier un utilisateur",
)
@limiter.limit("10/minute")
async def login(
    request: Request,
    data: LoginRequest,
    db: AsyncSession = Depends(get_async_session),
) -> dict:
    service = AuthService(db)
    result = await service.login(data)
    return api_response(result, message="Connexion réussie")


@router.post(
    "/logout",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Déconnecter l'utilisateur courant",
)
async def logout(
    current_user: Utilisateur = Depends(get_current_user),
    db: AsyncSession = Depends(get_async_session),
) -> None:
    service = AuthService(db)
    jti = getattr(current_user, "_jti", None)
    if jti:
        await service.logout(jti)


@router.post(
    "/refresh",
    summary="Renouveler les tokens d'accès",
)
async def refresh(
    data: RefreshRequest,
    db: AsyncSession = Depends(get_async_session),
) -> dict:
    service = AuthService(db)
    result = await service.refresh(data)
    return api_response(result, message="Tokens renouvelés")


@router.get(
    "/validate",
    summary="Valider le token et récupérer le profil complet",
)
async def validate_token(
    current_user: Utilisateur = Depends(get_current_user),
    db: AsyncSession = Depends(get_async_session),
) -> dict:
    service = AuthService(db)
    result = await service.validate_and_get_user(current_user)
    return api_response(result, message="Token valide")


@router.post(
    "/forgot-password",
    status_code=status.HTTP_200_OK,
    summary="Demander une réinitialisation de mot de passe",
)
@limiter.limit("3/minute")
async def forgot_password(
    request: Request,
    data: ForgotPasswordRequest,
    db: AsyncSession = Depends(get_async_session),
) -> dict:
    service = AuthService(db)
    await service.forgot_password(data)
    return api_response(
        None,
        message="Si cet email est enregistré, vous recevrez un lien de réinitialisation.",
    )


@router.post(
    "/reset-password",
    status_code=status.HTTP_200_OK,
    summary="Réinitialiser le mot de passe avec le token reçu par email",
)
@limiter.limit("5/minute")
async def reset_password(
    request: Request,
    data: ResetPasswordRequest,
    db: AsyncSession = Depends(get_async_session),
) -> dict:
    service = AuthService(db)
    await service.reset_password(data)
    return api_response(None, message="Mot de passe réinitialisé avec succès")
