import re
from pathlib import Path

from ..exceptions import MailError
from ..models.mail_request import MailRequest

EMAIL_REGEX = re.compile(r"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$")


def _validate_email(email: str) -> bool:
    return bool(EMAIL_REGEX.match(email))


def validate_mail_request(req: MailRequest) -> None:
    if not req.sender or not _validate_email(req.sender):
        raise MailError(f"Sender inválido: {req.sender}")

    if "\n" in req.sender or "\r" in req.sender:
        raise MailError("El sender contiene saltos de línea no permitidos.")

    if not req.to:
        raise MailError("Debe especificarse al menos un destinatario en 'to'.")

    for email in req.to:
        if not _validate_email(email):
            raise MailError(f"Destinatario inválido: {email}")

    for email in req.cc:
        if not _validate_email(email):
            raise MailError(f"Dirección CC inválida: {email}")

    for email in req.bcc:
        if not _validate_email(email):
            raise MailError(f"Dirección BCC inválida: {email}")

    if not req.subject or not req.subject.strip():
        raise MailError("El asunto no puede estar vacío.")

    if "\n" in req.subject or "\r" in req.subject:
        raise MailError("El asunto contiene saltos de línea no permitidos.")

    for att_path in req.attachments:
        p = Path(att_path)
        if not p.exists() or not p.is_file():
            raise MailError(f"Adjunto no encontrado: {att_path}")

    template_name = req.template.strip() if req.template else None
    if not req.message and not template_name:
        raise MailError("Debe proveerse un message o un template.")