use lmrc_cloudflare::{CloudflareClient, Error, RetryConfig};
use std::time::Duration;

#[test]
fn test_builder_requires_api_token() {
    let result = CloudflareClient::builder().build();
    assert!(result.is_err());
    match result.unwrap_err() {
        Error::InvalidInput(msg) => assert_eq!(msg, "API token is required"),
        _ => panic!("Expected InvalidInput error"),
    }
}

#[test]
fn test_builder_with_api_token() {
    let client = CloudflareClient::builder().api_token("test-token").build();
    assert!(client.is_ok());
}

#[test]
fn test_builder_with_custom_base_url() {
    let client = CloudflareClient::builder()
        .api_token("test-token")
        .base_url("https://custom.api.com")
        .build()
        .unwrap();

    assert_eq!(client.base_url, "https://custom.api.com");
}

#[test]
fn test_builder_with_custom_timeout() {
    let client = CloudflareClient::builder()
        .api_token("test-token")
        .timeout(Duration::from_secs(60))
        .build();
    assert!(client.is_ok());
}

#[test]
fn test_builder_with_retry_config() {
    let retry_config = RetryConfig {
        max_retries: 5,
        initial_delay: Duration::from_millis(1000),
        max_delay: Duration::from_secs(60),
        backoff_multiplier: 2.0,
    };

    let client = CloudflareClient::builder()
        .api_token("test-token")
        .retry_config(retry_config.clone())
        .build()
        .unwrap();

    assert_eq!(client.retry_config.max_retries, 5);
    assert_eq!(
        client.retry_config.initial_delay,
        Duration::from_millis(1000)
    );
}

#[test]
fn test_builder_with_disabled_retries() {
    let client = CloudflareClient::builder()
        .api_token("test-token")
        .retry_config(RetryConfig::disabled())
        .build()
        .unwrap();

    assert_eq!(client.retry_config.max_retries, 0);
}

#[test]
fn test_new_constructor() {
    let client = CloudflareClient::new("test-token");
    assert!(client.is_ok());
}

#[test]
fn test_default_retry_config() {
    let config = RetryConfig::default();
    assert_eq!(config.max_retries, 3);
    assert_eq!(config.initial_delay, Duration::from_millis(500));
    assert_eq!(config.max_delay, Duration::from_secs(30));
    assert_eq!(config.backoff_multiplier, 2.0);
}

#[test]
fn test_retry_config_delay_calculation() {
    let config = RetryConfig::default();

    // First attempt: 500ms
    assert_eq!(config.delay_for_attempt(0), Duration::from_millis(500));

    // Second attempt: 500 * 2 = 1000ms
    assert_eq!(config.delay_for_attempt(1), Duration::from_millis(1000));

    // Third attempt: 500 * 4 = 2000ms
    assert_eq!(config.delay_for_attempt(2), Duration::from_millis(2000));

    // Fourth attempt: 500 * 8 = 4000ms
    assert_eq!(config.delay_for_attempt(3), Duration::from_millis(4000));
}

#[test]
fn test_retry_config_max_delay() {
    let config = RetryConfig {
        max_retries: 10,
        initial_delay: Duration::from_secs(1),
        max_delay: Duration::from_secs(5),
        backoff_multiplier: 2.0,
    };

    // Should cap at max_delay
    assert_eq!(config.delay_for_attempt(10), Duration::from_secs(5));
}

#[test]
fn test_client_is_cloneable() {
    let client = CloudflareClient::new("test-token").unwrap();
    let _cloned = client.clone();
    // Should compile and work
}

#[test]
fn test_invalid_token_format() {
    // Tokens with null bytes should fail
    let result = CloudflareClient::builder().api_token("test\0token").build();

    assert!(result.is_err());
    match result.unwrap_err() {
        Error::InvalidInput(msg) => assert_eq!(msg, "Invalid API token format"),
        _ => panic!("Expected InvalidInput error for invalid token format"),
    }
}
