//! API 处理器

pub mod auth;
pub mod users;
pub mod devices;
pub mod sessions;
pub mod admin;
pub mod setup;

use axum::{
    extract::FromRequestParts,
    http::{request::Parts, StatusCode},
    response::{IntoResponse, Response},
    Json,
};
use crate::models::ApiResponse;
use crate::services::AppState;
use std::sync::Arc;

/// 认证用户提取器
pub struct AuthUser {
    pub user_id: String,
    pub username: String,
    pub role: String,
}

#[axum::async_trait]
impl FromRequestParts<Arc<AppState>> for AuthUser {
    type Rejection = AuthError;

    async fn from_request_parts(parts: &mut Parts, state: &Arc<AppState>) -> Result<Self, Self::Rejection> {
        // 从 Authorization header 获取 token
        let auth_header = parts
            .headers
            .get("Authorization")
            .and_then(|v| v.to_str().ok())
            .ok_or(AuthError::MissingToken)?;

        // 解析 Bearer token
        let token = auth_header
            .strip_prefix("Bearer ")
            .ok_or(AuthError::InvalidToken)?;

        // 验证 token
        let auth_service = crate::services::auth::AuthService::new(&state.config);
        let claims = auth_service
            .verify_token(token)
            .map_err(|_| AuthError::InvalidToken)?;

        Ok(AuthUser {
            user_id: claims.sub,
            username: claims.username,
            role: claims.role,
        })
    }
}

/// 可选认证用户提取器
pub struct OptionalAuthUser(pub Option<AuthUser>);

#[axum::async_trait]
impl FromRequestParts<Arc<AppState>> for OptionalAuthUser {
    type Rejection = std::convert::Infallible;

    async fn from_request_parts(parts: &mut Parts, state: &Arc<AppState>) -> Result<Self, Self::Rejection> {
        Ok(OptionalAuthUser(
            AuthUser::from_request_parts(parts, state).await.ok()
        ))
    }
}

/// 管理员用户提取器
pub struct AdminUser(pub AuthUser);

#[axum::async_trait]
impl FromRequestParts<Arc<AppState>> for AdminUser {
    type Rejection = AuthError;

    async fn from_request_parts(parts: &mut Parts, state: &Arc<AppState>) -> Result<Self, Self::Rejection> {
        let user = AuthUser::from_request_parts(parts, state).await?;
        if user.role != "admin" {
            return Err(AuthError::Forbidden);
        }
        Ok(AdminUser(user))
    }
}

/// 认证错误
pub enum AuthError {
    MissingToken,
    InvalidToken,
    Forbidden,
}

impl IntoResponse for AuthError {
    fn into_response(self) -> Response {
        let (status, message) = match self {
            AuthError::MissingToken => (StatusCode::UNAUTHORIZED, "缺少认证令牌"),
            AuthError::InvalidToken => (StatusCode::UNAUTHORIZED, "无效的认证令牌"),
            AuthError::Forbidden => (StatusCode::FORBIDDEN, "权限不足"),
        };

        (status, Json(ApiResponse::<()>::err(message))).into_response()
    }
}

/// API 错误处理
pub fn api_error(status: StatusCode, message: impl ToString) -> Response {
    (status, Json(ApiResponse::<()>::err(message))).into_response()
}
