#[derive(Debug, Clone, PartialEq, thiserror::Error)]
pub enum ValidationError {
    #[error("Campo '{0}' não pode estar vazio")]
    EmptyField(String),

    #[error("Campo '{field}' excede o tamanho máximo de {max} caracteres (atual: {actual})")]
    TooLong {
        field: String,
        max: usize,
        actual: usize,
    },

    #[error("Campo '{field}' tem formato inválido: {message}")]
    InvalidFormat { field: String, message: String },

    #[error("Campo '{field}' fora do intervalo válido [{min}, {max}] (atual: {actual})")]
    OutOfRange {
        field: String,
        min: f64,
        max: f64,
        actual: f64,
    },

    #[error("{0}")]
    Generic(String),
}

/// Macro para implementar conversão automática de erros do nutype para ValidationError
///
/// Esta macro reduz o boilerplate de implementar `From<NutypeError> for ValidationError`
/// para cada tipo validado usando nutype.
///
/// # Exemplo
///
/// ```rust
/// use nutype::nutype;
/// use konduto::impl_nutype_error_conversion;
///
/// #[nutype(
///     sanitize(trim),
///     validate(not_empty, len_char_max = 100),
///     derive(Debug, Clone, Serialize, Deserialize)
/// )]
/// pub struct MyType(String);
///
/// // Antes: 5 linhas de código boilerplate
/// // impl From<MyTypeError> for ValidationError {
/// //     fn from(err: MyTypeError) -> Self {
/// //         ValidationError::Generic(err.to_string())
/// //     }
/// // }
///
/// // Depois: 1 linha
/// impl_nutype_error_conversion!(MyTypeError);
/// ```
#[macro_export]
macro_rules! impl_nutype_error_conversion {
    ($error_type:ty) => {
        impl From<$error_type> for $crate::types::validation_errors::ValidationError {
            fn from(err: $error_type) -> Self {
                $crate::types::validation_errors::ValidationError::Generic(err.to_string())
            }
        }
    };
}
