"""Business email templates and email-provider dispatch."""

import logging

from fastapi import HTTPException

from app.config import settings
from app.database import async_session
from app.services import system_setting_service
from app.services.provider_loader import create_email_provider
from mode.email.base import EmailMessage, EmailProviderError


log = logging.getLogger("qycw.email")


def _frontend_url(frontend_url: str | None = None) -> str:
    return (frontend_url or settings.FRONTEND_URL).rstrip("/")


async def _send(
    to: str,
    subject: str,
    body: str,
    *,
    config_overrides: dict[str, object] | None = None,
) -> None:
    try:
        async with async_session() as session:
            config = await system_setting_service.get_email_provider_config(session, config_overrides)
        if not config.email_enabled:
            raise EmailProviderError("email service is disabled")
        provider = create_email_provider(config)
        await provider.send(EmailMessage(to=to, subject=subject, body=body))
    except EmailProviderError as exc:
        if "disabled" in exc.message:
            raise HTTPException(status_code=400, detail="邮件服务未启用") from exc
        if "missing config" in exc.message or "not configured" in exc.message:
            raise HTTPException(status_code=500, detail="邮件服务未配置完整") from exc
        raise HTTPException(status_code=500, detail="邮件发送失败，请稍后重试") from exc


async def send_test_email(to: str, *, config_overrides: dict[str, object] | None = None) -> None:
    await _send(
        to,
        "【清云互联】邮件配置测试",
        (
            "您好：\n\n"
            "这是一封后台邮件配置测试邮件。收到此邮件说明当前邮件通道可用。\n\n"
            "—— 清云互联团队"
        ),
        config_overrides=config_overrides,
    )


async def send_verification_code(to: str, code: str, purpose: str = "register") -> None:
    if purpose == "login":
        subject = "【清云互联】登录验证码"
        action_text = "您正在登录清云互联账户"
    elif purpose == "bind":
        subject = "【清云互联】邮箱绑定验证码"
        action_text = "您正在将该邮箱绑定到清云互联账户"
    else:
        subject = "【清云互联】注册验证码"
        action_text = "您正在注册清云互联账户"

    body = (
        "您好：\n\n"
        f"{action_text}。本次验证码为：{code}\n"
        "验证码 10 分钟内有效，请勿向他人泄露。\n\n"
        "如非本人操作，请忽略此邮件。\n\n"
        "—— 清云互联团队"
    )
    try:
        await _send(to, subject, body)
    except Exception as exc:  # noqa: BLE001
        log.error("send verification code to %s failed: %s", to, exc)
        raise


async def send_order_placed(
    to: str,
    username: str,
    out_order_no: str,
    items: list[dict],
    total_amount_cents: int,
    frontend_url: str | None = None,
) -> None:
    base_url = _frontend_url(frontend_url)
    subject = "【清云互联】订单已提交，正在为您开通服务"
    lines = [f"{username}，您好：\n", "您的订单已成功提交，我们正在为您开通以下服务：\n"]
    for item in items:
        lines.append(
            f"  - {item.get('product_name', '未知产品')}"
            f" x{item.get('quantity', 1)}"
            f" {item.get('cycle', '')}"
            f" ￥{item.get('unit_price_yuan', '0')}/周期"
        )
    lines.append(f"\n订单号：{out_order_no}")
    lines.append(f"实付金额：￥{total_amount_cents / 100:.2f}")
    lines.append("\n开通完成后我们将再次通知您，请留意邮件。")
    lines.append(f"\n登录控制台查看实例：{base_url}/console/instances")
    lines.append("\n—— 清云互联团队")
    try:
        await _send(to, subject, "\n".join(lines))
    except Exception as exc:  # noqa: BLE001
        log.error("send_order_placed to %s failed: %s", to, exc)


async def send_instance_active(
    to: str,
    username: str,
    product_name: str,
    main_ip: str,
    ssh_port: int | None,
    hostname: str | None,
    expires_at: str | None,
    frontend_url: str | None = None,
) -> None:
    base_url = _frontend_url(frontend_url)
    subject = "【清云互联】您的云服务器已成功开通"
    body = (
        f"{username}，您好：\n\n"
        f"您购买的“{product_name}”已成功开通，以下是连接信息：\n\n"
        f"  主 IP：{main_ip}\n"
        + (f"  SSH 端口：{ssh_port}\n" if ssh_port else "")
        + (f"  主机名：{hostname}\n" if hostname else "")
        + (f"  到期时间：{expires_at}\n" if expires_at else "")
        + "\n登录密码请在控制台“实例详情”中查看。\n"
        f"控制台地址：{base_url}/console/instances\n\n"
        "—— 清云互联团队"
    )
    try:
        await _send(to, subject, body)
    except Exception as exc:  # noqa: BLE001
        log.error("send_instance_active to %s failed: %s", to, exc)


async def send_instance_failed(
    to: str,
    username: str,
    product_name: str,
    out_order_no: str,
    reason: str,
    frontend_url: str | None = None,
) -> None:
    base_url = _frontend_url(frontend_url)
    subject = "【清云互联】服务开通失败，费用已退回"
    body = (
        f"{username}，您好：\n\n"
        f"非常抱歉，您购买的“{product_name}”开通失败。\n\n"
        f"  订单号：{out_order_no}\n"
        f"  失败原因：{reason}\n\n"
        "费用已原路退回至您的账户余额，请登录控制台确认。\n"
        "如有疑问请联系客服。\n\n"
        f"控制台地址：{base_url}/console\n\n"
        "—— 清云互联团队"
    )
    try:
        await _send(to, subject, body)
    except Exception as exc:  # noqa: BLE001
        log.error("send_instance_failed to %s failed: %s", to, exc)


async def send_welcome(
    to: str,
    username: str,
    password_set: bool = True,
    frontend_url: str | None = None,
) -> None:
    base_url = _frontend_url(frontend_url)
    subject = "【清云互联】注册成功，欢迎加入"
    if password_set:
        body = (
            f"{username}，您好：\n\n"
            "您已成功注册清云互联账户。\n"
            f"  用户名：{username}\n"
            f"  邮箱：{to}\n\n"
            "您可以使用注册时设置的密码登录。\n"
            f"登录入口：{base_url}/login\n\n"
            "—— 清云互联团队"
        )
    else:
        body = (
            f"{username}，您好：\n\n"
            "您已成功注册清云互联账户。\n"
            f"  用户名：{username}\n"
            f"  邮箱：{to}\n\n"
            "您注册时未设置密码，目前仅可使用邮箱验证码方式登录。\n"
            "如需启用密码登录，请登录后在“账户设置”中设置一个新密码。\n"
            f"登录入口：{base_url}/login\n\n"
            "—— 清云互联团队"
        )
    try:
        await _send(to, subject, body)
    except Exception as exc:  # noqa: BLE001
        log.error("send welcome to %s failed: %s", to, exc)
