use json::{JsonValue, object};
use rs_pop3::POP3Result::{POP3Message, POP3Stat};
use rs_pop3::POP3Stream;
use openssl::ssl::{SslConnector, SslMethod};

pub struct Pop3 {
    default: String,
    connections: JsonValue,
    pop3_host: String,
    pop3_port: u16,
    send_email: String,
    send_pass: String,
    imap_host: String,
    imap_port: u16,
    mode: String,
}

impl Pop3 {
    pub fn new(config: JsonValue) -> Self {
        let default = config["default"].to_string();
        let connections = config["connections"].clone();
        let connection = connections[default.clone()].clone();

        let pop3_host = connection["pop3_host"].to_string();
        let pop3_port = connection["pop3_port"].as_u16().unwrap();
        let imap_host = connection["imap_host"].to_string();
        let imap_port = connection["imap_port"].as_u16().unwrap();
        let send_email = connection["send_email"].to_string();
        let send_pass = connection["send_pass"].to_string();
        let mode = connection["mode"].to_string();


        Self {
            default,
            connections,
            pop3_host,
            pop3_port,
            imap_host,
            imap_port,
            send_email,
            send_pass,
            mode,
        }
    }
    pub fn change_connection(&mut self, name: &str) {
        let connection = self.connections[name.clone()].clone();
        self.default = name.to_string();
        self.pop3_host = connection["pop3_host"].to_string();
        self.pop3_port = connection["pop3_port"].as_u16().unwrap();
        self.send_email = connection["send_email"].to_string();
        self.send_pass = connection["send_pass"].to_string();
        self.imap_host = connection["imap_host"].to_string();
        self.imap_port = connection["imap_port"].as_u16().unwrap();
    }
    pub fn connect(&mut self) {
        let mut gmail_socket = match POP3Stream::connect(
            (self.pop3_host.as_str().clone(), self.pop3_port),
            Some(SslConnector::builder(SslMethod::tls()).unwrap().build())
            , self.pop3_host.as_str().clone(),
        ) {
            Ok(s) => s,
            Err(e) => panic!("{}", e)
        };

        gmail_socket.login(self.send_email.as_str().clone(), self.send_pass.as_str().clone());

        let stat = gmail_socket.stat();
        match stat {
            POP3Stat {
                num_email,
                mailbox_size
            } => println!("总邮件数量: {},  mailbox_size:{}", num_email, mailbox_size),
            _ => println!("Err for stat"),
        }

        // let list_all = gmail_socket.list(None);
        // match list_all {
        //     POP3List { emails_metadata } => {
        //         for i in emails_metadata.iter() {
        //             println!("message_id: {},  message_size: {}", i.message_id, i.message_size);
        //         }
        //     }
        //     _ => println!("Err for list_all"),
        // }

        let message_25 = gmail_socket.retr(4820);
        match message_25 {
            POP3Message { raw } => {
                let data = self.cl(raw.join(""));
                println!("{:#}", data);
            }
            _ => println!("Error for message_25"),
        }

        gmail_socket.quit();
    }
    fn cl(&mut self, data: String) -> JsonValue {
        match self.mode.as_str() {
            "qq" => self.qq(data),
            _ => self.qq(data)
        }
    }
    fn qq(&mut self, body: String) -> JsonValue {
        let mut data = object! {};
        let mut body: Vec<&str> = body.split("\r\n\r\n").collect();
        let mut heads: Vec<&str> = body[0].split("\r\n").collect();
        body.remove(0);
        for item in heads.iter_mut() {
            if data["received"].is_empty() && item.contains("Received: ") {
                data["received"] = item.trim_start_matches("Received: from ").into();
                *item = "";
                continue;
            }
            if data["by"].is_empty() && item.contains("\tby ") {
                data["by"] = item.trim_start_matches("\tby ").into();
                *item = "";
                continue;
            }
            if data["id"].is_empty() && item.contains("\tid ") {
                data["id"] = item.trim_start_matches("\tid ").into();
                *item = "";
                continue;
            }
            if data["X-QQ-mid"].is_empty() && item.contains("X-QQ-mid: ") {
                data["X-QQ-mid"] = item.trim_start_matches("X-QQ-mid: ").into();
                *item = "";
                continue;
            }
            if data["Message-ID"].is_empty() && item.contains("Message-ID: ") {
                data["Message-ID"] = item.trim_start_matches("Message-ID: ").into();
                *item = "";
                continue;
            }
            if data["form"].is_empty() && item.contains("From: ") {
                data["form"] = item.trim_start_matches("From: ").into();
                *item = "";
                continue;
            }
            if data["subject"].is_empty() && item.contains("Subject: ") {
                data["subject"] = item.trim_start_matches("Subject: ").into();
                *item = "";
                continue;
            }
            if data["to"].is_empty() && item.contains("To: ") {
                data["to"] = item.trim_start_matches("To: ").into();
                *item = "";
                continue;
            }
            if data["reply-to"].is_empty() && item.contains("Reply-To: ") {
                data["reply-to"] = item.trim_start_matches("Reply-To: ").into();
                *item = "";
                continue;
            }
            if data["mine-version"].is_empty() && item.contains("MIME-Version: ") {
                data["mine-version"] = item.trim_start_matches("MIME-Version: ").into();
                *item = "";
                continue;
            }
            if data["date"].is_empty() && item.contains("Date: ") {
                data["date"] = item.trim_start_matches("Date: ").into();
                *item = "";
                continue;
            }
            if data["content-type"].is_empty() && item.contains("Content-Type: ") {
                data["content-type"] = item.trim_start_matches("Content-Type: ").into();
                *item = "";
                continue;
            }
            if data["boundary"].is_empty() && item.contains(" boundary=") {
                data["boundary"] = item.trim_start_matches(" boundary=").trim_start_matches("\"").trim_end_matches("\"").into();
                *item = "";
                continue;
            }
            if data["x-qq-xmailinfo"].is_empty() && item.contains("X-QQ-XMAILINFO: ") {
                data["x-qq-xmailinfo"] = item.trim_start_matches("X-QQ-XMAILINFO: ").into();
                *item = "";
                continue;
            }
            if item.contains("\t ") {
                data["x-qq-xmailinfo"] = format!("{}{}", data["x-qq-xmailinfo"], item.trim_start_matches("\t ")).into();
                *item = "";
                continue;
            }
        }
        // let xmailinfo = data["x-qq-xmailinfo"].to_string();
        // let xmailinfo = df_crypto::base64::decode(xmailinfo);
        // println!("{:#?}", xmailinfo);

        let body = body.join("\r\n");
        let body: Vec<&str> = body.split("\r\n").collect();

        println!("{:#?}", body);
        // let boundary = format!("--{}", data["boundary"]);
        // let mut body: Vec<&str> = body.split(boundary.as_str().clone()).collect();
        // let body = body.join("");
        // let mut body: Vec<&str> = body.split("\r\n\r\n\r\n\r\n").collect();
        //
        // // if body[0].is_empty() {
        // //     body.remove(0);
        // // }
        // if body[body.len() - 1].to_string() == "--" {
        //     body.remove(body.len() - 1);
        // }
        // for item in body.iter_mut() {
        //     if item.to_string()=="--"{
        //         *item="";
        //         continue;
        //     }
        //     if item.contains("\r\n\r\nContent-Type: "){
        //         let
        //         println!("{:#?}", item.split("\r\n\\r\n").collect());
        //         *item="";
        //         continue;
        //     }
        // }


        // let heads = data[0].clone();
        // let mut body = String::new();
        // for index in 1..data.len() {
        //     body = format!("{}{}", body.clone(), data[index]);
        // }
        // let body: Vec<&str> = body.split("\r\n").collect();
        // let body = body[0].to_string();
        //
        // let mut list: Vec<&str> = heads.split("\r\n").collect();
        //
        // let size = list[0].to_string()[4..list[0].to_string().len()].to_string();
        // let mut subject = String::new();
        // let mut from_name = String::new();
        // let mut from_mail = String::new();
        // let mut sender = String::new();
        // let mut encoding = String::new();
        //
        // let mut to_name = String::new();
        // let mut to_mail = String::new();
        // let mut reply_to_name = String::new();
        // let mut reply_to_mail = String::new();
        // let mut date = String::new();
        // let mut content_type = String::new();

        // for item in list.iter_mut() {
        //     let text = item.to_string();
        //
        //     if text.contains("Content-Type:") {
        //         let ttt: Vec<&str> = text.split(": ").collect();
        //         let content_types = ttt[1].to_string();
        //         if content_types.contains("multipart/alternative") {
        //             content_type = "multipart/alternative".to_string();
        //         } else {
        //             content_type = "base64".to_string();
        //         }
        //     }
        //
        //     if text.contains("Subject: ") {
        //         let ttt: Vec<&str> = text.split(": ").collect();
        //         subject = ttt[1].to_string();
        //         if text.contains("b?") {
        //             let ttt: Vec<&str> = subject.split("?").collect();
        //             subject = ttt[3].to_string();
        //             subject = df_crypto::base64::decode(subject.to_string()).clone();
        //         }
        //     }
        //
        //
        //     if text.as_str().to_lowercase().as_str().contains("sender: ") {
        //         let ttt: Vec<&str> = text.split(": ").collect();
        //         sender = ttt[1].to_string();
        //     }
        //
        //     if text.as_str().to_lowercase().as_str().contains("from: ") {
        //         let (name, mail) = self._from(text.clone());
        //         from_name = name.clone();
        //         from_mail = mail.clone();
        //     }
        //
        //     if text.as_str().to_lowercase().as_str().contains("to: ") {
        //         let (name, mail) = self._to(text.clone());
        //         to_name = name.clone();
        //         to_mail = mail.clone();
        //     }
        //
        //     if text.as_str().to_lowercase().as_str().contains("reply-to: ") {
        //         let (name, mail) = self._to(text.clone());
        //         reply_to_name = name.clone();
        //         reply_to_mail = mail.clone();
        //     }
        //
        //     if text.as_str().to_lowercase().as_str().contains("date: ") {
        //         let ttt: Vec<&str> = text.split(": ").collect();
        //         date = ttt[1].to_string();
        //     }
        //
        //     if text.as_str().to_lowercase().as_str().contains("Content-Transfer-Encoding: ") {
        //         let ttt: Vec<&str> = text.split(": ").collect();
        //         encoding = ttt[1].to_string();
        //     }
        // }

        // let info = object! {
        //     size:size.parse::<u32>().unwrap().clone(),
        //     subject:subject,
        //     from_name:from_name.clone(),
        //     from_mail:from_mail.clone(),
        //     to_name:to_name.clone(),
        //     to_mail:to_mail.clone(),
        //     reply_to_name:reply_to_name.clone(),
        //     reply_to_mail:reply_to_mail.clone(),
        //     date:date.clone(),
        //     body:df_crypto::base64::decode(body.to_string()).clone().clone(),
        //     content_type:content_type.clone(),
        //     sender:sender.clone(),
        //     encoding:encoding.clone()
        // };
        return data;
    }

