import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import * as nodemailer from 'nodemailer';
import { EmailVerificationType } from '../../domain/entities/email-verification.entity';
import { IEmailProvider, EmailDeliveryResult } from './email-provider.interface';

/**
 * Gmail SMTP Provider
 *
 * 使用 Gmail SMTP + App Password 发送验证码邮件。
 *
 * 环境变量:
 *   GMAIL_USER         — Gmail 账号（如 noreply@gmail.com）
 *   GMAIL_APP_PASSWORD — Gmail 应用专用密码（Google 账号 → 安全性 → 应用专用密码）
 *   EMAIL_FROM_NAME    — 发件人显示名（默认 Genex）
 *
 * Gmail 应用专用密码获取步骤：
 *   1. 在 Google 账号开启两步验证
 *   2. 访问 myaccount.google.com → 安全性 → 两步验证 → 应用专用密码
 *   3. 选择「邮件」→ 复制 16 位密码（不含空格）
 */
@Injectable()
export class GmailProvider implements IEmailProvider, OnModuleInit {
  private readonly logger = new Logger('GmailProvider');
  private transporter: nodemailer.Transporter;

  /** 验证码类型 → 邮件主题 */
  private static readonly SUBJECT_MAP: Record<EmailVerificationType, string> = {
    [EmailVerificationType.REGISTER]: '【Genex】注册验证码',
    [EmailVerificationType.LOGIN]: '【Genex】登录验证码',
    [EmailVerificationType.RESET_PASSWORD]: '【Genex】重置密码验证码',
    [EmailVerificationType.CHANGE_EMAIL]: '【Genex】更换邮箱验证码',
  };

  /** 验证码类型 → 操作说明文案 */
  private static readonly ACTION_MAP: Record<EmailVerificationType, string> = {
    [EmailVerificationType.REGISTER]: '您正在注册 Genex 账号',
    [EmailVerificationType.LOGIN]: '您正在登录 Genex 账号',
    [EmailVerificationType.RESET_PASSWORD]: '您正在重置 Genex 账号密码',
    [EmailVerificationType.CHANGE_EMAIL]: '您正在更换 Genex 账号绑定邮箱',
  };

  async onModuleInit() {
    this.transporter = nodemailer.createTransport({
      host: 'smtp.gmail.com',
      port: 587,
      secure: false, // STARTTLS
      auth: {
        user: process.env.GMAIL_USER,
        pass: process.env.GMAIL_APP_PASSWORD,
      },
    });
    this.logger.log(`Gmail SMTP initialized: user=${process.env.GMAIL_USER}`);
  }

  async send(
    email: string,
    code: string,
    type: EmailVerificationType,
  ): Promise<EmailDeliveryResult> {
    try {
      const fromName = process.env.EMAIL_FROM_NAME || 'Genex';
      const from = `"${fromName}" <${process.env.GMAIL_USER}>`;
      const subject = GmailProvider.SUBJECT_MAP[type];
      const html = this.buildHtml(code, type);

      const info = await this.transporter.sendMail({ from, to: email, subject, html });

      this.logger.log(
        `Email sent [${type}]: to=${email.replace(/(?<=.).(?=[^@]*@)/, '*')} msgId=${info.messageId}`,
      );
      return { success: true, providerId: info.messageId };
    } catch (error: any) {
      this.logger.error(`Gmail send error: ${error.message}`);
      return { success: false, errorMsg: error.message };
    }
  }

  private buildHtml(code: string, type: EmailVerificationType): string {
    const action = GmailProvider.ACTION_MAP[type];
    return `
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /></head>
<body style="margin:0;padding:0;background:#f5f5f7;font-family:Arial,sans-serif;">
  <table width="100%" cellpadding="0" cellspacing="0">
    <tr>
      <td align="center" style="padding:40px 16px;">
        <table width="560" cellpadding="0" cellspacing="0" style="background:#fff;border-radius:16px;overflow:hidden;box-shadow:0 2px 12px rgba(0,0,0,0.08);">
          <!-- Header -->
          <tr>
            <td style="background:linear-gradient(135deg,#6C63FF,#9B8FFF);padding:32px;text-align:center;">
              <span style="font-size:28px;font-weight:800;color:#fff;letter-spacing:-0.5px;">GENEX</span>
              <p style="margin:8px 0 0;color:rgba(255,255,255,0.85);font-size:13px;">券金融平台</p>
            </td>
          </tr>
          <!-- Body -->
          <tr>
            <td style="padding:40px 40px 32px;">
              <p style="margin:0 0 8px;color:#1a1a2e;font-size:16px;">${action}，请使用以下验证码：</p>
              <!-- Code block -->
              <div style="margin:28px 0;text-align:center;">
                <span style="display:inline-block;background:#f0eeff;border-radius:12px;padding:18px 40px;font-size:42px;font-weight:800;letter-spacing:12px;color:#6C63FF;">${code}</span>
              </div>
              <p style="margin:0;color:#555;font-size:14px;line-height:1.7;">
                验证码有效期 <strong>5 分钟</strong>，请勿将验证码告知任何人。<br/>
                如非本人操作，请忽略此邮件。
              </p>
            </td>
          </tr>
          <!-- Footer -->
          <tr>
            <td style="background:#f9f9f9;padding:20px 40px;border-top:1px solid #eee;">
              <p style="margin:0;color:#999;font-size:12px;text-align:center;">
                此邮件由系统自动发送，请勿直接回复。<br/>
                © ${new Date().getFullYear()} Genex · 券金融平台
              </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>
</html>`;
  }
}
