use tauri::AppHandle;
use lettre::{Message, SmtpTransport, Transport, AsyncTransport};
use lettre::transport::smtp::authentication::Credentials;
use lettre::transport::smtp::AsyncSmtpTransport;
use lettre::Tokio1Executor;

#[derive(serde::Deserialize)]
pub struct SmtpConfig {
    host: String,
    port: u16,
    username: String,
    password: String,
    sender_email: String,
    sender_name: Option<String>,
}

#[derive(serde::Deserialize)]
pub struct EmailMessage {
    to: Vec<String>,
    subject: String,
    body_html: String,
}

#[tauri::command]
pub async fn send_smtp_email(app: AppHandle, config: SmtpConfig, message: EmailMessage) -> Result<String, String> {
    println!("SMTP: Preparing to send email to {:?}", message.to);
    
    // 1. Build Message
    let sender_str = if let Some(name) = &config.sender_name {
        format!("{} <{}>", name, config.sender_email)
    } else {
        config.sender_email.clone()
    };

    let mut builder = Message::builder()
        .from(sender_str.parse().map_err(|e: lettre::address::AddressError| e.to_string())?)
        .subject(message.subject);

    for recipient in message.to {
        builder = builder.to(recipient.parse().map_err(|e: lettre::address::AddressError| e.to_string())?);
    }

    let email = builder
        .header(lettre::message::header::ContentType::TEXT_HTML)
        .body(message.body_html)
        .map_err(|e| e.to_string())?;

    // 2. Build Transport
    println!("SMTP: Connecting to {}:{}...", config.host, config.port);
    let creds = Credentials::new(config.username, config.password);

    // TLS Configuration
    // Proton Mail and others on 465 require Implicit TLS (Wrapper).
    // Others on 587 use STARTTLS (Opportunistic).
    
    use lettre::transport::smtp::client::{Tls, TlsParameters};

    let tls_params = TlsParameters::builder(config.host.clone())
        .build()
        .map_err(|e| format!("TLS Params error: {}", e))?;

    let builder = AsyncSmtpTransport::<Tokio1Executor>::relay(&config.host)
        .map_err(|e| e.to_string())?
        .port(config.port)
        .credentials(creds);

    let mailer: AsyncSmtpTransport<Tokio1Executor> = if config.port == 465 {
        println!("SMTP: Using Implicit TLS (Wrapper) for port 465");
        builder.tls(Tls::Wrapper(tls_params)).build()
    } else {
        println!("SMTP: Using Opportunistic TLS (STARTTLS) for port {}", config.port);
        builder.tls(Tls::Opportunistic(tls_params)).build()
    };

    // 3. Send with Timeout
    println!("SMTP: Sending...");
    let send_task = mailer.send(email);
    
    match tokio::time::timeout(std::time::Duration::from_secs(15), send_task).await {
        Ok(result) => match result {
            Ok(_) => {
                println!("SMTP: Success!");
                Ok("Email sent successfully".to_string())
            },
            Err(e) => {
                println!("SMTP: Failed: {}", e);
                // Hint at common issues
                Err(format!("Failed to send: {}. (Check Host/Port/Password)", e))
            }
        },
        Err(_) => {
            println!("SMTP: Timeout");
            Err("Connection timed out after 15s. Try changing Port (465 vs 587) or check VPN/Firewall.".to_string())
        }
    }
}
