package service

import (
	"bytes"
	"crypto/tls"
	"fmt"
	ht "html/template"
	"strings"
	"time"

	"github.com/wneessen/go-mail"

	"be.ems/src/framework/config"
	"be.ems/src/framework/logger"
	"be.ems/src/framework/utils/date"
	"be.ems/src/framework/utils/parse"
	neDataModel "be.ems/src/modules/ne_data/model"
)

// EmailAlarm 发告警邮件
func EmailAlarm(a neDataModel.Alarm, neIP string) error {
	emailList := fmt.Sprint(config.Get("notification.email.list"))
	if len(emailList) == 0 {
		return fmt.Errorf("email list is empty")
	}

	// 模板
	htmlBodyTemplate := `
	<strong>Alarm information</strong>
		<p style="text-indent: 2.5em;">Sequence: {{.AlarmSeq}}</p>
		<p style="text-indent: 2.5em;">NE Name: {{.NeName}}</p>
		<p style="text-indent: 4.5em;">NE IP: {{.NeIp}}</p>
		<p style="text-indent: 5em;">Title: {{.AlarmTitle}}</p>
		<p style="text-indent: 3.5em;">Severity: {{.OrigSeverity}}</p>
		<p style="text-indent: 2.5em;">Event Time: {{.AlarmTime}}</p>
		<p style="text-indent: 2em;">Alarm Status: {{.AlarmStatus}}</p>
	<i>Automatic sent by OMC, please do not reply!</i> 
	`
	htmlTpl, err := ht.New("htmltpl").Parse(htmlBodyTemplate)
	if err != nil {
		return fmt.Errorf("EmailAlarm Parse alarmId:%s fail %s", a.AlarmId, err.Error())
	}
	// 参数值
	data := map[string]any{
		"AlarmSeq":     a.AlarmSeq,
		"NeName":       a.NeName,
		"NeIp":         neIP,
		"AlarmTitle":   a.AlarmTitle,
		"OrigSeverity": a.OrigSeverity,
		"AlarmTime":    date.ParseDateToStr(a.EventTime, time.RFC3339),
		"AlarmStatus":  a.AlarmStatus,
	}
	buffer := bytes.NewBuffer(nil)
	if err := htmlTpl.Execute(buffer, data); err != nil {
		return fmt.Errorf("EmailAlarm Execute alarmId:%s fail %s", a.AlarmId, err.Error())
	}
	htmlStr := buffer.String()

	// 发送邮件
	err = EmailSendHTML(htmlStr, strings.Split(emailList, ","))
	if err != nil {
		return fmt.Errorf("EmailAlarm alarmId:%s fail %s", a.AlarmId, err.Error())
	}
	return err
}

// EmailSendHTML 发送HTML邮件
func EmailSendHTML(htmlStr string, toEmailArr []string) error {
	// QQ 邮箱：
	// SMTP 服务器地址：smtp.qq.com（SSL协议端口：465/994 | 非SSL协议端口：25）
	// 163 邮箱：
	// SMTP 服务器地址：smtp.163.com（端口：25）
	// host := "mail.agrandtech.com"
	// port := 25
	// userName := "smtpext@agrandtech.com"
	// password := "1000smtp@omc!"

	emailConf := config.Get("notification.email").(map[string]any)
	enable := parse.Boolean(emailConf["enable"])
	if !enable {
		return fmt.Errorf("email notification not enable")
	}
	title := fmt.Sprint(emailConf["title"])
	smtp := fmt.Sprint(emailConf["smtp"])
	port := parse.Number(emailConf["port"])
	user := fmt.Sprint(emailConf["user"])
	password := fmt.Sprint(emailConf["password"])

	message := mail.NewMsg()
	// 发件人
	if err := message.From(user); err != nil {
		return fmt.Errorf("failed to set From address: %s", err)
	}
	// 收件人
	hasTo := false
	for _, v := range toEmailArr {
		if err := message.AddTo(v); err != nil {
			logger.Errorf("failed to set To address: %v %s", v, err)
			continue
		}
		hasTo = true
	}
	if !hasTo {
		return fmt.Errorf("failed to set To address not has")
	}
	// 邮件主题
	message.Subject(title)
	// 邮件HTML内容
	message.SetBodyString(mail.TypeTextHTML, htmlStr)
	// 连接到邮件SMTP服务器
	client, err := mail.NewClient(smtp,
		mail.WithSMTPAuth(mail.SMTPAuthAutoDiscover),
		mail.WithUsername(user),
		mail.WithPort(int(port)),
		mail.WithPassword(password),
		mail.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}),
	)
	if err != nil {
		return fmt.Errorf("failed to create mail client: %s", err)
	}
	// 发送
	if err := client.DialAndSend(message); err != nil {
		return fmt.Errorf("failed to send mail: %s", err)
	}
	return nil
}
