"""
Email service for sending notifications.
"""
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from typing import Optional
from datetime import datetime

from app.models.notification import NotificationSetting


class EmailService:
    """Service for sending emails via SMTP."""

    @staticmethod
    def send_email(
        settings: NotificationSetting,
        to_email: str,
        subject: str,
        html_body: str,
        plain_body: Optional[str] = None
    ) -> tuple[bool, Optional[str]]:
        """
        Send an email using SMTP configuration.

        Args:
            settings: SMTP configuration settings
            to_email: Recipient email address
            subject: Email subject
            html_body: HTML email body
            plain_body: Plain text email body (optional)

        Returns:
            Tuple of (success: bool, error_message: Optional[str])
        """
        if not settings.email_enabled:
            return False, "Email notifications are disabled"

        if not settings.smtp_host or not settings.from_email:
            return False, "SMTP configuration is incomplete"

        try:
            # Create message
            msg = MIMEMultipart('alternative')
            msg['From'] = f"{settings.from_name} <{settings.from_email}>" if settings.from_name else settings.from_email
            msg['To'] = to_email
            msg['Subject'] = subject
            msg['Date'] = datetime.now().strftime("%a, %d %b %Y %H:%M:%S %z")

            # Attach plain text version (fallback)
            if plain_body:
                msg.attach(MIMEText(plain_body, 'plain', 'utf-8'))

            # Attach HTML version
            msg.attach(MIMEText(html_body, 'html', 'utf-8'))

            # Connect to SMTP server
            if settings.smtp_use_ssl:
                smtp = smtplib.SMTP_SSL(settings.smtp_host, settings.smtp_port)
            else:
                smtp = smtplib.SMTP(settings.smtp_host, settings.smtp_port)

            # Start TLS if required
            if settings.smtp_use_tls and not settings.smtp_use_ssl:
                smtp.starttls()

            # Login if credentials provided
            if settings.smtp_username and settings.smtp_password:
                smtp.login(settings.smtp_username, settings.smtp_password)

            # Send email
            smtp.sendmail(settings.from_email, [to_email], msg.as_string())
            smtp.quit()

            return True, None

        except smtplib.SMTPAuthenticationError as e:
            return False, f"SMTP Authentication failed: {str(e)}"
        except smtplib.SMTPException as e:
            return False, f"SMTP Error: {str(e)}"
        except Exception as e:
            return False, f"Failed to send email: {str(e)}"

    @staticmethod
    def test_connection(settings: NotificationSetting) -> tuple[bool, Optional[str]]:
        """
        Test SMTP connection without sending an email.

        Args:
            settings: SMTP configuration settings

        Returns:
            Tuple of (success: bool, error_message: Optional[str])
        """
        if not settings.smtp_host:
            return False, "SMTP host is not configured"

        try:
            if settings.smtp_use_ssl:
                smtp = smtplib.SMTP_SSL(settings.smtp_host, settings.smtp_port, timeout=10)
            else:
                smtp = smtplib.SMTP(settings.smtp_host, settings.smtp_port, timeout=10)

            if settings.smtp_use_tls and not settings.smtp_use_ssl:
                smtp.starttls()

            if settings.smtp_username and settings.smtp_password:
                smtp.login(settings.smtp_username, settings.smtp_password)

            smtp.quit()
            return True, None

        except smtplib.SMTPAuthenticationError as e:
            return False, f"Authentication failed: {str(e)}"
        except smtplib.SMTPException as e:
            return False, f"SMTP Error: {str(e)}"
        except Exception as e:
            return False, f"Connection failed: {str(e)}"
