use std::collections::HashMap;
use json::{array, JsonValue};
use lettre::{Message, SmtpTransport, Transport};
use lettre::message::{Attachment, Mailbox, MultiPart, SinglePart};
use lettre::message::header::ContentType;
use lettre::transport::smtp::authentication::Credentials;
use crate::Connection;

#[derive(Clone)]
pub struct Smtp {
    pub(crate) connection: Connection,

    pub(crate) from_name: String,
    pub(crate) from_mail: String,

    pub(crate) to_name: String,
    pub(crate) to_mail: String,

    pub(crate) to_vec: Vec<Mailbox>,
    pub(crate) cc_vec: Vec<Mailbox>,

    pub(crate) cc_name: String,
    pub(crate) cc_mail: String,

    pub(crate) body_text: String,
    pub(crate) body_html: String,

    pub subject: String,

    pub(crate) files: HashMap<String, SinglePart>,
}

impl Smtp {
    pub fn new(connection: Connection) -> Self {
        return Self {
            connection: connection.clone(),
            from_name: connection.name.to_string(),
            from_mail: connection.mail.to_string(),

            to_vec: Vec::new(),
            cc_vec: Vec::new(),

            to_name: String::new(),
            to_mail: String::new(),
            cc_name: String::new(),
            cc_mail: String::new(),

            body_text: String::new(),
            body_html: String::new(),
            subject: String::new(),
            files: HashMap::new(),
        };
    }

    /// 设置发件人信息
    pub fn set_from(&mut self, from_name: &str, from_mail: &str) -> &mut Self {
        self.from_name = from_name.to_string();
        self.from_mail = from_mail.to_string();
        self
    }

    /// 收件人
    /// * name 收件人名称
    /// * mail 收件箱
    // pub fn set_to(&mut self, name: &str, mail: &str) -> &mut Self {
    //     self.to_name = name.to_string();
    //     self.to_mail = mail.to_string();
    //     self
    // }

    pub fn set_to(&mut self, to_vec: Vec<String>) -> &mut Self {
        let mut to_box: Vec<Mailbox> = vec![];
        for item in to_vec {
            let to = item.parse().unwrap();
            to_box.push(to);
        }
        self.to_vec = to_box;
        self
    }

    /// 抄送人
    /// * name 收件人名称
    /// * mail 收件箱
    // pub fn set_cc(&mut self, name: &str, mail: &str) -> &mut Self {
    //     self.cc_name = name.to_string();
    //     self.cc_mail = mail.to_string();
    //     self
    // }

    pub fn set_cc(&mut self, cc_vec: Vec<String>) -> &mut Self {
        let mut cc_box: Vec<Mailbox> = vec![];
        for item in cc_vec {
            let cc = item.parse().unwrap();
            cc_box.push(cc);
        }
        self.cc_vec = cc_box;
        self
    }
    pub fn set_body(&mut self, text: &str, html: &str) -> &mut Self {
        self.body_text = text.to_string();
        self.body_html = html.to_string();
        self
    }
    pub fn set_subject(&mut self, subject: &str) -> &mut Self {
        self.subject = subject.to_string();
        self
    }
    /// 附件
    pub fn set_file(&mut self, name: &str, data: Vec<u8>, content_type: &str) -> &mut Self {
        if self.files.get(&*name.to_string()).is_none() {
            let files = Attachment::new(name.to_string()).body(data.clone(), ContentType::parse(content_type).unwrap());
            self.files.insert(name.to_string(), files);
        }
        self
    }
    /// 发送
    ///
    /// * subject 主题
    /// * body 内容
    /// subject: &str, body_text: &str, body_html: Vec<u8>, files: Vec<SinglePart>
    pub fn send(&mut self) -> Result<Vec<u8>, String> {
        let mut builder = Message::builder().from(format!("{} <{}>", self.from_name, self.from_mail).parse().unwrap()).subject(self.subject.clone());

        // builder = builder.to(format!("{} <{}>", self.to_name, self.to_mail).parse().unwrap());
        for item in self.to_vec.clone() {
            builder = builder.to(item.clone())
        }

        if !self.cc_vec.is_empty() {
            // builder = builder.cc(format!("{} <{}>", self.cc_name, self.cc_mail).parse().unwrap());
            for item in self.cc_vec.clone() {
                builder = builder.cc(item.clone())
            }
        }

        // 发件这里传入参数html网页格式用Vec<u8>字节码
        let mut body = MultiPart::alternative().multipart(
            MultiPart::alternative_plain_html(String::from(self.body_text.clone()), String::from(self.body_html.clone()))
        );

        if self.files.len() > 0 {
            for (_, file) in self.files.iter() {
                body = body.singlepart(file.clone()).clone();
            }
        }

        let email = builder.multipart(body.clone()).unwrap();


        let mailer = SmtpTransport::relay(self.connection.host.as_str())
            .unwrap()
            .port(self.connection.port.parse::<u16>().unwrap())
            .credentials(Credentials::new(self.connection.mail.to_string(), self.connection.pass.to_string()))
            .build();
        match mailer.send(&email) {
            Ok(_) => {
                let e = email.formatted();
                Ok(e)
            }
            Err(e) => {
                Err(e.to_string())
            }
        }
    }
}
