use flutter_rust_bridge::frb;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MailServerConfig {
    pub imap_host: String,
    pub imap_port: u16,
    pub smtp_host: String,
    pub smtp_port: u16,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageHeader {
    pub uid: u32,
    pub subject: String,
    pub from: String,
    pub to: Vec<String>,
    pub date: i64,
    pub is_read: bool,
    pub has_attachments: bool,
    pub pgp_status: PgpStatus,
    pub flag: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum PgpStatus {
    None,
    /// Message was encrypted by the sender (requires recipient private key to read).
    Encrypted,
    Signed,
    SignedAndEncrypted,
    InvalidSignature,
    /// Message stored at rest encrypted with the user's own public key.
    EncryptedAtRest,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageBody {
    pub uid: u32,
    pub from: Option<String>,
    pub text_plain: Option<String>,
    pub text_html: Option<String>,
    pub attachments: Vec<Attachment>,
    pub pgp_status: PgpStatus,
    pub signature_fingerprint: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Attachment {
    pub name: String,
    pub content_type: String,
    pub size: usize,
    pub content: Vec<u8>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Contact {
    pub email: String,
    pub display_name: Option<String>,
    pub public_key: Option<String>,
    pub fingerprint: Option<String>,
    pub trust_level: TrustLevel,
    pub first_seen: i64,
    pub last_seen: i64,
}

#[frb]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum TrustLevel {
    Unknown,
    Trusted,
    Established,
    Warning,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Draft {
    pub id: Option<i64>,
    pub to: String,
    pub subject: String,
    pub body: String,
    pub attachments: Vec<Attachment>,
    pub last_updated: i64,
    pub last_synced_at: i64,
    pub server_uid: Option<u32>,
}

#[derive(Debug, Clone)]
pub struct PgpKeyPair {
    pub public_key: String,
    pub private_key: String,
    pub key_info: String,
    pub fingerprint: String,
    pub user_ids: Vec<String>,
}

#[frb]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum MailError {
    Generic(String),
    Network(String),
    Auth(String),
    PassphraseRequired,
    InvalidPassphrase,
    KeyNotFound(String),
    Crypto(String),
}

impl std::fmt::Display for MailError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            MailError::Generic(s) => write!(f, "{}", s),
            MailError::Network(s) => write!(f, "Network error: {}", s),
            MailError::Auth(s) => write!(f, "Auth error: {}", s),
            MailError::PassphraseRequired => write!(f, "Passphrase required"),
            MailError::InvalidPassphrase => write!(f, "Invalid passphrase"),
            MailError::KeyNotFound(s) => write!(f, "Key not found: {}", s),
            MailError::Crypto(s) => write!(f, "Crypto error: {}", s),
        }
    }
}

impl std::error::Error for MailError {}

#[frb]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum FolderType {
    Inbox,
    Sent,
    Drafts,
    Trash,
    Junk,
    Archive,
    Custom,
}

#[frb]
#[derive(Debug, Clone)]
pub struct FolderStats {
    pub unread: i32,
    pub server_total: i32,
}

#[frb]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FolderInfo {
    pub name: String,
    /// Raw server-side folder name in IMAP Modified UTF-7 encoding.
    /// Use this when issuing IMAP SELECT/EXAMINE/APPEND commands.
    pub imap_name: String,
    pub folder_type: FolderType,
    pub is_selectable: bool,
    pub unread_count: i32,
}
