use json::{JsonValue, object};

#[derive(Clone, Debug)]
pub struct Qq {
    data: Vec<String>,
    body: String,
    received: String,
    by: String,
    message_id: String,
    date: String,

    from_name: String,
    from_mail: String,

    subject: String,

    to_name: String,
    to_mail: String,

    reply_to_name: String,
    reply_to_mail: String,

    version: String,
    mailinfo: String,
    boundary: String,
}

impl Qq {
    pub fn new(data: Vec<String>) -> Self {
        let body = data.join("");
        let mut list: Vec<&str> = body.split("\r\n\r\n").collect();
        let data: Vec<&str> = list[0].split("\r\n").collect();
        list.remove(0);
        let list = list.join("\r\n");
        Self {
            data: data.iter().map(|x| x.to_string()).collect(),
            body: list,
            received: "".to_string(),
            by: "".to_string(),
            message_id: "".to_string(),
            date: "".to_string(),
            from_name: "".to_string(),
            subject: "".to_string(),
            to_name: "".to_string(),
            to_mail: "".to_string(),
            reply_to_name: "".to_string(),
            version: "".to_string(),
            mailinfo: "".to_string(),
            from_mail: "".to_string(),
            reply_to_mail: "".to_string(),
            boundary: "".to_string(),
        }
    }
    pub fn to_json(&mut self) -> JsonValue {
        self.get_received();
        self.get_message_id();
        self.get_by();
        self.get_from();
        self.get_subject();
        self.get_reply_to();
        self.get_to();
        self.get_version();
        self.get_boundary();

        self.get_x_qq_mid();
        self.get_date();
        self.get_mailinfo();
        self.get_body();
        object! {
            subject:self.subject.clone(),
            date:self.date.clone(),
            from_name:self.from_name.clone(),
            from_mail:self.from_mail.clone(),
            to_name:self.to_name.clone(),
            to_mail:self.to_mail.clone(),
            reply_to_name:self.reply_to_name.clone(),
            reply_to_mail:self.reply_to_mail.clone(),
        }
    }

