use crate::Client;
use crate::error::Error;
use crate::message::MessagePreview;
use jiff::Timestamp;
use serde::Deserialize;

#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
pub(crate) struct MailboxData {
    token: String,
    #[serde(rename = "mailbox")]
    address: String,
}

/// A disposable mailbox created through [`Client`](crate::Client).
///
/// The mailbox borrows the client that created it, so it can continue to make authenticated
/// requests for messages associated with the mailbox token.
#[derive(Clone, Debug)]
pub struct Mailbox<'a> {
    client: &'a Client,

    data: MailboxData,
}

impl<'a> Mailbox<'a> {
    pub(crate) fn new(client: &'a Client, data: MailboxData) -> Self {
        Self { client, data }
    }

    /// Returns the mailbox email address.
    pub fn address(&self) -> &str {
        &self.data.address
    }

    /// Lists messages received by this mailbox.
    ///
    /// If `after` is provided, only messages received after that timestamp are requested.
    pub async fn list_messages(
        &'a self,
        after: Option<Timestamp>,
    ) -> Result<Vec<MessagePreview<'a>>, Error> {
        let data = self
            .client
            .list_mailbox_messages(&self.data.token, after)
            .await?;
        Ok(data
            .into_iter()
            .map(|data| MessagePreview::new(self.client, self, data))
            .collect())
    }

    pub(crate) fn token(&self) -> &str {
        &self.data.token
    }
}
