use std::net::TcpStream;
use crate::{Connection};

#[derive(Clone)]
pub struct Imap {
    host: String,
    port: String,

    // name: String,
    mail: String,
    pass: String,

    // total_mail: i32,
    // total_size: i64,
}

impl Imap {
    pub fn new(config: Connection) -> Self {
        Self {
            host: config.host,
            port: config.port,
            // name: config.name,
            mail: config.mail,
            pass: config.pass,
            // total_mail: 0,
            // total_size: 0,
        }
    }
    pub fn connect(&mut self) -> String {
        let client = imap::ClientBuilder::new(self.host.clone(), self.port.parse::<u16>().unwrap()).native_tls().unwrap();
        let imap_session = client
            .login(self.mail.clone(), self.pass.clone())
            .map_err(|e| e.0);
        let mut imap_session = match imap_session {
            Ok(e) => e,
            Err(e) => {
                println!("{:#?}", e);
                return "aaa".to_string();
            }
        };


        imap_session.select("INBOX").unwrap();

        let messages = imap_session.fetch("6", "RFC822").unwrap();
        let message = if let Some(m) = messages.iter().next() {
            m
        } else {
           return "bbb".to_string();
        };

        let body = message.body().expect("message did not have a body!");



        // 尝试将字节数组直接转换为 UTF-8 格式的 Rust 字符串
        let data = match std::str::from_utf8(body) {
            Ok(str) => str.to_owned(),
            Err(_) => {
                // 如果转换失败，则说明字节数组可能采用其它编码格式，使用 gbk_to_utf8 方法转换为 UTF-8 格式的 Rust 字符串
                let gbk_str = br_crypto::encoding::gbk_to_utf8(body.to_vec());
                gbk_str
            }
        };
        println!(">>>>>>{}", data);

        // be nice to the server and log out
        imap_session.logout().unwrap();


        return data;
    }
    pub fn connect_p(&mut self) {
        let stream = TcpStream::connect(format!("{}:{}", self.host.clone(), self.port.clone())).unwrap();
        let mut client = imap::Client::new(stream);
        client.read_greeting().unwrap();
        eprintln!("\nUNENCRYPTED connection made!!!!\n");
        eprintln!("This is highly not recommended.\n");
        // to do anything useful with the e-mails, we need to log in
        // keep in mind that this is over plain TCP, so may leak all your secrets!
        let mut imap_session = client
            .login(self.mail.clone(), self.pass.clone()).unwrap();

        // we want to fetch the first email in the INBOX mailbox
        imap_session.select("INBOX").unwrap();

        // fetch message number 1 in this mailbox, along with its RFC822 field.
        // RFC 822 dictates the format of the body of e-mails
        let messages = imap_session.fetch("4", "RFC822").unwrap();
        let message = if let Some(m) = messages.iter().next() {
            m
        } else {
            println!("1111");
            return;
        };

        let body = message.body().expect("message did not have a body!");
        let data = String::from_utf8_lossy(body).to_string();
        println!(">>>>>>{}", data);

        imap_session.logout().unwrap();
        return;
    }

    pub fn connect_t(&mut self) {
        let client = imap::ClientBuilder::new(self.host.clone(), self.port.parse::<u16>().unwrap()).rustls().unwrap();
        let mut imap_session = client.login(self.mail.clone(), self.pass.clone()).map_err(|e| e.0).unwrap();

        // we want to fetch the first email in the INBOX mailbox
        imap_session.select("INBOX").unwrap();

        // fetch message number 1 in this mailbox, along with its RFC822 field.
        // RFC 822 dictates the format of the body of e-mails
        let messages = imap_session.fetch("1", "RFC822").unwrap();
        let message = if let Some(m) = messages.iter().next() {
            m
        } else {
            return;
        };

        let body = message.body().expect("message did not have a body!");
        let data = String::from_utf8_lossy(body).to_string();
        println!("{}", data);

        imap_session.logout().unwrap();
    }

    pub fn connect_listen(&mut self) {
        let client = imap::ClientBuilder::new(self.host.clone(), self.port.parse::<u16>().unwrap()).rustls().unwrap();
        let mut imap = client.login(self.mail.clone(), self.pass.clone()).map_err(|e| e.0).unwrap();
        imap.debug = true;
        // we want to fetch the first email in the INBOX mailbox
        imap.select("INBOX").unwrap();

        let mut num_responses = 0;
        let max_responses = 6000;
        let idle_result = imap.idle().wait_while(|response| {
            num_responses += 1;
            println!("IDLE response #{}: {:?}", num_responses, response);
            if num_responses >= max_responses {
                // Stop IDLE
                false
            } else {
                // Continue IDLE
                true
            }
        });

        match idle_result {
            Ok(reason) => println!("IDLE finished normally {:?}", reason),
            Err(e) => println!("IDLE finished with error {:?}", e),
        }

        imap.logout().unwrap();
    }
    pub fn connect_totls(&mut self) {
        let client = imap::ClientBuilder::new(self.host.clone(), self.port.parse::<u16>().unwrap()).rustls();
        let client = match client {
            Ok(e) => e,
            Err(e) => {
                println!("{}", e);
                return;
            }
        };
        let mut imap = client.login(self.mail.clone(), self.pass.clone()).map_err(|e| e.0).unwrap();
        imap.debug = true;
        let t = imap.select("INBOX").unwrap();

        println!("总邮件数量:{} 消息未被阅读:{}", t.exists, t.unseen.unwrap_or(0));

        imap.logout().unwrap();
    }
}
