"""
Async SMTP Email Service with retry logic and proper error handling
"""
import aiosmtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
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 = "Codul tău de autentificare ROA2WEB"
        html_body = self._create_email_template(code, username)

        for attempt in range(1, self.max_retries + 1):
            try:
                await self._send_email(to_email, subject, html_body)
                logger.info(
                    f"Email sent successfully to {to_email} "
                    f"(attempt {attempt}/{self.max_retries})"
                )
                return True

            except aiosmtplib.SMTPException as e:
                logger.warning(
                    f"SMTP error on attempt {attempt}/{self.max_retries}: {e}"
                )
                if attempt < self.max_retries:
                    # Exponential backoff: 2s, 4s, 8s
                    delay = self.retry_delay * (2 ** (attempt - 1))
                    logger.info(f"Retrying in {delay}s...")
                    await asyncio.sleep(delay)
                else:
                    logger.error(f"Failed to send email to {to_email} after {self.max_retries} attempts")

            except Exception as e:
                logger.error(f"Unexpected error sending email: {e}", exc_info=True)
                return False

        return False

    async def _send_email(
        self,
        to_email: str,
        subject: str,
        html_body: str
    ) -> None:
        """
        Internal async SMTP sender

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

        # Attach HTML body
        html_part = MIMEText(html_body, "html", "utf-8")
        message.attach(html_part)

        # Send via async SMTP with STARTTLS
        # Using start_tls parameter for automatic STARTTLS handling
        smtp = aiosmtplib.SMTP(
            hostname=self.smtp_host,
            port=self.smtp_port,
            start_tls=self.use_tls,  # Use start_tls instead of 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 HTML email template"""
        return f"""
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
            line-height: 1.6;
            color: #333;
            margin: 0;
            padding: 0;
            background-color: #f5f5f5;
        }}
        .container {{
            max-width: 600px;
            margin: 0 auto;
            background: white;
        }}
        .header {{
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 40px 20px;
            text-align: center;
        }}
        .header h1 {{
            margin: 0;
            font-size: 28px;
        }}
        .content {{
            padding: 40px 20px;
        }}
        .code-box {{
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            border: 3px solid #667eea;
            border-radius: 12px;
            padding: 30px;
            margin: 30px 0;
            text-align: center;
        }}
        .code {{
            font-size: 42px;
            font-weight: bold;
            letter-spacing: 12px;
            color: #667eea;
            font-family: 'Courier New', monospace;
            display: block;
            margin: 15px 0;
        }}
        .warning {{
            background-color: #fff3cd;
            border-left: 4px solid #ffc107;
            padding: 15px;
            margin: 20px 0;
            border-radius: 4px;
        }}
        .footer {{
            text-align: center;
            color: #666;
            font-size: 12px;
            padding: 20px;
            border-top: 1px solid #e0e0e0;
            background-color: #f9f9f9;
        }}
        .button {{
            display: inline-block;
            padding: 12px 24px;
            background-color: #667eea;
            color: white;
            text-decoration: none;
            border-radius: 6px;
            margin-top: 20px;
        }}
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>ROA2WEB</h1>
            <p style="margin: 10px 0 0 0; opacity: 0.9;">Autentificare Telegram Bot</p>
        </div>

        <div class="content">
            <p>Salut <strong>{username}</strong>,</p>

            <p>Ai solicitat autentificarea în aplicația ROA2WEB Telegram Bot.</p>

            <div class="code-box">
                <p style="margin: 0; font-size: 14px; color: #666; font-weight: 500;">
                    Codul tău de autentificare:
                </p>
                <span class="code">{code}</span>
                <p style="margin: 0; font-size: 12px; color: #888;">
                    Introdu acest cod în conversația Telegram
                </p>
            </div>

            <div class="warning">
                <strong>Important:</strong> Acest cod expiră în <strong>5 minute</strong>
                și poate fi folosit o singură dată.
            </div>

            <p>După introducerea codului, vei fi solicitat să introduci parola ta Oracle.</p>

            <hr style="border: none; border-top: 1px solid #e0e0e0; margin: 30px 0;">

            <p style="font-size: 14px; color: #666;">
                <strong>Nu ai solicitat acest cod?</strong><br>
                Dacă nu ai inițiat această autentificare, poți ignora acest email în siguranță.
                Nimeni nu va avea acces la contul tău fără parola ta Oracle.
            </p>
        </div>

        <div class="footer">
            <p><strong>ROA2WEB</strong> - ERP Reports Application</p>
            <p>Acest email a fost trimis automat. Te rugăm să nu răspunzi.</p>
            <p style="margin-top: 10px; color: #999;">
                © 2025 ROA2WEB. All rights reserved.
            </p>
        </div>
    </div>
</body>
</html>
        """


# 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
