use crate::ValidationError;
use base64::Engine;
use base64::engine::general_purpose;
use std::fmt;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KondutoApiKey(String);

const FIELD_NAME: &str = "konduto_api_key";

impl KondutoApiKey {
    const MAX_LENGTH: usize = 25;
    pub fn new(value: impl Into<String>) -> Result<Self, ValidationError> {
        let input = value.into();
        let trimmed = input.trim();

        if trimmed.is_empty() {
            return Err(ValidationError::EmptyField(FIELD_NAME.to_string()));
        }

        if trimmed.len() > Self::MAX_LENGTH {
            return Err(ValidationError::TooLong {
                field: FIELD_NAME.to_string(),
                max: Self::MAX_LENGTH,
                actual: trimmed.len(),
            });
        }

        Ok(Self(trimmed.to_string()))
    }

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

    pub fn as_b64(&self) -> String {
        let encoded = general_purpose::STANDARD.encode(self.as_str().as_bytes());
        format!("Basic {}", encoded)
    }
}

impl fmt::Display for KondutoApiKey {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}
