// US-002: Unit tests for EIP-712 signing engine and Credentials

use asterdex_sdk::{AsterDexError, Credentials};

/// US-002: Sign a known message, verify signature format (0x-prefixed, 132 chars or 130 hex chars)
#[test]
fn eip712_sign_known_vector() {
    // Hardhat test key #0
    let private_key = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
    let user = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266";
    let signer = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266";
    let creds = Credentials::new(user, signer, private_key, 714u64).unwrap();

    let params = &[
        ("symbol", "BTCUSDT"),
        ("side", "BUY"),
        ("type", "LIMIT"),
        ("quantity", "0.001"),
    ];

    let signed = creds.sign_query(params).unwrap();
    assert!(signed.contains("&signature="), "signed query must contain &signature=");

    let sig_part = signed.split("&signature=").nth(1).unwrap();
    // FORMULA-001: signature in transport must NOT have 0x prefix
    assert!(
        !sig_part.starts_with("0x"),
        "signature in query string must NOT have 0x prefix, got: {}",
        &sig_part[..sig_part.len().min(10)]
    );
    assert_eq!(
        sig_part.len(),
        130,
        "signature hex must be exactly 130 chars (65 bytes), got {}",
        sig_part.len()
    );
}

/// US-002: Set env vars, call from_env(), verify Ok
#[test]
fn credentials_from_env() {
    // Use unique env var names to avoid interference with other tests
    std::env::set_var("ASTERDEX_USER", "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266");
    std::env::set_var(
        "ASTERDEX_SIGNER_ADDRESS",
        "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
    );
    std::env::set_var(
        "ASTERDEX_SIGNER_PRIVATE_KEY",
        "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
    );
    std::env::set_var("ASTERDEX_CHAIN_ID", "714");

    let result = Credentials::from_env();
    assert!(result.is_ok(), "from_env() should succeed with valid env vars");
}

/// US-002: Call new_nonce() twice, verify second > first
#[test]
fn nonce_monotonic() {
    let creds = Credentials::new(
        "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
        "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
        "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
        714u64,
    )
    .unwrap();

    let n1 = creds.new_nonce();
    let n2 = creds.new_nonce();
    let n3 = creds.new_nonce();
    assert!(n1 < n2, "nonce must be monotonically increasing: {n1} < {n2}");
    assert!(n2 < n3, "nonce must be monotonically increasing: {n2} < {n3}");
}

/// US-002: Invalid hex private key returns ConfigError
#[test]
fn credentials_invalid_key_errors() {
    let result = Credentials::new(
        "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
        "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
        "not_a_valid_hex_key",
        714u64,
    );
    match result {
        Err(AsterDexError::ConfigError { .. }) => {} // expected
        Err(other) => panic!("expected ConfigError, got: {other}"),
        Ok(_) => panic!("expected Err(ConfigError), got Ok"),
    }
}
