"""Envio de correos por SMTP (para avisar al deudor/codeudor que tienen un prestamo para
firmar). Las credenciales viven SOLO en variables de entorno (.env de cada instalacion),
nunca en el codigo. Si no estan configuradas, el envio simplemente se omite: el prestamista
siempre puede seguir compartiendo el enlace de firma manualmente (copiar enlace o WhatsApp),
asi que la falta de correo configurado no bloquea nada."""
import logging
import os
import smtplib
import socket
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

logger = logging.getLogger(__name__)

SMTP_HOST = os.environ.get("SMTP_HOST")
SMTP_PORT = int(os.environ.get("SMTP_PORT") or 587)
SMTP_USER = os.environ.get("SMTP_USER")
SMTP_PASSWORD = os.environ.get("SMTP_PASSWORD")
SMTP_FROM = os.environ.get("SMTP_FROM") or SMTP_USER

_getaddrinfo_original = socket.getaddrinfo


def _resolver_solo_ipv4(host, port, family=0, type=0, proto=0, flags=0):
    """Fuerza la resolucion a IPv4. Algunos servidores (y, se confirmo en pruebas, este
    mismo entorno de desarrollo) tienen IPv6 mal configurado: la resolucion con
    AF_UNSPEC falla por completo aunque el registro A (IPv4) del host funcione bien. Esto
    NO afecta la verificacion del certificado TLS, que sigue haciendose contra el nombre
    de host original (smtplib nunca ve la IP, solo el resolver la usa por debajo)."""
    return _getaddrinfo_original(host, port, socket.AF_INET, type, proto, flags)


def smtp_configurado():
    return bool(SMTP_HOST and SMTP_USER and SMTP_PASSWORD)


def enviar_correo(destinatario, asunto, cuerpo_html):
    """Devuelve True si el correo se envio, False si no se pudo enviar o si el SMTP no
    esta configurado en este servidor. Nunca lanza una excepcion hacia quien la llama."""
    if not smtp_configurado() or not destinatario:
        return False

    mensaje = MIMEMultipart("alternative")
    mensaje["Subject"] = asunto
    mensaje["From"] = SMTP_FROM
    mensaje["To"] = destinatario
    mensaje.attach(MIMEText(cuerpo_html, "html"))

    socket.getaddrinfo = _resolver_solo_ipv4
    try:
        if SMTP_PORT == 465:
            with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT, timeout=15) as servidor:
                servidor.login(SMTP_USER, SMTP_PASSWORD)
                servidor.sendmail(SMTP_FROM, [destinatario], mensaje.as_string())
        else:
            with smtplib.SMTP(SMTP_HOST, SMTP_PORT, timeout=15) as servidor:
                servidor.starttls()
                servidor.login(SMTP_USER, SMTP_PASSWORD)
                servidor.sendmail(SMTP_FROM, [destinatario], mensaje.as_string())
        return True
    except Exception:
        logger.exception("No se pudo enviar el correo a %s via %s:%s", destinatario, SMTP_HOST, SMTP_PORT)
        return False
    finally:
        socket.getaddrinfo = _getaddrinfo_original
