"""
Authentication API endpoints
"""
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import HTTPBearer

from app.api.v1.dependencies.auth import get_current_user, get_auth_service
from app.core.exceptions.auth import (
    InvalidCredentialsError,
    UserNotFoundError,
    UserInactiveError,
    UserLockedError,
    EmailNotVerifiedError,
    TokenExpiredError,
    InvalidTokenError
)
from app.domain.entities.user import User
from app.domain.services.auth_service import AuthService
from app.schemas.auth import (
    LoginRequest,
    LoginResponse,
    TokenResponse,
    RefreshTokenRequest,
    PasswordResetRequest,
    PasswordResetConfirm,
    PasswordChangeRequest,
    EmailVerificationRequest
)
from app.schemas.base import MessageResponse

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


@router.post("/login", response_model=LoginResponse)
async def login(
    login_request: LoginRequest,
    auth_service: AuthService = Depends(get_auth_service)
):
    """Authenticate user and return tokens"""
    try:
        user, tokens = await auth_service.authenticate_user(login_request)
        
        return LoginResponse(
            user=user,
            access_token=tokens.access_token,
            refresh_token=tokens.refresh_token,
            token_type=tokens.token_type,
            expires_in=tokens.expires_in
        )
        
    except (InvalidCredentialsError, UserNotFoundError) as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=str(e)
        )
    except (UserInactiveError, UserLockedError, EmailNotVerifiedError) as e:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=str(e)
        )


@router.post("/refresh", response_model=TokenResponse)
async def refresh_token(
    refresh_request: RefreshTokenRequest,
    auth_service: AuthService = Depends(get_auth_service)
):
    """Refresh access token"""
    try:
        tokens = await auth_service.refresh_token(refresh_request.refresh_token)
        return tokens
        
    except (InvalidTokenError, TokenExpiredError, UserNotFoundError) as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=str(e)
        )


@router.post("/logout", response_model=MessageResponse)
async def logout(
    current_user: User = Depends(get_current_user),
    auth_service: AuthService = Depends(get_auth_service)
):
    """Logout current user"""
    await auth_service.logout(current_user.id, "token_placeholder")
    
    return MessageResponse(message="Successfully logged out")


@router.post("/verify-email", response_model=MessageResponse)
async def verify_email(
    verification_request: EmailVerificationRequest,
    auth_service: AuthService = Depends(get_auth_service)
):
    """Verify user email"""
    try:
        await auth_service.verify_email(verification_request.token)
        return MessageResponse(message="Email verified successfully")
        
    except InvalidTokenError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )


@router.post("/password-reset", response_model=MessageResponse)
async def request_password_reset(
    reset_request: PasswordResetRequest,
    auth_service: AuthService = Depends(get_auth_service)
):
    """Request password reset"""
    await auth_service.request_password_reset(reset_request.email)
    
    return MessageResponse(
        message="If the email exists, a password reset link has been sent"
    )


@router.post("/password-reset/confirm", response_model=MessageResponse)
async def confirm_password_reset(
    reset_confirm: PasswordResetConfirm,
    auth_service: AuthService = Depends(get_auth_service)
):
    """Confirm password reset"""
    try:
        await auth_service.reset_password(reset_confirm.token, reset_confirm.new_password)
        return MessageResponse(message="Password reset successfully")
        
    except (InvalidTokenError, TokenExpiredError) as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )


@router.post("/password-change", response_model=MessageResponse)
async def change_password(
    password_change: PasswordChangeRequest,
    current_user: User = Depends(get_current_user),
    auth_service: AuthService = Depends(get_auth_service)
):
    """Change user password"""
    try:
        await auth_service.change_password(
            current_user.id,
            password_change.current_password,
            password_change.new_password
        )
        return MessageResponse(message="Password changed successfully")
        
    except InvalidCredentialsError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )
    except UserNotFoundError as e:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=str(e)
        )


@router.get("/me", response_model=User)
async def get_current_user_info(
    current_user: User = Depends(get_current_user)
):
    """Get current user information"""
    return current_user


@router.post("/validate-token", response_model=MessageResponse)
async def validate_token(
    current_user: User = Depends(get_current_user)
):
    """Validate current token"""
    return MessageResponse(message="Token is valid")
