use crate::dev::DevApi;
use axum::body::Body;
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::routing::put;
use axum::{Extension, Json, Router};
use etwin_core::hammerfest::{HammerfestPassword, HammerfestServer, HammerfestUserId, HammerfestUsername};
use serde::{Deserialize, Serialize};
use thiserror::Error;

pub fn router() -> Router<Body> {
  Router::new().route("/users", put(upsert_hammerfest_user))
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub(crate) struct UpsertHammerfestUserBody {
  pub server: HammerfestServer,
  pub id: HammerfestUserId,
  pub username: HammerfestUsername,
  pub password: HammerfestPassword,
}

#[derive(Debug, Error)]
enum UpsertHammerfestUserError {
  #[error("dev hammerfest_client API is disabled")]
  Disabled,
}

impl IntoResponse for UpsertHammerfestUserError {
  fn into_response(self) -> Response {
    (StatusCode::FORBIDDEN, self.to_string()).into_response()
  }
}

async fn upsert_hammerfest_user(
  Extension(dev_api): Extension<DevApi>,
  Json(body): Json<UpsertHammerfestUserBody>,
) -> Result<(StatusCode, Json<UpsertHammerfestUserBody>), UpsertHammerfestUserError> {
  let hammerfest_client = dev_api.hammerfest_client.ok_or(UpsertHammerfestUserError::Disabled)?;
  {
    let body = body.clone();
    hammerfest_client.create_user(body.server, body.id, body.username, body.password);
  }
  Ok((StatusCode::OK, Json(body)))
}
