"""
Email sending service for notification alerts (module 1.1.11).

Uses plain SMTP via Python's standard library rather than a third-party
email API/SDK — this keeps the dependency footprint minimal and works
with any SMTP provider the client chooses (SendGrid, AWS SES, Gmail
SMTP relay, their own mail server, etc.) by just changing the .env
settings, with no code change.

Deliberately fails safe: if EMAIL_ENABLED is false or SMTP isn't
configured, send_email() logs and returns False rather than raising —
a notification email failing to send must never break the underlying
notification (which still exists and is visible in-app) or the
analysis flow that triggered it.
"""

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

from app.core.config import get_settings
from app.core.logging_config import get_logger

settings = get_settings()
logger = get_logger(__name__)


def send_email(to_address: str, subject: str, body_text: str, body_html: str | None = None) -> bool:
    if not settings.EMAIL_ENABLED:
        logger.info(f"Email sending disabled (EMAIL_ENABLED=false) — skipped email to {to_address}")
        return False

    if not settings.SMTP_HOST or not settings.SMTP_USERNAME:
        logger.warning(
            "EMAIL_ENABLED is true but SMTP_HOST/SMTP_USERNAME are not configured — "
            f"skipped email to {to_address}"
        )
        return False

    message = MIMEMultipart("alternative")
    message["Subject"] = subject
    message["From"] = f"{settings.EMAIL_FROM_NAME} <{settings.EMAIL_FROM_ADDRESS}>"
    message["To"] = to_address

    message.attach(MIMEText(body_text, "plain"))
    if body_html:
        message.attach(MIMEText(body_html, "html"))

    try:
        with smtplib.SMTP(settings.SMTP_HOST, settings.SMTP_PORT, timeout=10) as server:
            if settings.SMTP_USE_TLS:
                server.starttls()
            server.login(settings.SMTP_USERNAME, settings.SMTP_PASSWORD)
            server.sendmail(settings.EMAIL_FROM_ADDRESS, to_address, message.as_string())
        logger.info(f"Sent email to {to_address}: {subject}")
        return True
    except Exception as exc:
        # Never let an email delivery failure propagate as an exception
        # to the caller — the in-app notification already exists and is
        # the source of truth; email is a best-effort supplementary channel.
        logger.error(f"Failed to send email to {to_address}: {exc}", exc_info=True)
        return False


def build_feasibility_change_email(
    crop: str, location: str, old_label: str | None, new_label: str
) -> tuple[str, str, str]:
    """Returns (subject, plain_text_body, html_body) for a feasibility-change alert."""
    subject = f"Update on your {crop.title()} plan: now '{new_label.replace('_', ' ')}'"

    change_phrase = (
        f"changed from '{old_label.replace('_', ' ')}' to '{new_label.replace('_', ' ')}'"
        if old_label
        else f"is now classified as '{new_label.replace('_', ' ')}'"
    )

    text_body = (
        f"Your crop plan for {crop} in {location.title()} {change_phrase}.\n\n"
        f"Log in to AgriField to see the full updated analysis, including yield "
        f"forecast, market outlook, and alternative crops.\n"
    )

    html_body = f"""
    <div style="font-family: sans-serif; color: #1A1A1A;">
      <h2 style="color: #2D5016;">Update on your {crop.title()} plan</h2>
      <p>Your crop plan for <strong>{crop}</strong> in <strong>{location.title()}</strong>
      {change_phrase}.</p>
      <p>Log in to AgriField to see the full updated analysis.</p>
    </div>
    """

    return subject, text_body, html_body
