package utils

import (
	"crypto/tls"
	"fmt"
	"io"
	"log"
	"strings"

	"github.com/PuerkitoBio/goquery"
	"github.com/emersion/go-imap"
	"github.com/emersion/go-imap/client"
	"github.com/emersion/go-message/mail"
)

type EmailImap struct {
}

// 获取最新一封邮件的正文内容
func (*EmailImap) GetLatestMailContent(server, username, password string) (string, error) {
	// 1. 连接 IMAP 服务器 (SSL/TLS, 端口 993)
	tlsConfig := &tls.Config{InsecureSkipVerify: true}
	c, err := client.DialTLS(server, tlsConfig)
	if err != nil {
		return "", fmt.Errorf("连接失败: %v", err)
	}
	defer c.Logout()

	// 2. 登录
	if err := c.Login(username, password); err != nil {
		return "", fmt.Errorf("登录失败: %v", err)
	}

	// 3. 选择收件箱
	mbox, err := c.Select("INBOX", false)
	if err != nil {
		return "", fmt.Errorf("选择收件箱失败: %v", err)
	}
	if mbox.Messages == 0 {
		return "", nil // 没有邮件
	}

	// 4. 获取最新一封邮件
	seqset := new(imap.SeqSet)
	seqset.AddNum(mbox.Messages)

	section := &imap.BodySectionName{}
	messages := make(chan *imap.Message, 1)
	go func() {
		if err := c.Fetch(seqset, []imap.FetchItem{section.FetchItem()}, messages); err != nil {
			log.Println("获取邮件失败:", err)
		}
	}()

	msg := <-messages
	if msg == nil {
		return "", nil
	}

	r := msg.GetBody(section)
	if r == nil {
		return "", nil
	}

	// 5. 解析邮件正文
	mr, err := mail.CreateReader(r)
	if err != nil {
		return "", fmt.Errorf("解析邮件失败: %v", err)
	}

	var htmlContent, textContent string

	for {
		p, err := mr.NextPart()
		if err == io.EOF {
			break
		}
		if err != nil {
			return "", fmt.Errorf("读取邮件失败: %v", err)
		}

		switch h := p.Header.(type) {
		case *mail.InlineHeader:
			mediaType, _, _ := h.ContentType()
			b, _ := io.ReadAll(p.Body)
			if strings.HasPrefix(mediaType, "text/html") {
				htmlContent = string(b)
			} else if strings.HasPrefix(mediaType, "text/plain") {
				textContent = string(b)
			}
		}
	}

	// 优先返回 HTML，没有就退回纯文本
	if htmlContent != "" {
		return htmlContent, nil
	}
	return textContent, nil
}

func (e *EmailImap) GetMailCode(server, username, password string) string {
	res, err := e.GetLatestMailContent(server, username, password)
	if err != nil {
		return "0"
	}

	htmlStr := res

	doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlStr))
	if err != nil {
		return "0"
	}

	code := ""
	doc.Find("td.h1.black").Each(func(i int, s *goquery.Selection) {
		if code == "" {
			code = strings.TrimSpace(s.Text())
		}
	})

	if code == "" {
		return "0"
	}
	return strings.TrimSpace(code)
}

func test() {
	var emailImap EmailImap
	content, err := emailImap.GetLatestMailContent("pop.dragonsmail.com:993", "CamilleMathews1u8K@dragonsmail.com", "vDgADn`zga.")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("最新邮件内容:\n", content)
}
