use puuid::{prefix, Puuid};

prefix!(User, "user");
prefix!(Order, "ord");

type UserId = Puuid<User>;
type OrderId = Puuid<Order>;

#[test]
fn test_type_safety() {
    let user_id = UserId::new_v7();
    let order_id = OrderId::new_v7();

    // Verify prefixes
    assert!(user_id.to_string().starts_with("user_"));
    assert!(order_id.to_string().starts_with("ord_"));

    // Verify they are not equal (even if we forced the inner UUID to be same, types differ)
    // Note: Rust compiler prevents 'user_id == order_id' directly.
    // We can only compare strings or raw UUIDs.
    assert_ne!(user_id.to_string(), order_id.to_string());
}

#[test]
fn test_default_trait() {
    // Should default to a valid V7 (or whatever feature is enabled)
    let id = UserId::default();
    assert!(!id.is_nil());
    assert!(id.to_string().starts_with("user_"));
}

#[cfg(feature = "serde")]
#[test]
fn test_serde_struct_integration() {
    use serde::{Deserialize, Serialize};

    #[derive(Serialize, Deserialize, Debug, PartialEq)]
    struct APIResponse {
        request_id: Puuid<Request>,
        user_id: UserId,
    }

    prefix!(Request, "req");

    let req_id = Puuid::<Request>::new_v7();
    let user_id = UserId::new_v7();

    let response = APIResponse {
        request_id: req_id,
        user_id,
    };

    // Serialize
    let json = serde_json::to_string(&response).unwrap();
    println!("JSON: {}", json);

    assert!(json.contains("req_"));
    assert!(json.contains("user_"));

    // Deserialize
    let loaded: APIResponse = serde_json::from_str(&json).unwrap();
    assert_eq!(response, loaded);
}

#[test]
fn test_uuid_interop() {
    // Ensure we can use standard UUID methods
    let id = UserId::new_v7();

    // .as_bytes() comes from Deref to uuid::Uuid
    let bytes = id.as_bytes();
    assert_eq!(bytes.len(), 16);

    // .get_version() comes from Deref
    assert_eq!(id.get_version(), Some(uuid::Version::SortRand));
}
