//
// Copyright (C) 2024 veypi <i@veypi.com>
// 2025-03-04 16:08:06
// Distributed under terms of the MIT license.
//

package email

import (
	"crypto/tls"
	"fmt"
	"net/smtp"

	"github.com/veypi/vbase/models"
)

// SMTPProvider SMTP 邮件提供商
type SMTPProvider struct {
	host     string
	port     int
	username string
	password string
	from     string
	fromName string
}

// NewSMTPProvider 创建 SMTP 提供商
func NewSMTPProvider() (*SMTPProvider, error) {
	host, err := models.GetSetting(models.SettingEmailSMTPHost)
	if err != nil || host == "" {
		return nil, fmt.Errorf("smtp host not configured")
	}

	port, _ := models.GetSettingInt(models.SettingEmailSMTPPort)
	if port == 0 {
		port = 587
	}

	username, _ := models.GetSetting(models.SettingEmailSMTPUser)
	password, _ := models.GetSetting(models.SettingEmailSMTPPass)
	from, _ := models.GetSetting(models.SettingEmailFrom)
	fromName, _ := models.GetSetting(models.SettingEmailFromName)

	if from == "" {
		from = username
	}

	return &SMTPProvider{
		host:     host,
		port:     port,
		username: username,
		password: password,
		from:     from,
		fromName: fromName,
	}, nil
}

// Send 发送邮件
func (p *SMTPProvider) Send(to, subject, content string) error {
	from := p.from
	if p.fromName != "" {
		from = fmt.Sprintf("%s <%s>", p.fromName, p.from)
	}

	// 构造邮件内容
	msg := fmt.Sprintf("From: %s\r\nTo: %s\r\nSubject: %s\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n%s",
		from, to, subject, content)

	addr := fmt.Sprintf("%s:%d", p.host, p.port)

	// 使用 TLS
	tlsConfig := &tls.Config{
		ServerName: p.host,
	}

	conn, err := tls.Dial("tcp", addr, tlsConfig)
	if err != nil {
		// 尝试非 TLS
		return smtp.SendMail(addr, smtp.PlainAuth("", p.username, p.password, p.host), p.from, []string{to}, []byte(msg))
	}
	defer conn.Close()

	client, err := smtp.NewClient(conn, p.host)
	if err != nil {
		return err
	}
	defer client.Close()

	// 认证
	auth := smtp.PlainAuth("", p.username, p.password, p.host)
	if err = client.Auth(auth); err != nil {
		return err
	}

	// 设置发件人
	if err = client.Mail(p.from); err != nil {
		return err
	}

	// 设置收件人
	if err = client.Rcpt(to); err != nil {
		return err
	}

	// 写入数据
	w, err := client.Data()
	if err != nil {
		return err
	}
	defer w.Close()

	_, err = w.Write([]byte(msg))
	return err
}

// SendVerificationCode 发送验证码邮件
func SendVerificationCode(to, code string) error {
	provider, err := NewProvider()
	if err != nil {
		return err
	}

	subject := "验证码"
	content := fmt.Sprintf(`
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
    <h2>您的验证码</h2>
    <p>您的验证码是：</p>
    <div style="font-size: 32px; font-weight: bold; color: #333; padding: 20px; background: #f5f5f5; text-align: center; letter-spacing: 5px;">
        %s
    </div>
    <p>此验证码 5 分钟内有效，请勿泄露给他人。</p>
</div>
`, code)

	return provider.Send(to, subject, content)
}
