import "server-only"

/**
 * 邮件通知渠道
 *
 * 使用 nodemailer（动态 import）通过 SMTP 发送邮件。
 * 支持 HTML 邮件模板，根据 payload.type 渲染不同颜色样式。
 *
 * 环境变量:
 * - EMAIL_HOST: SMTP 主机
 * - EMAIL_PORT: SMTP 端口（默认 587）
 * - EMAIL_USER: SMTP 用户名
 * - EMAIL_PASS: SMTP 密码
 * - EMAIL_FROM: 发件人地址（默认 noreply@example.com）
 *
 * Mock 实现: 当 EMAIL_HOST 未配置时启用，仅记录日志不实际发送。
 */

import type {
  NotificationPayload,
  ChannelSendResult,
  NotificationChannel,
} from "../types"
import type { NotificationChannelSender, ChannelRecipient } from "./types"

const channel: NotificationChannel = "email"

/** 从环境变量读取邮件配置 */
function getEmailConfig(): {
  host: string | undefined
  port: number
  user: string | undefined
  pass: string | undefined
  from: string
} {
  return {
    host: process.env.EMAIL_HOST,
    port: Number(process.env.EMAIL_PORT ?? "587"),
    user: process.env.EMAIL_USER,
    pass: process.env.EMAIL_PASS,
    from: process.env.EMAIL_FROM ?? "noreply@example.com",
  }
}

/** 是否启用邮件渠道（SMTP 主机配置即启用） */
export function isEmailEnabled(): boolean {
  return Boolean(process.env.EMAIL_HOST)
}

/** 根据通知类型返回主题色（用于 HTML 模板） */
function getTypeColor(type: NotificationPayload["type"]): string {
  switch (type) {
    case "success":
      return "#16a34a"
    case "warning":
      return "#d97706"
    case "error":
      return "#dc2626"
    case "info":
    default:
      return "#2563eb"
  }
}

/** 生成 HTML 邮件内容 */
function buildHtmlContent(payload: NotificationPayload): string {
  const color = getTypeColor(payload.type)
  const actionLink = payload.actionUrl
    ? `<p style="margin-top:16px;"><a href="${payload.actionUrl}" style="color:${color};text-decoration:none;">点击查看详情 →</a></p>`
    : ""
  return `
    <div style="font-family:Arial,sans-serif;max-width:600px;margin:0 auto;padding:20px;">
      <div style="border-left:4px solid ${color};padding-left:16px;">
        <h2 style="color:${color};margin:0 0 12px 0;">${escapeHtml(payload.title)}</h2>
        <p style="color:#374151;line-height:1.6;margin:0;">${escapeHtml(payload.content)}</p>
        ${actionLink}
      </div>
      <hr style="border:none;border-top:1px solid #e5e7eb;margin:24px 0;" />
      <p style="color:#9ca3af;font-size:12px;margin:0;">此邮件由系统自动发送，请勿回复。</p>
    </div>
  `
}

/** HTML 转义，防止 XSS */
function escapeHtml(text: string): string {
  return text
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#39;")
}

/** Mock 邮件发送器（开发环境使用） */
class MockEmailSender implements NotificationChannelSender {
  readonly channel = channel

  async send(
    payload: NotificationPayload,
    recipient: ChannelRecipient
  ): Promise<ChannelSendResult> {
    console.info(
      `[MockEmail] send to ${recipient.email ?? "(no email)"}: subject="${payload.title}"`
    )
    return {
      channel,
      success: true,
      messageId: `mock-email-${Date.now()}`,
      sentAt: new Date(),
    }
  }

  async sendBatch(
    items: Array<{ payload: NotificationPayload; recipient: ChannelRecipient }>
  ): Promise<ChannelSendResult[]> {
    return Promise.all(items.map((item) => this.send(item.payload, item.recipient)))
  }
}

/** Nodemailer SMTP 邮件发送器 */
class NodemailerEmailSender implements NotificationChannelSender {
  readonly channel = channel

  async send(
    payload: NotificationPayload,
    recipient: ChannelRecipient
  ): Promise<ChannelSendResult> {
    if (!recipient.email) {
      return { channel, success: false, error: "Missing recipient email", sentAt: new Date() }
    }

    const config = getEmailConfig()
    if (!config.host) {
      return { channel, success: false, error: "EMAIL_HOST not configured", sentAt: new Date() }
    }

    try {
      // 动态 import nodemailer，避免增加构建体积
      const nodemailer = await import("nodemailer")
      const transporter = nodemailer.createTransport({
        host: config.host,
        port: config.port,
        secure: config.port === 465,
        auth: config.user
          ? { user: config.user, pass: config.pass ?? "" }
          : undefined,
      })

      const info = await transporter.sendMail({
        from: config.from,
        to: recipient.email,
        subject: payload.title,
        html: buildHtmlContent(payload),
        text: payload.content,
      })

      return {
        channel,
        success: true,
        messageId: info.messageId,
        sentAt: new Date(),
      }
    } catch (e) {
      return {
        channel,
        success: false,
        error: e instanceof Error ? e.message : "Email send failed",
        sentAt: new Date(),
      }
    }
  }

  async sendBatch(
    items: Array<{ payload: NotificationPayload; recipient: ChannelRecipient }>
  ): Promise<ChannelSendResult[]> {
    return Promise.all(items.map((item) => this.send(item.payload, item.recipient)))
  }
}

/**
 * 创建邮件渠道发送器。
 * 配置了 EMAIL_HOST 时使用 Nodemailer，否则使用 Mock 实现。
 */
export function createEmailSender(): NotificationChannelSender {
  if (isEmailEnabled()) {
    return new NodemailerEmailSender()
  }
  return new MockEmailSender()
}
