use crate::EternaltwinSystem;
use axum::body::Body;
use axum::extract::{Extension, Path};
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::routing::get;
use axum::{Json, Router};
use eternaltwin_core::auth::AuthContext;
use eternaltwin_core::hammerfest::{GetHammerfestUserOptions, HammerfestServer, HammerfestUser, HammerfestUserId};
use serde::Serialize;
use serde_json::json;

pub fn router() -> Router<(), Body> {
  Router::new().route("/:server/users/:user_id", get(get_user))
}

#[derive(Copy, Clone, Debug, Serialize)]
#[serde(tag = "error")]
enum GetHammerfestUserError {
  HammerfestUserNotFound,
  InternalServerError,
}

impl IntoResponse for GetHammerfestUserError {
  fn into_response(self) -> Response {
    let status = match self {
      Self::HammerfestUserNotFound => StatusCode::NOT_FOUND,
      Self::InternalServerError => StatusCode::INTERNAL_SERVER_ERROR,
    };
    let (status, body) = match serde_json::to_value(self) {
      Ok(body) => (status, Json(body)),
      Err(_) => (
        StatusCode::INTERNAL_SERVER_ERROR,
        Json(json!({"error": "InternalServerError"})),
      ),
    };
    (status, body).into_response()
  }
}

async fn get_user(
  Extension(api): Extension<EternaltwinSystem>,
  Path((server, id)): Path<(HammerfestServer, HammerfestUserId)>,
) -> Result<Json<HammerfestUser>, GetHammerfestUserError> {
  let acx = AuthContext::guest();
  match api
    .hammerfest
    .get_user(&acx, &GetHammerfestUserOptions { server, id, time: None })
    .await
  {
    Ok(Some(result)) => Ok(Json(result)),
    Ok(None) => Err(GetHammerfestUserError::HammerfestUserNotFound),
    Err(_) => Err(GetHammerfestUserError::InternalServerError),
  }
}
