//! 邮件解析：基于 mail-parser 解析 RFC 5322 邮件。

use anyhow::Result;
use mail_parser::{MessageParser, MimeHeaders};

pub struct ParsedEmail {
    pub subject: Option<String>,
    pub sender_name: Option<String>,
    #[allow(dead_code)]
    pub from_addr: Option<String>,
    pub text_body: Option<String>,
    pub html_body: Option<String>,
    pub message_id: Option<String>,
    pub attachments: Vec<ParsedAttachment>,
}

pub struct ParsedAttachment {
    pub filename: Option<String>,
    pub content_type: String,
    pub size: i64,
    pub content: Vec<u8>,
}

/// 解析原始邮件字节流。
pub fn parse(raw: &[u8]) -> Result<ParsedEmail> {
    let message = MessageParser::default()
        .parse(raw)
        .ok_or_else(|| anyhow::anyhow!("邮件解析失败"))?;

    let subject = message.subject().map(|s| s.to_string());
    let message_id = message.message_id().map(|s| s.to_string());

    let (from_addr, sender_name) = if let Some(from) = message.from() {
        if let Some(addr) = from.first() {
            (
                addr.address().map(|s| s.to_string()),
                addr.name().map(|s| s.to_string()),
            )
        } else {
            (None, None)
        }
    } else {
        (None, None)
    };

    let text_body = message.body_text(0).map(|s| s.into_owned());
    let html_body = message.body_html(0).map(|s| s.into_owned());

    let mut attachments = Vec::new();
    for part in message.attachments() {
        let filename = part.attachment_name().map(|s| s.to_string());
        let content_type = part
            .content_type()
            .map(|ct| match ct.subtype() {
                Some(sub) => format!("{}/{}", ct.ctype(), sub),
                None => ct.ctype().to_string(),
            })
            .unwrap_or_else(|| "application/octet-stream".to_string());
        let content = part.contents().to_vec();
        let size = content.len() as i64;
        attachments.push(ParsedAttachment {
            filename,
            content_type,
            size,
            content,
        });
    }

    Ok(ParsedEmail {
        subject,
        sender_name,
        from_addr,
        text_body,
        html_body,
        message_id,
        attachments,
    })
}
