use std::env;

use lettre::{
    message::{header::ContentType, Mailbox, MultiPart, SinglePart},
    transport::smtp::{authentication::Credentials, extension::ClientId},
    Message, SmtpTransport,
};

use crate::models::User;

use super::ApplicationError;

pub fn get_mailer() -> anyhow::Result<SmtpTransport> {
    let server = &env::var("SMTP_SERVER")?;
    let port = &env::var("SMTP_PORT")?.parse()?;
    let login = &env::var("SMTP_LOGIN")
        .and_then(|x| Ok(Some(x)))
        .unwrap_or(None);
    let password = &env::var("SMTP_PASSWORD")
        .and_then(|x| Ok(Some(x)))
        .unwrap_or(None);
    let tls_type = &env::var("SMTP_TLSTYPE")?;
    let hostname = &env::var("HOSTNAME")?;

    let mut builder = match tls_type.as_str() {
        "starttls" => SmtpTransport::starttls_relay(server)?.port(*port),
        "tls" => SmtpTransport::relay(server)?.port(*port),
        _ => SmtpTransport::builder_dangerous(server).port(*port),
    };

    if let (Some(login), Some(password)) = (login, password) {
        builder = builder.credentials(Credentials::new(login.to_string(), password.to_string()));
    }

    let mailer = builder
        .hello_name(ClientId::Domain(hostname.to_string()))
        .build();

    Ok(mailer)
}

pub fn build_forgot_password_message(user: &User, token: &str) -> Message {
    let hostname = env::var("HOSTNAME").unwrap();
    let reset_url = format!("https://{hostname}/reset-password?token={token}");

    let message = Message::builder()
                .from("noreply <noreply@brasiwa-leipzig.de>".parse().unwrap())
                .reply_to("noreply <noreply@brasiwa-leipzig.de>".parse().unwrap())
                .to(format!("{} <{}>", user.name, user.email).parse().unwrap())
                .subject("Brass: Zurücksetzen des Passworts angefordert")
                .multipart(
                    MultiPart::alternative()
                        .singlepart(
                            SinglePart::builder()
                                .header(ContentType::TEXT_PLAIN)
                                .body(format!(r##"Hallo {},

du hast angefordert, dein Passwort zurückzusetzen. Kopiere dafür folgenden Link in deinen Browser:

{reset_url}

Bitte beachte, dass der Link nur 24 Stunden gültig ist. Solltest du nichts angefordert haben, dann musst du nichts weiter tun.

Viele Grüße"##, user.name))
                )
                .singlepart(
                    SinglePart::builder()
                        .header(ContentType::TEXT_HTML)
                        .body(format!(r##"<p>Hallo {},</p>

<p>du hast angefordert, dein Passwort zurückzusetzen. Klicke dafür <a href="{reset_url}" target="_blank">hier</a> oder kopiere folgenden Link in deinen Browser:</p>

<p>{reset_url}</p>

<p>Bitte beachte, dass der Link <b>nur 24 Stunden gültig</b> ist. Solltest du nichts angefordert haben, dann musst du nichts weiter tun.</p>

<p>Viele Grüße</p>"##, user.name))
                ))
                .unwrap();

    return message;
}

pub fn build_registration_message(user: &User, token: &str) -> Result<Message, ApplicationError> {
    let hostname = env::var("HOSTNAME")?;
    let register_url = format!("https://{hostname}/register?token={token}");

    let message = Message::builder()
                .from("noreply <noreply@brasiwa-leipzig.de>".parse()?)
                .reply_to("noreply <noreply@brasiwa-leipzig.de>".parse()?)
                .to(Mailbox::new(Some(user.name.clone()), user.email.parse()?))
                .subject("Brass: Registrierung deines Accounts")
                .multipart(
                    MultiPart::alternative()
                        .singlepart(
                            SinglePart::builder()
                                .header(ContentType::TEXT_PLAIN)
                                .body(format!(r##"Hallo {},

dein Account für https:://{hostname} wurde erstellt. Du musst nur noch ein Passwort festlegen. Kopiere dafür folgenden Link in deinen Browser:

{register_url}

Bitte beachte, dass der Link nur 24 Stunden gültig ist.

Viele Grüße"##, user.name))
                )
                .singlepart(
                    SinglePart::builder()
                        .header(ContentType::TEXT_HTML)
                        .body(format!(r##"<p>Hallo {},</p>

<p>dein Account für <a href="https:://{hostname}" target="_blank">https://{hostname}</a> wurde erstellt. Du musst nur noch ein Passwort festlegen. Klicke dafür <a href="{register_url}" target="_blank">hier</a> oder kopiere folgenden Link in deinen Browser:</p>

<p>{register_url}</p>

<p>Bitte beachte, dass der Link <b>nur 24 Stunden gültig</b> ist.</p>

<p>Viele Grüße</p>"##, user.name))
                ))
                ?;

    Ok(message)
}
