use actix_web::dev::ServiceResponse;
use actix_web::web::Data;
use actix_web::{App, http::StatusCode, test};
use athena_rs::AppState;
use athena_rs::api::management;
use athena_rs::api::metrics::prometheus_metrics;
use athena_rs::drivers::postgresql::sqlx_driver::PostgresClientRegistry;
use moka::future::Cache;
use reqwest::Client;
use serde_json::Value;
use std::sync::Arc;
use std::time::Instant;

fn build_test_state() -> Data<AppState> {
    let cache: Arc<Cache<String, Value>> = Arc::new(Cache::builder().build());
    let immortal_cache: Arc<Cache<String, Value>> = Arc::new(Cache::builder().build());
    let client: Client = Client::builder()
        .build()
        .expect("Failed to build HTTP client");
    let pg_registry: Arc<PostgresClientRegistry> = Arc::new(PostgresClientRegistry::empty());
    let jdbc_pool_cache = Arc::new(Cache::builder().max_capacity(64).build());

    Data::new(AppState {
        cache,
        immortal_cache,
        client,
        process_start_time_seconds: 0,
        process_started_at: Instant::now(),
        pg_registry,
        jdbc_pool_cache,
        gateway_force_camel_case_to_snake_case: false,
        gateway_auto_cast_uuid_filter_values_to_text: true,
        pipeline_registry: None,
        logging_client_name: None,
        gateway_auth_client_name: None,
        gateway_jdbc_allow_private_hosts: true,
        gateway_jdbc_allowed_hosts: vec![],
        prometheus_metrics_enabled: true,
        metrics_state: Arc::new(athena_rs::api::metrics::MetricsState::new()),
    })
}

#[actix_web::test]
async fn management_capabilities_requires_client_header() {
    let state = build_test_state();
    let app = test::init_service(
        App::new()
            .app_data(state.clone())
            .configure(management::services),
    )
    .await;

    let req = test::TestRequest::get()
        .uri("/management/capabilities")
        .to_request();
    let resp: ServiceResponse = test::call_service(&app, req).await;

    assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
}

#[actix_web::test]
async fn management_capabilities_rejects_unknown_client() {
    let state = build_test_state();
    let app = test::init_service(
        App::new()
            .app_data(state.clone())
            .configure(management::services),
    )
    .await;

    let req = test::TestRequest::get()
        .uri("/management/capabilities")
        .insert_header(("X-Athena-Client", "reporting"))
        .to_request();
    let resp: ServiceResponse = test::call_service(&app, req).await;

    assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
}

#[actix_web::test]
async fn metrics_endpoint_returns_prometheus_payload() {
    let state = build_test_state();
    let app = test::init_service(
        App::new()
            .app_data(state.clone())
            .service(prometheus_metrics),
    )
    .await;

    let req = test::TestRequest::get().uri("/metrics").to_request();
    let resp = test::call_service(&app, req).await;

    assert_eq!(resp.status(), StatusCode::OK);
    let body = test::read_body(resp).await;
    let body = std::str::from_utf8(&body).expect("valid utf8");
    assert!(body.contains("athena_uptime_seconds"));
    assert!(body.contains("athena_requests_last_24h"));
    assert!(body.contains("athena_cluster_mirror_up"));
}
