use std::time::Duration;

use dotenvy::dotenv;
use reqwest::blocking::Client;
use reqwest::header::{AUTHORIZATION, CONTENT_TYPE, HeaderMap, HeaderValue};
use sunocore::models::studio::StudioProject;
use sunocore::validation::env::{suno_api_key_unwrap, suno_base_url_unwrap};
use uuid::Uuid;

// Integration test: fetch from <SUNO_BASE_URL>/api/studio/project/<project_id>
// and ensure it deserializes into StudioProject.
//
// Disabled by default so CI/local runs don't fail if the backend isn't running.
// Run with: cargo test --test integration_suno_project -- --ignored
#[test]
fn fetch_and_deserialize_studio_project() {
    // Load .env for SUNO_BASE_URL and SUNO_API_KEY
    let _ = dotenv();

    let base = suno_base_url_unwrap();

    let project_id = "a6d2bb30-0004-4860-b6bb-1639ca065957".to_string();

    let expected_uuid = Uuid::parse_str(&project_id)
        .expect("STUDIO_PROJECT_ID must be a valid UUID (or set it in .env)");

    let url = format!(
        "{}/api/studio/project/{}",
        base.trim_end_matches('/'),
        project_id
    );

    let mut headers = HeaderMap::new();
    headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));

    let api_key = suno_api_key_unwrap();

    if let Some(api_key) = api_key.as_ref() {
        // Send both common auth styles to maximize compatibility with local/staging
        headers.insert(
            AUTHORIZATION,
            HeaderValue::from_str(&format!("Bearer {}", api_key)).expect("valid header"),
        );
        headers.insert(
            "X-Api-Key",
            HeaderValue::from_str(api_key).expect("valid header"),
        );
    }

    let client = Client::builder()
        .default_headers(headers)
        .timeout(Duration::from_secs(20))
        .build()
        .expect("build http client");

    let resp = client
        .get(&url)
        .send()
        .unwrap_or_else(|e| panic!("request to {} failed: {}", url, e));

    assert!(
        resp.status().is_success(),
        "HTTP {} fetching {}. Did you set SUNO_API_KEY and run the backend at SUNO_BASE_URL?",
        resp.status(),
        url
    );

    // Read text then deserialize for better error messages when schema drifts.
    let body = resp
        .text()
        .unwrap_or_else(|e| panic!("reading body from {} failed: {}", url, e));
    let project: StudioProject = serde_json::from_str(&body).unwrap_or_else(|e| {
        panic!(
            "deserialization failed for {}: {}\nbody: {}",
            url,
            e,
            &body[..body.len().min(2000)]
        )
    });

    // Basic sanity checks
    assert_eq!(project.id, expected_uuid, "mismatched project id");
    assert!(!project.title.is_empty(), "title should not be empty");
    assert!(
        project.state.tracks.len() > 0,
        "expected at least one track"
    );
}
