import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

import settings_store as settings


def is_configured() -> bool:
    return bool((settings.get("SMTP_HOST") or "").strip())


def send_email(to: str, subject: str, body: str, html: str = None) -> bool:
    """Sends a plain-text (and optionally HTML) email using the admin-configured
    SMTP settings. Returns False (never raises) on any failure — email delivery
    should never crash the calling feature (registration, migration, etc.)."""
    host = (settings.get("SMTP_HOST") or "").strip()
    if not host or not to:
        return False
    try:
        port = int(settings.get("SMTP_PORT", "587") or 587)
    except ValueError:
        port = 587
    user = (settings.get("SMTP_USER") or "").strip()
    pwd = settings.get("SMTP_PASSWORD") or ""
    from_addr = settings.get("SMTP_FROM") or user or "no-reply@mailshift.com"
    from_name = settings.get("SMTP_FROM_NAME") or "MailShift"
    sender = f"{from_name} <{from_addr}>"

    try:
        if html:
            msg = MIMEMultipart("alternative")
            msg.attach(MIMEText(body, "plain", "utf-8"))
            msg.attach(MIMEText(html, "html", "utf-8"))
        else:
            msg = MIMEText(body, "plain", "utf-8")
        msg["Subject"] = subject
        msg["From"] = sender
        msg["To"] = to
        with smtplib.SMTP(host, port, timeout=15) as s:
            try:
                s.starttls()
            except Exception:
                pass
            if user:
                s.login(user, pwd)
            s.sendmail(from_addr, [to], msg.as_string())
        return True
    except Exception:
        return False


def render_template(text: str, ctx: dict) -> str:
    """Very small {{variable}} substitution — no external templating dependency."""
    if not text:
        return text
    for key, val in ctx.items():
        text = text.replace("{{" + key + "}}", str(val if val is not None else ""))
    return text


def send_templated(db, template_key: str, to: str, ctx: dict) -> bool:
    """Loads an EmailTemplate by key, renders subject/body/html with ctx, and sends it.
    Falls back silently (returns False) if SMTP isn't configured or the template
    is missing/disabled — callers should not treat this as a hard error."""
    from models import EmailTemplate
    if not is_configured() or not to:
        return False
    tmpl = db.query(EmailTemplate).filter(EmailTemplate.key == template_key).first()
    if not tmpl or not tmpl.is_active:
        return False
    subject = render_template(tmpl.subject, ctx)
    body = render_template(tmpl.body_text, ctx)
    html = render_template(tmpl.body_html, ctx) if tmpl.body_html else None
    return send_email(to, subject, body, html)
