//! HTTP handlers for authentication
//!
//! Ready-to-use Axum handlers for login, logout, and user info endpoints.

use axum::{extract::State, http::StatusCode, Json};
use std::sync::Arc;

use crate::{
    error::{AuthError, AuthResult},
    models::{AuthUser, Credentials, LoginResponse},
    traits::AuthProvider,
    AuthConfig,
};

/// Login handler
///
/// Authenticates user and returns session token.
///
/// ## Example
///
/// ```rust,ignore
/// use axum::{Router, routing::post};
/// use lmrc_auth::handlers::login_handler;
/// use std::sync::Arc;
///
/// let router = Router::new()
///     .route("/auth/login", post(login_handler::<MyAuthProvider>))
///     .with_state((auth_provider, config));
/// ```
pub async fn login_handler<P>(
    State((provider, _config)): State<(Arc<P>, AuthConfig)>,
    Json(credentials): Json<Credentials>,
) -> AuthResult<Json<LoginResponse>>
where
    P: AuthProvider,
{
    // Authenticate user
    let user = provider
        .authenticate(&credentials.email, &credentials.password)
        .await?;

    // Create session
    let session = provider.create_session(user.id).await?;

    // Return login response
    Ok(Json(LoginResponse::new(session, user)))
}

/// Logout handler
///
/// Destroys the user's session.
pub async fn logout_handler<P>(
    State((provider, _config)): State<(Arc<P>, AuthConfig)>,
    token: String, // Extract from cookie or header
) -> AuthResult<StatusCode>
where
    P: AuthProvider,
{
    provider.destroy_session(&token).await?;
    Ok(StatusCode::NO_CONTENT)
}

/// Get current user handler
///
/// Returns information about the currently authenticated user.
pub async fn me_handler<P>(
    State((provider, _config)): State<(Arc<P>, AuthConfig)>,
    token: String, // Extract from cookie or header
) -> AuthResult<Json<AuthUser>>
where
    P: AuthProvider,
{
    let user = provider
        .validate_session(&token)
        .await?
        .ok_or(AuthError::InvalidSession)?;

    Ok(Json(user))
}
