use actix_web::{web, HttpResponse};
use serde_json::json;

use crate::api::athena_guard;
use crate::data::provider_requests::{self, DataSourceProviderRequestNew};
use crate::AppState;

pub async fn list_provider_requests(state: web::Data<AppState>) -> HttpResponse {
    let Some(cli) = athena_guard::athena_client(state.get_ref()) else {
        return athena_guard::no_athena_response();
    };
    match provider_requests::list_requests(cli).await {
        Ok(rows) => HttpResponse::Ok().json(rows),
        Err(e) => HttpResponse::InternalServerError().json(json!({"error": e.to_string()})),
    }
}

pub async fn get_provider_request(state: web::Data<AppState>, path: web::Path<i64>) -> HttpResponse {
    let Some(cli) = athena_guard::athena_client(state.get_ref()) else {
        return athena_guard::no_athena_response();
    };
    let id = path.into_inner();
    match provider_requests::get_request_by_id(cli, id).await {
        Ok(Some(row)) => HttpResponse::Ok().json(row),
        Ok(None) => HttpResponse::NotFound().json(json!({"error": "not found"})),
        Err(e) => HttpResponse::InternalServerError().json(json!({"error": e.to_string()})),
    }
}

pub async fn post_provider_request(
    state: web::Data<AppState>,
    body: web::Json<DataSourceProviderRequestNew>,
) -> HttpResponse {
    let Some(cli) = athena_guard::athena_client(state.get_ref()) else {
        return athena_guard::no_athena_response();
    };
    match provider_requests::insert_request(cli, &body).await {
        Ok(()) => HttpResponse::Created().json(json!({"ok": true})),
        Err(e) => HttpResponse::BadRequest().json(json!({"error": e.to_string()})),
    }
}

pub async fn put_provider_request(
    state: web::Data<AppState>,
    path: web::Path<i64>,
    body: web::Json<DataSourceProviderRequestNew>,
) -> HttpResponse {
    let Some(cli) = athena_guard::athena_client(state.get_ref()) else {
        return athena_guard::no_athena_response();
    };
    let id = path.into_inner();
    match provider_requests::update_request(cli, id, &body).await {
        Ok(()) => HttpResponse::Ok().json(json!({"ok": true})),
        Err(e) => HttpResponse::BadRequest().json(json!({"error": e.to_string()})),
    }
}

pub async fn delete_provider_request(state: web::Data<AppState>, path: web::Path<i64>) -> HttpResponse {
    let Some(cli) = athena_guard::athena_client(state.get_ref()) else {
        return athena_guard::no_athena_response();
    };
    let id = path.into_inner();
    match provider_requests::delete_request(cli, id).await {
        Ok(()) => HttpResponse::NoContent().finish(),
        Err(e) => HttpResponse::BadRequest().json(json!({"error": e.to_string()})),
    }
}
