package utils

import (
	"bytes"
	"crypto/tls"
	"fmt"
	"gopkg.in/gomail.v2"
	"html/template"
)

type emailUtils struct{}

var Email = emailUtils{}

type EmailConfig struct {
	Enable   bool   // 邮箱启用状态
	Username string // 邮箱用户名
	Address  string // 邮箱地址
	Host     string // 邮箱服务器地址
	Port     int    // 邮箱服务器端口
	Password string // 邮箱密码
	SSL      bool   // 是否使用SSL
}

// SendTemplate 发送HTML模板，从配置文件中读取邮箱配置，支持上下文控制
func (e *emailUtils) SendTemplate(emailConfig *EmailConfig, target, subject, htmlTemplate string, data map[string]interface{}) error {
	// 使用Go的模板系统处理HTML模板
	tmpl, err := template.New("email").Parse(htmlTemplate)
	if err != nil {
		return fmt.Errorf("解析模板失败: %w", err)
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, data); err != nil {
		return fmt.Errorf("执行模板失败: %w", err)
	}

	// 发送处理后的HTML内容
	return e.SendEmail(emailConfig, target, subject, buf.String(), true)
}

// SendEmail 使用gomail库发送邮件
func (e *emailUtils) SendEmail(emailConfig *EmailConfig, target, subject, content string, isHTML bool) error {
	if !emailConfig.Enable {
		return nil
	}
	// 创建新邮件
	m := gomail.NewMessage()
	m.SetHeader("From", emailConfig.Address)
	m.SetHeader("To", target)
	m.SetHeader("Subject", subject)
	// 设置内容类型
	if isHTML {
		m.SetBody("text/html", content)
	} else {
		m.SetBody("text/plain", content)
	}
	// 创建发送器
	d := gomail.NewDialer(emailConfig.Host, emailConfig.Port, emailConfig.Username, emailConfig.Password)
	// 配置SSL/TLS
	if emailConfig.SSL {
		d.SSL = true
	} else {
		// 对于非SSL但需要STARTTLS的情况
		d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
	}
	// 发送邮件
	if err := d.DialAndSend(m); err != nil {
		return fmt.Errorf("发送邮件失败: %w", err)
	}
	return nil
}

func (e *emailUtils) GetEmailConfigFromEnv() *EmailConfig {
	return &EmailConfig{
		Enable:   Env.GetAsBool("EMAIL_ENABLE", false),
		Username: Env.Get("EMAIL_USERNAME", ""),
		Address:  Env.Get("EMAIL_ADDRESS", ""),
		Host:     Env.Get("EMAIL_HOST", "smtp.example.com"),
		Port:     Env.GetAsInt("EMAIL_PORT", 587),
		Password: Env.Get("EMAIL_PASSWORD", ""),
		SSL:      Env.GetAsBool("EMAIL_SSL", true),
	}
}
