# doja_sdk/email_client.py
import smtplib
import ssl
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

from .base import DojaBase
from .exceptions import DojaAPIError


class DojaEmailClient(DojaBase):
    """
    DoJa Email Client - Send emails protected by DoJa License validation.
    Supports text/HTML emails with optional file attachments.

    Usage:
        from doja_sdk import DojaEmailClient

        email = DojaEmailClient(
            doja_token="your-license-token",
            smtp_host="smtp.gmail.com",
            smtp_port=587,
            smtp_user="no-reply@tuempresa.com",
            smtp_password="app_password"
        )

        email.send(
            to="cliente@empresa.com",
            subject="Bienvenido",
            body="Gracias por registrarte."
        )
    """

    def __init__(
        self,
        doja_token: str,
        smtp_host: str,
        smtp_port: int = 587,
        smtp_user: str = "",
        smtp_password: str = "",
        default_from: str = None,
        use_tls: bool = True,
    ):
        """
        Initialize the DoJa Email Client.

        Args:
            doja_token:     Your DoJa license key.
            smtp_host:      SMTP server hostname (e.g. smtp.gmail.com).
            smtp_port:      SMTP server port (default: 587 for TLS).
            smtp_user:      SMTP authentication username.
            smtp_password:  SMTP authentication password.
            default_from:   Default sender address. Falls back to smtp_user if not set.
            use_tls:        Whether to use STARTTLS (default: True).
        """
        # First validate the license via DojaBase
        super().__init__(doja_token)

        self.smtp_host = smtp_host
        self.smtp_port = smtp_port
        self.smtp_user = smtp_user
        self.smtp_password = smtp_password
        self.default_from = default_from or smtp_user
        self.use_tls = use_tls

    def send(
        self,
        to: str,
        subject: str,
        body: str,
        html: bool = False,
        from_address: str = None,
        cc: str = None,
        bcc: str = None,
        attachments: list = None,
        reply_to: str = None,
    ) -> dict:
        """
        Send an email message.

        Args:
            to:           Recipient email address (or comma-separated list).
            subject:      Email subject line.
            body:         Email body content (plain text or HTML).
            html:         If True, body is treated as HTML. Default: False.
            from_address: Override the default sender address.
            cc:           CC recipients (comma-separated string).
            bcc:          BCC recipients (comma-separated string).
            attachments:  List of file paths to attach.
            reply_to:     Reply-To address.

        Returns:
            dict with status info.

        Raises:
            DojaQuotaExceeded: If the license has no remaining messages.
            DojaAPIError: If the SMTP server rejects the email.
        """
        # Re-validate quota before sending
        self._validate_license()

        sender = from_address or self.default_from
        msg = MIMEMultipart("mixed")
        msg["From"] = sender
        msg["To"] = to
        msg["Subject"] = subject

        if cc:
            msg["Cc"] = cc
        if reply_to:
            msg["Reply-To"] = reply_to

        # Body
        content_type = "html" if html else "plain"
        msg.attach(MIMEText(body, content_type, "utf-8"))

        # Attachments
        if attachments:
            for filepath in attachments:
                if not os.path.isfile(filepath):
                    raise DojaAPIError(f"Attachment not found: {filepath}")

                filename = os.path.basename(filepath)
                with open(filepath, "rb") as f:
                    part = MIMEBase("application", "octet-stream")
                    part.set_payload(f.read())
                encoders.encode_base64(part)
                part.add_header("Content-Disposition", f"attachment; filename={filename}")
                msg.attach(part)

        # Build recipient list for SMTP envelope
        all_recipients = [addr.strip() for addr in to.split(",")]
        if cc:
            all_recipients += [addr.strip() for addr in cc.split(",")]
        if bcc:
            all_recipients += [addr.strip() for addr in bcc.split(",")]

        # Send via SMTP
        try:
            if self.use_tls:
                context = ssl.create_default_context()
                server = smtplib.SMTP(self.smtp_host, self.smtp_port)
                server.starttls(context=context)
            else:
                server = smtplib.SMTP_SSL(self.smtp_host, self.smtp_port)

            if self.smtp_user and self.smtp_password:
                server.login(self.smtp_user, self.smtp_password)

            server.sendmail(sender, all_recipients, msg.as_string())
            server.quit()

        except smtplib.SMTPException as e:
            raise DojaAPIError(f"SMTP Error: {str(e)}")
        except Exception as e:
            raise DojaAPIError(f"Email send failed: {str(e)}")

        # Consume 1 credit after successful send
        self._consume_license()

        return {
            "status": "sent",
            "to": to,
            "subject": subject,
            "from": sender
        }
