use crate::error::Result;
use async_trait::async_trait;

#[async_trait]
pub trait EmailPort: Send + Sync {
    async fn send_email(&self, to: &str, subject: &str, body: &str) -> Result<()>;

    async fn send_welcome_email(&self, to_email: &str, first_name: &str) -> Result<()>;

    async fn send_vault_release_notification(
        &self,
        to_email: &str,
        beneficiary_name: &str,
        owner_name: &str,
        vault_name: &str,
        access_id: &str,
    ) -> Result<()>;
}

#[async_trait]
impl<T: EmailPort + ?Sized + Send + Sync> EmailPort for std::sync::Arc<T> {
    async fn send_email(&self, to: &str, subject: &str, body: &str) -> Result<()> {
        self.as_ref().send_email(to, subject, body).await
    }

    async fn send_welcome_email(&self, to_email: &str, first_name: &str) -> Result<()> {
        self.as_ref().send_welcome_email(to_email, first_name).await
    }

    async fn send_vault_release_notification(
        &self,
        to_email: &str,
        beneficiary_name: &str,
        owner_name: &str,
        vault_name: &str,
        access_id: &str,
    ) -> Result<()> {
        self.as_ref()
            .send_vault_release_notification(
                to_email,
                beneficiary_name,
                owner_name,
                vault_name,
                access_id,
            )
            .await
    }
}
