"""
Async SMTP Email Service with retry logic and proper error handling
"""
import aiosmtplib
from email.message import EmailMessage
import os
import logging
from typing import Optional
import asyncio

logger = logging.getLogger(__name__)


class EmailService:
    """Async SMTP client for sending authentication codes"""

    def __init__(self):
        self.smtp_host = os.getenv("SMTP_HOST", "mail.romfast.ro")
        self.smtp_port = int(os.getenv("SMTP_PORT", "587"))
        self.smtp_user = os.getenv("SMTP_USER")
        self.smtp_password = os.getenv("SMTP_PASSWORD")
        self.from_email = os.getenv("SMTP_FROM_EMAIL")
        self.from_name = os.getenv("SMTP_FROM_NAME", "ROA2WEB")
        self.use_tls = os.getenv("SMTP_USE_TLS", "true").lower() == "true"

        # Retry configuration
        self.max_retries = int(os.getenv("EMAIL_MAX_RETRIES", "3"))
        self.retry_delay = float(os.getenv("EMAIL_RETRY_DELAY", "2.0"))  # seconds

        # Validate required config
        if not all([self.smtp_user, self.smtp_password, self.from_email]):
            raise ValueError("SMTP configuration incomplete. Check .env file.")

    async def send_auth_code(
        self,
        to_email: str,
        code: str,
        username: str
    ) -> bool:
        """
        Send authentication code via email with retry logic

        Args:
            to_email: Recipient email address
            code: 6-digit authentication code
            username: Oracle username for personalization

        Returns:
            True if email sent successfully (after retries if needed)

        Raises:
            No exceptions - returns False on all failures
        """
        subject = "Autentificare ROA2WEB"
        text_body = self._create_email_template(code, username)

        for attempt in range(1, self.max_retries + 1):
            try:
                await self._send_email(to_email, subject, text_body)
                logger.info(
                    f"[EMAIL] ✅ Sent auth code to {to_email} "
                    f"(attempt {attempt}/{self.max_retries}) via {self.smtp_host}:{self.smtp_port}"
                )
                return True

            except aiosmtplib.SMTPException as e:
                logger.error(
                    f"[EMAIL] ❌ Attempt {attempt}/{self.max_retries} failed for {to_email}: "
                    f"{type(e).__name__}: {e}"
                )
                if attempt < self.max_retries:
                    # Exponential backoff: 2s, 4s, 8s
                    delay = self.retry_delay * (2 ** (attempt - 1))
                    logger.info(f"[EMAIL] Retrying in {delay}s...")
                    await asyncio.sleep(delay)
                else:
                    logger.error(f"[EMAIL] ❌ All {self.max_retries} attempts failed for {to_email}")

            except Exception as e:
                logger.error(f"[EMAIL] ❌ Unexpected error on attempt {attempt}/{self.max_retries} for {to_email}: {type(e).__name__}: {e}", exc_info=True)
                return False

        return False

    async def _send_email(
        self,
        to_email: str,
        subject: str,
        text_body: str
    ) -> None:
        """
        Internal async SMTP sender (plain text to avoid spam filters)

        Raises:
            aiosmtplib.SMTPException: On SMTP errors
        """
        message = EmailMessage()
        message["From"] = f"{self.from_name} <{self.from_email}>"
        message["To"] = to_email
        message["Subject"] = subject
        message.set_content(text_body)

        smtp = aiosmtplib.SMTP(
            hostname=self.smtp_host,
            port=self.smtp_port,
            start_tls=self.use_tls,
            timeout=30
        )

        try:
            await smtp.connect()
            await smtp.login(self.smtp_user, self.smtp_password)
            await smtp.send_message(message)
        finally:
            try:
                await smtp.quit()
            except:
                pass

    def _create_email_template(self, code: str, username: str) -> str:
        """Generate plain text email body (HTML blocked by spam filters)"""
        return (
            f"Codul tau de autentificare ROA2WEB:\n\n"
            f"  {code}\n\n"
            f"Introdu acest cod in Telegram. Expira in 5 minute.\n\n"
            f"---\n"
            f"Solicitat pentru: {username}\n"
            f"Daca nu ai initiat aceasta autentificare, ignora acest email."
        )


# Singleton instance
_email_service: Optional[EmailService] = None


def get_email_service() -> EmailService:
    """Get or create singleton email service instance"""
    global _email_service
    if _email_service is None:
        _email_service = EmailService()
    return _email_service
