"""SMTP 邮件通知服务：每日推送 + 邀请邮件 + 系统通知"""

import asyncio
import html
import logging
import smtplib
import ssl
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

from app.config import settings
from app.services.email_templates import render_template, _render_digest_items

logger = logging.getLogger(__name__)

SMTP_HOST: str = settings.SMTP_HOST or ""
SMTP_PORT: int = settings.SMTP_PORT or 587
SMTP_USER: str = settings.SMTP_USER or ""
SMTP_PASSWORD: str = settings.SMTP_PASSWORD or ""
FROM_EMAIL: str = settings.SMTP_FROM or "noreply@scilit-oncology.com"
FROM_NAME: str = "OncoLit 肿瘤科研文献中心"


async def send_email(to_email: str, subject: str, html_body: str) -> bool:
    """发送邮件（异步包装）"""
    if not SMTP_HOST:
        logger.info("DEV mode — email to %s (%d bytes)", to_email, len(html_body))
        return True
    loop = asyncio.get_event_loop()
    return await loop.run_in_executor(None, _send_sync, to_email, subject, html_body)


def _send_sync(to_email: str, subject: str, html_body: str) -> bool:
    """同步发送邮件（自动选择 SSL/TLS）"""
    try:
        msg = MIMEMultipart("alternative")
        msg["From"] = f"{FROM_NAME} <{FROM_EMAIL}>"
        msg["To"] = to_email
        msg["Subject"] = subject
        msg.attach(MIMEText(html_body, "html", "utf-8"))

        logger.info("Sending email to %s via %s:%s ...", to_email, SMTP_HOST, SMTP_PORT)

        if SMTP_PORT == 465:
            ctx = ssl.create_default_context()
            with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT, timeout=10, context=ctx) as server:
                server.login(SMTP_USER, SMTP_PASSWORD)
                server.sendmail(FROM_EMAIL, [to_email], msg.as_string())
        else:
            with smtplib.SMTP(SMTP_HOST, SMTP_PORT, timeout=10) as server:
                server.starttls()
                server.login(SMTP_USER, SMTP_PASSWORD)
                server.sendmail(FROM_EMAIL, [to_email], msg.as_string())

        logger.info("Email sent to %s successfully", to_email)
        return True
    except smtplib.SMTPAuthenticationError:
        logger.error("SMTP authentication failed for %s — check SMTP_PASSWORD (腾讯企业邮需用授权码而非登录密码)", SMTP_USER)
        return False
    except smtplib.SMTPException as e:
        logger.error("SMTP error sending to %s: %s", to_email, e)
        return False
    except Exception as e:
        logger.error("Failed to send email to %s: %s", to_email, e)
        return False


def build_daily_digest(feed_items: list[dict], user_name: str) -> str:
    """构建每日文献推送 HTML 邮件"""
    must_read = [f for f in feed_items if f["priority"] == "must_read"]
    recommended = [f for f in feed_items if f["priority"] == "recommended"]

    must_read_html = _render_digest_items(must_read[:10], "⭐", "#d03050")
    if recommended[:5]:
        rec_html = _render_digest_items(recommended[:5], "🟡", "#d68000")
        recommended_html = f"<hr style='margin:16px 0'><p style='color:#666'>推荐文献：</p>{rec_html}"
    else:
        recommended_html = ""

    base_url = settings.PUBLIC_BASE_URL or ""
    summary_line = f"<p style='font-size:13px;color:#888;margin:0 0 12px'>今日必读 {len(must_read)} 篇 · 推荐 {len(recommended)} 篇</p>"
    return render_template(
        "digest",
        user_name=html.escape(user_name),
        summary_line=summary_line,
        must_read_items=must_read_html,
        recommended_items=recommended_html,
        base_url=base_url,
    )


def build_invite_email(inviter_name: str, team_name: str, invite_link: str) -> str:
    """构建邀请邮件"""
    base_url = settings.PUBLIC_BASE_URL or ""
    return render_template(
        "invite",
        inviter_name=html.escape(inviter_name),
        team_name=html.escape(team_name),
        invite_link=f"{base_url}{invite_link}",
        base_url=base_url,
    )


def build_password_reset_email(user_name: str, reset_link: str) -> str:
    """构建密码重置邮件"""
    base_url = settings.PUBLIC_BASE_URL or ""
    return render_template(
        "password_reset",
        user_name=user_name,
        reset_link=reset_link,
        base_url=base_url,
    )


def build_notification_email(user_name: str, content: str, cta_text: str = "", cta_link: str = "") -> str:
    """构建通用通知邮件"""
    base_url = settings.PUBLIC_BASE_URL or ""
    return render_template(
        "notification",
        user_name=user_name,
        content=content,
        cta_text=cta_text,
        cta_link=cta_link,
        base_url=base_url,
    )
