use crate::types::validation_errors::ValidationError;
use serde::{Deserialize, Serialize};
use std::fmt;

/// Número de mensagens trocadas entre comprador e vendedor (marketplace)
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
#[repr(transparent)]
pub struct MessagesExchanged(u32);

impl MessagesExchanged {
    /// Cria um novo contador de mensagens validado
    pub fn new(value: u32) -> Result<Self, ValidationError> {
        Ok(Self(value))
    }

    pub fn value(&self) -> u32 {
        self.0
    }

    /// Verifica se houve troca de mensagens
    pub fn has_messages(&self) -> bool {
        self.0 > 0
    }

    /// Incrementa o contador de mensagens
    pub fn increment(&mut self) {
        self.0 = self.0.saturating_add(1);
    }
}

impl fmt::Display for MessagesExchanged {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.0 == 1 {
            write!(f, "1 mensagem")
        } else {
            write!(f, "{} mensagens", self.0)
        }
    }
}

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

    #[test]
    fn test_messages_exchanged_valid() {
        let messages = MessagesExchanged::new(30).unwrap();
        assert_eq!(messages.value(), 30);
    }

    #[test]
    fn test_messages_exchanged_zero() {
        let messages = MessagesExchanged::new(0).unwrap();
        assert_eq!(messages.value(), 0);
        assert!(!messages.has_messages());
    }

    #[test]
    fn test_messages_exchanged_has_messages() {
        let messages = MessagesExchanged::new(5).unwrap();
        assert!(messages.has_messages());
    }

    #[test]
    fn test_messages_exchanged_increment() {
        let mut messages = MessagesExchanged::new(10).unwrap();
        messages.increment();
        assert_eq!(messages.value(), 11);
    }

    #[test]
    fn test_messages_exchanged_default() {
        let messages = MessagesExchanged::default();
        assert_eq!(messages.value(), 0);
    }

    #[test]
    fn test_messages_exchanged_display() {
        let one = MessagesExchanged::new(1).unwrap();
        assert_eq!(one.to_string(), "1 mensagem");

        let many = MessagesExchanged::new(10).unwrap();
        assert_eq!(many.to_string(), "10 mensagens");
    }
}