    fn _qq(&mut self, data: String) -> JsonValue {
        let data: Vec<&str> = data.split("\r\n\r\n").collect();
        let heads = data[0].clone();
        let mut body = String::new();
        for index in 1..data.len() {
            body = format!("{}{}", body.clone(), data[index]);
        }
        let body: Vec<&str> = body.split("\r\n").collect();
        let body = body[0].to_string();

        let mut list: Vec<&str> = heads.split("\r\n").collect();


        let size = list[0].to_string()[4..list[0].to_string().len()].to_string();
        let mut subject = String::new();
        let mut from_name = String::new();
        let mut from_mail = String::new();
        let mut sender = String::new();
        let mut encoding = String::new();

        let mut to_name = String::new();
        let mut to_mail = String::new();
        let mut reply_to_name = String::new();
        let mut reply_to_mail = String::new();
        let mut date = String::new();
        let mut content_type = String::new();

        for item in list.iter_mut() {
            let text = item.to_string();

            if text.contains("Content-Type:") {
                let ttt: Vec<&str> = text.split(": ").collect();
                let content_types = ttt[1].to_string();
                if content_types.contains("multipart/alternative") {
                    content_type = "multipart/alternative".to_string();
                } else {
                    content_type = "base64".to_string();
                }
            }

            if text.contains("Subject: ") {
                let ttt: Vec<&str> = text.split(": ").collect();
                subject = ttt[1].to_string();
                if text.contains("b?") {
                    let ttt: Vec<&str> = subject.split("?").collect();
                    subject = ttt[3].to_string();
                    subject = df_crypto::base64::decode(subject.to_string()).clone();
                }
            }


            if text.as_str().to_lowercase().as_str().contains("sender: ") {
                let ttt: Vec<&str> = text.split(": ").collect();
                sender = ttt[1].to_string();
            }

            if text.as_str().to_lowercase().as_str().contains("from: ") {
                let (name, mail) = self._from(text.clone());
                from_name = name.clone();
                from_mail = mail.clone();
            }

            if text.as_str().to_lowercase().as_str().contains("to: ") {
                let (name, mail) = self._to(text.clone());
                to_name = name.clone();
                to_mail = mail.clone();
            }

            if text.as_str().to_lowercase().as_str().contains("reply-to: ") {
                let (name, mail) = self._to(text.clone());
                reply_to_name = name.clone();
                reply_to_mail = mail.clone();
            }

            if text.as_str().to_lowercase().as_str().contains("date: ") {
                let ttt: Vec<&str> = text.split(": ").collect();
                date = ttt[1].to_string();
            }

            if text.as_str().to_lowercase().as_str().contains("Content-Transfer-Encoding: ") {
                let ttt: Vec<&str> = text.split(": ").collect();
                encoding = ttt[1].to_string();
            }
        }

        let info = object! {
            size:size.parse::<u32>().unwrap().clone(),
            subject:subject,
            from_name:from_name.clone(),
            from_mail:from_mail.clone(),
            to_name:to_name.clone(),
            to_mail:to_mail.clone(),
            reply_to_name:reply_to_name.clone(),
            reply_to_mail:reply_to_mail.clone(),
            date:date.clone(),
            body:df_crypto::base64::decode(body.to_string()).clone().clone(),
            content_type:content_type.clone(),
            sender:sender.clone(),
            encoding:encoding.clone()
        };
        return info;
    }
    /// 来自地址
    fn _from(&mut self, data: String) -> (String, String) {
        let list: Vec<&str> = data.split(": ").collect();
        let mail = list[1].to_string();
        if mail.contains("<") {
            let list: Vec<&str> = mail.split("<").collect();
            let from_name = list[0].to_string().trim().to_string();
            let from_email = list[1].trim_end_matches(">").to_string();
            (from_name, from_email)
        } else {
            ("".to_string(), mail.to_string())
        }
    }
    /// 收件人
    fn _to(&mut self, data: String) -> (String, String) {
        let list: Vec<&str> = data.split(": ").collect();
        let mail = list[1].to_string();
        if mail.contains("<") {
            let list: Vec<&str> = mail.split("<").collect();
            let mut name = list[0].to_string().trim().to_string();
            let email = list[1].trim_end_matches(">").to_string();
            if name.contains("=?") && name.contains("?=") {
                let ttt: Vec<&str> = name.split("?").collect();
                name = ttt[3].to_string();
                name = df_crypto::base64::decode(name).clone();
            }
            (name, email)
        } else {
            ("".to_string(), mail.to_string())
        }
    }
}