use crate::types::shared::email::Email;
use crate::types::validation_errors::ValidationError;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CustomerEmail(Email);

impl CustomerEmail {
    /// Cria um novo email de cliente
    ///
    /// # Erros
    ///
    /// Retorna erro se o email for inválido ou exceder 100 caracteres
    pub fn new(email: impl Into<String>) -> Result<Self, ValidationError> {
        let parsed_email =
            Email::try_from(email.into()).map_err(|e| ValidationError::InvalidFormat {
                field: "email".to_string(),
                message: e.to_string(),
            })?;

        Ok(Self(parsed_email))
    }

    pub fn as_str(&self) -> &str {
        self.0.as_str()
    }
}

impl Serialize for CustomerEmail {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> Deserialize<'de> for CustomerEmail {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        CustomerEmail::new(s).map_err(serde::de::Error::custom)
    }
}
