//! Email service initialization
//!
//! This module handles the initialization of email services with support for
//! multiple providers (SMTP, SendGrid, Console) and template management.

#[cfg(any(feature = "email", feature = "metrics"))]
use std::sync::Arc;

#[cfg(any(feature = "email", feature = "metrics"))]
use crate::config::Config;
#[cfg(feature = "email")]
use crate::email::{EmailService, EmailServiceBuilder};

/// Initialize email service
#[cfg(feature = "email")]
pub async fn initialize_email_service(
    config: &Config,
) -> Result<Arc<EmailService>, Box<dyn std::error::Error>> {
    // Resolve email template directory relative to root path
    let email_template_dir = config
        .email
        .template_dir
        .as_ref()
        .map(|dir| config.get_absolute_path(dir))
        .unwrap_or_else(|| config.get_absolute_path("templates/email"));

    let email_service_builder = EmailServiceBuilder::new()
        .default_from(&config.email.from_email)
        .default_from_name(&config.email.from_name)
        .template_dir(&email_template_dir.unwrap_or_default())
        .enabled(config.email.enabled);

    // Configure provider based on config
    let email_service_builder = match config.email.provider.as_str() {
        "smtp" => {
            let smtp_config = crate::email::SmtpConfig {
                host: config.email.smtp_host.clone(),
                port: config.email.smtp_port,
                username: config.email.smtp_username.clone(),
                password: config.email.smtp_password.clone(),
                use_tls: config.email.smtp_use_tls,
                use_starttls: config.email.smtp_use_starttls,
            };
            email_service_builder.smtp_provider(smtp_config)
        }
        "sendgrid" => {
            let sendgrid_config = crate::email::SendGridConfig {
                api_key: config.email.sendgrid_api_key.clone(),
                endpoint: config.email.sendgrid_endpoint.clone(),
            };
            email_service_builder.sendgrid_provider(sendgrid_config)
        }
        _ => {
            // Default to console provider
            email_service_builder.console_provider()
        }
    };

    let email_service =
        email_service_builder
            .build()
            .await
            .map_err(|e| -> Box<dyn std::error::Error> {
                tracing::error!("Failed to initialize email service: {}", e);
                Box::new(e)
            })?;

    tracing::info!(
        "Email service initialized with provider: {}",
        email_service.provider_name()
    );
    tracing::info!("Email service enabled: {}", email_service.is_enabled());
    Ok(Arc::new(email_service))
}

/// Initialize metrics service if enabled
#[cfg(feature = "metrics")]
pub fn initialize_metrics_service(
    config: &Config,
) -> Result<
    Option<(
        crate::metrics::MetricsService,
        Option<Arc<crate::metrics::MetricsRegistry>>,
    )>,
    Box<dyn std::error::Error>,
> {
    use crate::metrics::MetricsService;

    if config.app.enable_metrics {
        let service = MetricsService::new().map_err(|e| {
            tracing::error!("Failed to create metrics service: {}", e);
            std::process::exit(1);
        })?;
        let registry = service.registry().cloned();

        Ok(Some((service, registry)))
    } else {
        Ok(None)
    }
}
