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

/// Nível de risco do pedido
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum RiskLevel {
    /// Risco baixo
    Low,
    /// Risco médio
    Medium,
    /// Risco alto
    High,
}

impl RiskLevel {
    /// Retorna o nome do nível de risco em português
    pub fn name(&self) -> &str {
        match self {
            RiskLevel::Low => "Baixo",
            RiskLevel::Medium => "Médio",
            RiskLevel::High => "Alto",
        }
    }
}

impl fmt::Display for RiskLevel {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            RiskLevel::Low => write!(f, "low"),
            RiskLevel::Medium => write!(f, "medium"),
            RiskLevel::High => write!(f, "high"),
        }
    }
}

impl std::str::FromStr for RiskLevel {
    type Err = ValidationError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.trim().to_lowercase().as_str() {
            "low" | "baixo" => Ok(RiskLevel::Low),
            "medium" | "medio" | "médio" => Ok(RiskLevel::Medium),
            "high" | "alto" => Ok(RiskLevel::High),
            _ => Err(ValidationError::InvalidFormat {
                field: "risk_level".to_string(),
                message: format!("invalid risk level: {}", s),
            }),
        }
    }
}

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

    #[test]
    fn test_risk_level_serialization() {
        let low = RiskLevel::Low;
        let json = serde_json::to_string(&low).unwrap();
        assert_eq!(json, r#""low""#);

        let high = RiskLevel::High;
        let json = serde_json::to_string(&high).unwrap();
        assert_eq!(json, r#""high""#);
    }

    #[test]
    fn test_risk_level_deserialization() {
        let json = r#""low""#;
        let level: RiskLevel = serde_json::from_str(json).unwrap();
        assert_eq!(level, RiskLevel::Low);

        let json = r#""medium""#;
        let level: RiskLevel = serde_json::from_str(json).unwrap();
        assert_eq!(level, RiskLevel::Medium);
    }

    #[test]
    fn test_risk_level_from_str() {
        assert_eq!("low".parse::<RiskLevel>().unwrap(), RiskLevel::Low);
        assert_eq!("baixo".parse::<RiskLevel>().unwrap(), RiskLevel::Low);
        assert_eq!("medium".parse::<RiskLevel>().unwrap(), RiskLevel::Medium);
        assert_eq!("high".parse::<RiskLevel>().unwrap(), RiskLevel::High);
    }

    #[test]
    fn test_risk_level_display() {
        assert_eq!(RiskLevel::Low.to_string(), "low");
        assert_eq!(RiskLevel::Medium.to_string(), "medium");
        assert_eq!(RiskLevel::High.to_string(), "high");
    }

    #[test]
    fn test_risk_level_name() {
        assert_eq!(RiskLevel::Low.name(), "Baixo");
        assert_eq!(RiskLevel::Medium.name(), "Médio");
        assert_eq!(RiskLevel::High.name(), "Alto");
    }
}

