use crate::{
    domain::{dto::user::UpdateProfileRequest, vo::ApiResponse},
    error::ErrorResponse,
    infra::middleware::UserId,
    repositories::user_profile_repository::UserProfileRepository,
    AppState,
};
use axum::{extract::State, Json};
use validator::Validate;

pub async fn get_profile(
    State(state): State<AppState>,
    UserId(user_id): UserId,
) -> Result<Json<ApiResponse<serde_json::Value>>, ErrorResponse> {
    let value = UserProfileRepository::new(state.pool)
        .get(&user_id)
        .await
        .map_err(|e| ErrorResponse::internal(e.to_string()))?;
    Ok(Json(ApiResponse::success(
        serde_json::to_value(value).unwrap_or_default(),
    )))
}
pub async fn update_profile(
    State(state): State<AppState>,
    UserId(user_id): UserId,
    Json(input): Json<UpdateProfileRequest>,
) -> Result<Json<ApiResponse<serde_json::Value>>, ErrorResponse> {
    input
        .validate()
        .map_err(|e| ErrorResponse::bad_request(e.to_string()))?;
    let value = UserProfileRepository::new(state.pool)
        .upsert(user_id, input)
        .await
        .map_err(|e| ErrorResponse::internal(e.to_string()))?;
    Ok(Json(ApiResponse::success(
        serde_json::to_value(value).unwrap_or_default(),
    )))
}
pub async fn delete_profile(
    State(state): State<AppState>,
    UserId(user_id): UserId,
) -> Result<Json<ApiResponse<()>>, ErrorResponse> {
    UserProfileRepository::new(state.pool)
        .delete(&user_id)
        .await
        .map_err(|e| ErrorResponse::internal(e.to_string()))?;
    Ok(Json(ApiResponse::success_with_message(
        (),
        "profile deleted",
    )))
}