    /// 获取 发送人信息
    fn get_received(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("Received: ") {
                let received = item.trim_start_matches("Received: from ");
                self.received = received.to_string();
                item.clear();
            }
        }
    }
    fn get_boundary(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("boundary=") {
                let data: Vec<&str> = item.split("\"").collect();
                self.boundary = data[1].to_string();
                item.clear();
                return;
            }
        }
    }

    fn get_from(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("From: ") {
                let data = item.trim_start_matches("From: ");
                if data.contains("=?") && data.contains("?=") {
                    let data: Vec<&str> = data.split("?").collect();
                    let code = data[1].clone();
                    let mode = data[2].clone();
                    println!("{} {}",code,mode);
                    self.from_name = br_crypto::base64::decode_code(data[3].to_string(), code);
                    self.from_mail = data[data.len() - 1].trim_start_matches("=").trim_start_matches(" ").trim_start_matches("<").trim_end_matches(">").to_string();
                } else if data.contains(" ") && data.contains("<") && data.contains(">") {
                    let data: Vec<&str> = data.split(" ").collect();
                    self.from_name = data[0].trim_start_matches("\"").trim_end_matches("\"").to_string();
                    self.from_mail = data[1].trim_start_matches("<").trim_end_matches(">").to_string();
                } else if data.contains("<") && data.contains(">") {
                    self.from_name = data.trim_start_matches("<").trim_end_matches(">").to_string();
                    self.from_mail = data.trim_start_matches("<").trim_end_matches(">").to_string();
                } else {
                    self.from_name = data.to_string();
                    self.from_mail = data.to_string();
                }
                item.clear();
                return;
            }
        }
    }
    fn get_to(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("To: ") {
                let data = item.trim_start_matches("To: ");
                let data = data.trim_end_matches(",");
                if data.contains("=?") && data.contains("?=") {
                    let i: Vec<&str> = data.split("?").collect();
                    self.to_name = br_crypto::base64::decode(i[3].to_string());
                    self.to_mail = i[i.len() - 1].trim_end_matches(">").trim_start_matches("= <").to_string();
                } else if data.contains(" ") && data.contains("<") && data.contains(">") {
                    let data: Vec<&str> = data.split(" ").collect();
                    self.to_name = data[0].trim_start_matches("\"").trim_end_matches("\"").to_string();
                    self.to_mail = data[1].trim_start_matches("<").trim_end_matches(">").to_string();
                } else if data.contains("<") && data.contains(">") {
                    self.to_name = data.trim_start_matches("<").trim_end_matches(">").to_string();
                    self.to_mail = data.trim_start_matches("<").trim_end_matches(">").to_string();
                } else {
                    self.to_name = data.to_string();
                    self.to_mail = data.to_string();
                }
                item.clear();
                return;
            }
        }
    }
    fn get_subject(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("Subject: ") {
                let data = item.trim_start_matches("Subject: ");
                if data.contains("=?") && data.contains("?=") {
                    let data: Vec<&str> = data.split("?").collect();
                    let code = data[1].clone();
                    self.subject = br_crypto::base64::decode_code(data[3].to_string(), code);
                } else {
                    self.subject = data.to_string();
                }
                item.clear();
                return;
            }
        }
    }
    fn get_reply_to(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("Reply-To: ") {
                let data = item.trim_start_matches("Reply-To: ");
                if data.contains("=?") && data.contains("?=") {
                    let data = data.trim_end_matches(">");
                    let data: Vec<&str> = data.split("?= <").collect();
                    self.reply_to_name = br_crypto::base64::decode(data[0].trim_start_matches("=?utf-8?b?").to_string());
                    self.reply_to_mail = data[1].to_string();
                } else if data.contains("<") && data.contains(">") {
                    let data: Vec<&str> = data.split(" ").collect();
                    self.reply_to_name = data[0].to_string();
                    self.reply_to_mail = data[1].trim_start_matches("<").trim_end_matches(">").to_string();
                } else {
                    self.reply_to_name = data.to_string();
                    self.reply_to_mail = data.to_string();
                }
                item.clear();
                return;
            }
        }
    }

    fn get_by(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("Content-Type: ") {
                return;
            }
            if item.contains("\tby ") {
                let data = item.trim_start_matches("\tby ");
                let data = data.trim_end_matches("\r\n");
                self.by = data.to_string();
                item.clear();
            }
        }
    }
    fn get_message_id(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("Content-Type: ") {
                return;
            }
            if item.contains("Message-ID: ") {
                let data = item.trim_start_matches("Message-ID: ");
                let data = data.trim_start_matches("<");
                let data = data.trim_end_matches(">");
                self.message_id = data.to_string();
                item.clear();
                return;
            }
        }
    }
    fn get_x_qq_mid(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("Content-Type: ") {
                return;
            }
            if item.contains("X-QQ-mid: ") {
                item.clear();
                return;
            }
        }
    }
    fn get_version(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("Content-Type: ") {
                return;
            }
            if item.contains("MIME-Version: ") || item.contains("Mime-Version: ") {
                let data = item.trim_start_matches("Mime-Version: ");
                let data = data.trim_start_matches("MIME-Version: ");
                self.version = data.to_string();
                item.clear();
                return;
            }
        }
    }
    fn get_date(&mut self) {
        for item in self.data.iter_mut() {
            if item.contains("Content-Type: ") {
                return;
            }
            if item.contains("Date: ") {
                item.clear();
                continue;
            }
            if item.contains(" (PDT)") {
                item.clear();
                continue;
            }
            if item.contains("\tfor ") {
                let data: Vec<&str> = item.split("; ").collect();
                self.date = data[1].to_string();
                item.clear();
                continue;
            }
        }
    }
    fn get_mailinfo(&mut self) {
        let mut open = false;
        for item in self.data.iter_mut() {
            if item.contains("X-QQ-XMAILINFO: ") && !open {
                let data = item.trim_start_matches("X-QQ-XMAILINFO: ");
                self.mailinfo = data.to_string();
                item.clear();
                open = true;
                continue;
            }
            if open && item.len() > 0 {
                let data = item.trim_start_matches("\t ");
                self.mailinfo = format!("{}{}", self.mailinfo, data);
                item.clear();
                continue;
            }
            if open && item.len() == 0 {
                return;
            }
        }
    }

    fn get_body(&mut self) {
        let data: Vec<&str> = self.body.trim_start_matches("\r\n").split(self.boundary.as_str()).collect();
        for item in data.iter() {
            let _list: Vec<&str> = item.split("\r\n\r\n\r\n\r\n").collect();
            // println!("{:#?}", list);
        }
    }
}