use super::address::Address;

/// Alias para endereço de cobrança
///
/// `BillingAddress` é semanticamente um endereço de cobrança, mas usa
/// exatamente a mesma estrutura e funcionalidades de `Address`.
///
/// # Exemplo
///
/// ```rust
/// use konduto::Country;
/// use konduto::BillingAddress;
///
/// let billing = BillingAddress::builder()
///     .name("João Silva").unwrap()
///     .address1("Rua das Flores, 123").unwrap()
///     .city("São Paulo").unwrap()
///     .state("SP").unwrap()
///     .zip("01234-567").unwrap()
///     .country(Country::BR)
///     .build();
/// ```
pub type BillingAddress = Address;

// Re-exportar os tipos de validação para facilitar o uso
pub use super::address::{
    AddressLine as BillingLine,
    AddressName as BillingName,
    City as BillingCity,
    Country as BillingCountry,
    CountryCode as BillingCountryCode, // Alias mantido para compatibilidade
    State as BillingState,
    ZipCode as BillingZipCode,
};

#[cfg(test)]
mod tests {
    use super::*;
    use crate::Country;

    #[test]
    fn test_billing_address_creation() -> Result<(), Box<dyn std::error::Error>> {
        let billing = BillingAddress::builder()
            .name("John Doe")?
            .address1("123 Main St")?
            .city("São Paulo")?
            .state("SP")?
            .zip("01234-567")?
            .country(Country::BR)
            .build();

        assert!(billing.name.is_some());
        assert_eq!(billing.name.unwrap().as_str(), "John Doe");
        assert_eq!(billing.city.unwrap().as_str(), "São Paulo");
        Ok(())
    }

    #[test]
    fn test_billing_address_serialization() -> Result<(), Box<dyn std::error::Error>> {
        let billing = BillingAddress::builder()
            .name("Jane Doe")?
            .address1("456 Oak Ave")?
            .city("Rio de Janeiro")?
            .state("RJ")?
            .zip("20000-000")?
            .country(Country::BR)
            .build();

        let json = serde_json::to_string(&billing).unwrap();
        assert!(json.contains("Jane Doe"));
        assert!(json.contains("Rio de Janeiro"));
        Ok(())
    }

    #[test]
    fn test_billing_address_default() {
        let billing = BillingAddress::default();
        assert!(billing.name.is_none());
        assert!(billing.address1.is_none());
    }

    #[test]
    fn test_billing_address_is_address() {
        // Verifica que BillingAddress pode ser usado onde Address é esperado
        fn accepts_address(_addr: &Address) {}

        let billing = BillingAddress::builder().name("Test").unwrap().build();

        accepts_address(&billing); // Funciona porque BillingAddress = Address
    }
}
