package utils

import (
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/jordan-wright/email"
	"github.com/spf13/cast"
	"mime"
	"net/smtp"
	"net/textproto"
	"path/filepath"
	"wireguard-ui/model"
)

type mail struct {
	*email.Email
	addr string
	auth smtp.Auth
	conf map[string]string
}

func Mail(conf *model.Setting) *mail {
	// 解析配置文件
	var mailConf = make(map[string]string)
	_ = json.Unmarshal([]byte(conf.Data), &mailConf)
	var m mail
	em := email.NewEmail()
	m.Email = em
	m.auth = smtp.PlainAuth("", mailConf["user"], mailConf["password"], mailConf["host"])
	m.addr = fmt.Sprintf("%s:%s", mailConf["host"], mailConf["port"])
	m.conf = mailConf
	return &m
}

func (m *mail) VerifyConfig() (err error) {
	if m == nil {
		return errors.New("邮件客户端初始化失败")
	}

	if m.auth == nil || m.addr == "" {
		return errors.New("邮件客户端未完成初始化")
	}

	return nil
}

// SendMail
// @description: 发送附件
// @receiver m
// @param to
// @param subject
// @param attacheFilePath
// @return err
func (m *mail) SendMail(to, subject, content, attacheFilePath string) (err error) {
	m.From = fmt.Sprintf("wg-dashboard <%s>", m.conf["user"])
	m.To = []string{to}
	m.Subject = subject
	m.Text = []byte(content)
	if attacheFilePath != "" {
		atch, err := m.AttachFile(attacheFilePath)
		if err != nil {
			return fmt.Errorf("读取附件文件失败: %v", err.Error())
		}
		emHeader := textproto.MIMEHeader{}
		emHeader.Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, mime.BEncoding.Encode("UTF-8", m.getFileName(attacheFilePath))))
		atch.Header = emHeader
	}

	if cast.ToBool(m.conf["skipTls"]) {
		return m.Send(m.addr, m.auth)
	}

	tlsConfig := &tls.Config{}
	tlsConfig.InsecureSkipVerify = cast.ToBool(m.conf["skipTls"])
	tlsConfig.ServerName = m.conf["host"]

	return m.SendWithTLS(m.addr, m.auth, tlsConfig)
}

// getFileName
// @description: 获取文件名
// @receiver m
// @param filePath
// @return string
func (m *mail) getFileName(filePath string) string {
	return filepath.Base(filePath)
}