package service

import (
	"context"
	"crypto/tls"
	"encoding/json"
	"fmt"

	"github.com/wneessen/go-mail"

	"be.ems/src/framework/config"
	"be.ems/src/framework/constants"
	"be.ems/src/framework/token"
	"be.ems/src/framework/utils/parse"
	"be.ems/src/modules/auth/model"
	systemModelVo "be.ems/src/modules/system/model/vo"
)

// BySMTP 登录创建用户信息
func (s *Account) BySMTP(body model.LoginSourceBody) (token.UserInfo, error) {
	info := token.UserInfo{}
	rows := s.sysLogSourceService.FindByActive(body.UID)
	if len(rows) != 1 {
		return info, fmt.Errorf("smtp auth source not exist")
	}
	item := rows[0]
	if item.Config == "" {
		return info, fmt.Errorf("smtp auth source config is empty")
	}
	var source systemModelVo.SysLoginSourceSMTP
	if err := json.Unmarshal([]byte(item.Config), &source); err != nil {
		return info, err
	}

	// 校验SMTP用户
	err := smtpAuth(source, body.Username, body.Password)
	if err != nil {
		return info, err
	}

	// 查询用户登录账号
	sysUser := s.sysUserService.FindByUserName(body.Username, item.Type, item.UID)
	if sysUser.UserId == 0 || sysUser.UserName == "" {
		sysUser = s.initLoginSourceUser(item.UID, item.Type, body.Username, body.Password)
	}
	if sysUser.UserId == 0 || sysUser.UserName != body.Username {
		return info, fmt.Errorf("login.errNameOrPasswd")
	}
	if sysUser.DelFlag == constants.STATUS_YES {
		return info, fmt.Errorf("login.errDelFlag")
	}
	if sysUser.StatusFlag == constants.STATUS_NO {
		return info, fmt.Errorf("login.errStatus")
	}

	// 登录用户信息
	info.UserId = sysUser.UserId
	info.DeptId = sysUser.DeptId
	info.User = sysUser
	// 用户权限组标识
	if config.IsSystemUser(sysUser.UserId) {
		info.Permissions = []string{constants.SYS_PERMISSION_SYSTEM}
	} else {
		perms := s.sysMenuService.FindPermsByUserId(sysUser.UserId)
		info.Permissions = parse.RemoveDuplicates(perms)
	}
	return info, nil
}

// smtpAuth 校验SMTP用户
func smtpAuth(source systemModelVo.SysLoginSourceSMTP, username, password string) error {
	client, err := mail.NewClient(source.Host,
		mail.WithSMTPAuth(mail.SMTPAuthAutoDiscover),
		mail.WithUsername(username),
		mail.WithPort(source.Port),
		mail.WithPassword(password),
		mail.WithTLSConfig(&tls.Config{InsecureSkipVerify: true}),
	)
	if err != nil {
		return fmt.Errorf("failed to create mail client %s", err)
	}
	// 连接到邮件SMTP服务器
	if err = client.DialWithContext(context.Background()); err != nil {
		return err
	}
	defer client.Close()
	return nil
}
