use api::{AppState, build_app};
use axum::body::Body;
use axum::http::{Request, StatusCode};
use http_body_util::BodyExt;
use sqlx::PgPool;
use tower::ServiceExt; // for `oneshot`

fn state(pool: PgPool, app_name: &str) -> AppState {
    AppState {
        db: db::Db::from_pool(pool),
        app_name: app_name.to_string(),
        cookie_secure: false,
        search: None,
        default_language: "sv".into(),
        default_timezone: "Europe/Stockholm".into(),
    }
}

#[sqlx::test]
async fn live_returns_ok(pool: PgPool) {
    let app = build_app(state(pool, "Test"));
    let resp = app
        .oneshot(
            Request::builder()
                .uri("/health/live")
                .body(Body::empty())
                .unwrap(),
        )
        .await
        .unwrap();

    assert_eq!(resp.status(), StatusCode::OK);
    let bytes = resp.into_body().collect().await.unwrap().to_bytes();
    let json: serde_json::Value = serde_json::from_slice(&bytes).unwrap();
    assert_eq!(json["status"], "ok");
}

#[sqlx::test]
async fn ready_reports_database_true(pool: PgPool) {
    let app = build_app(state(pool, "Test"));
    let resp = app
        .oneshot(
            Request::builder()
                .uri("/health/ready")
                .body(Body::empty())
                .unwrap(),
        )
        .await
        .unwrap();

    assert_eq!(resp.status(), StatusCode::OK);
    let bytes = resp.into_body().collect().await.unwrap().to_bytes();
    let json: serde_json::Value = serde_json::from_slice(&bytes).unwrap();
    assert_eq!(json["database"], true);
    assert_eq!(json["status"], "ok");
}

#[sqlx::test]
async fn openapi_doc_uses_configured_title(pool: PgPool) {
    let app = build_app(state(pool, "My Museum CMS"));
    let resp = app
        .oneshot(
            Request::builder()
                .uri("/api-docs/openapi.json")
                .body(Body::empty())
                .unwrap(),
        )
        .await
        .unwrap();

    assert_eq!(resp.status(), StatusCode::OK);
    let bytes = resp.into_body().collect().await.unwrap().to_bytes();
    let json: serde_json::Value = serde_json::from_slice(&bytes).unwrap();
    assert_eq!(json["info"]["title"], "My Museum CMS");
}
