package mail

import (
	"crypto/tls"
	"errors"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"io"
	"log"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"strings"
	"time"
)

const (
	//LoginSuccessUrl = "https://mail.fontree.cn/iredadmin/dashboard?checknew" //登录后的重定向地址
	CreateUrl = "http://106.12.56.142/admin/box/new?new=true"
	LoginUrl  = "http://106.12.56.142/admin/login"
)

type iredCookie struct {
	Cookie   string
	Name     string
	ExpireAt *time.Time
}

type IRedMail struct {
	IsProd   bool   `json:"isProd"`
	Username string `json:"username"`
	Password string `json:"password"`
	Domain   string
	*iredCookie
}

type CreateAccountInfo struct {
	Username string
	Password string
	Cn       string
}

var ReadMail *IRedMail

func LoadEnv(userName, psw, domain string, isProd bool) {

	ReadMail = &IRedMail{
		IsProd:   isProd,
		Username: userName,
		Password: psw,
		Domain:   domain,
	}

}

//CreateMailAccount 创建电子邮箱账号
func (m *IRedMail) CreateMailAccount(new CreateAccountInfo) error {

	if m.IsProd != true {
		fmt.Println("过滤创建邮箱帐号")
		return nil
	}

	//0 登陆
	cookies, err := m.login()
	if err != nil {
		return err
	}

	/*
		//1 先去解析csrf_token
		csrfToken, err := m.getCsrfTokenBeforeAdd()
		if err != nil {
			return err
		}
		fmt.Println(csrfToken, err)
	*/
	//1 先去解析csrf_token
	err = m.createAccount(cookies, new)
	if err != nil {
		return err
	}

	return nil
}

// login 登陆超管
func (m *IRedMail) login() ([]*http.Cookie, error) {

	cookies, csrfToken, err := m.getCsrfTokenAndCookieBeforeLogin()
	if err != nil {
		return nil, err
	}
	fmt.Println(cookies, csrfToken)

	loginUrl := LoginUrl
	values := url.Values{}
	values.Set("email", m.Username)
	values.Set("password", m.Password)
	values.Set("_csrf_token", csrfToken)
	// 忽略HTTPS证书验证
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}

	tempCookieJar, _ := cookiejar.New(nil)
	u, err := url.Parse("http://106.12.56.142")
	if err != nil {
		log.Fatal(err)
		return nil, err
	}
	tempCookieJar.SetCookies(u, cookies)

	// 创建一个自定义Transport的HTTP客户端
	//client := &http.Client{Transport: tr, Jar:cookies }
	client := &http.Client{Transport: tr, Jar: tempCookieJar}

	// 发起POST请求
	res, err := client.PostForm(loginUrl, values)
	if err != nil {
		log.Fatal(err)
		return nil, err
	}

	// 发送请求
	defer res.Body.Close()
	//fmt.Println(res.)
	str, err := io.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}
	fmt.Println("成功")
	fmt.Println(string(str))

	/*
		if res.Request.URL.String() != LoginSuccessUrl {
			msg := res.Request.URL.Query().Get("msg")
			return errors.New("超管登录失败提示:" + msg)
		}
	*/

	/*
		for _, cookie := range res.Cookies() {
			temp := &iredCookie{
				Cookie: cookie.Value,
				Name:   cookie.Name,
			}
			m.iredCookie = temp
		}
	*/

	return res.Cookies(), nil
}

// getCsrfTokenAndCookieBeforeLogin 登陆前获取token
func (m *IRedMail) getCsrfTokenAndCookieBeforeLogin() ([]*http.Cookie, string, error) {
	var csrfToken string
	var isExist bool
	cookieJar, _ := cookiejar.New(nil)

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}

	// 创建一个HTTP客户端，并设置cookie jar
	client := &http.Client{
		Jar:       cookieJar,
		Transport: tr,
	}

	// 创建登录请求
	loginURL := LoginUrl
	req, err := http.NewRequest("GET", loginURL, nil)
	if err != nil {
		fmt.Println("创建请求失败:", err)
		return nil, "", err
	}

	// 发送登录请求
	res, err := client.Do(req)

	if err != nil {
		fmt.Println("请求错误", loginURL, err)
		return nil, "", err
	}

	defer res.Body.Close()
	if err != nil {
		return nil, "", err
	}
	str, err := io.ReadAll(res.Body)
	if err != nil {
		return nil, "", err
	}

	// 解析HTML
	doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(str)))
	if err != nil {
		return nil, "", err
	}

	doc.Find("input[name='_csrf_token']").Each(func(i int, s *goquery.Selection) {
		csrfToken, isExist = s.Attr("value")
		fmt.Println("查找1---", csrfToken, isExist) // 输出: testUser
	})

	if isExist == false {
		return nil, "", errors.New("没有查找到csrf_token")
	}

	return res.Cookies(), csrfToken, nil
}

// getCsrfTokenBeforeAdd 登陆前获取token
func (m *IRedMail) getCsrfTokenBeforeAdd() (string, error) {
	var csrfToken string
	var isExist bool
	cookieJar, _ := cookiejar.New(nil)

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}

	// 创建一个HTTP客户端，并设置cookie jar
	client := &http.Client{
		Jar:       cookieJar,
		Transport: tr,
	}

	// 创建登录请求
	loginURL := CreateUrl + m.Domain
	req, err := http.NewRequest("GET", loginURL, nil)
	if err != nil {
		fmt.Println("创建请求失败:", err)
		return "", err
	}

	// 向请求中添加cookie
	cookie := &http.Cookie{
		Name:  m.iredCookie.Name,
		Value: m.iredCookie.Cookie,
	}
	req.AddCookie(cookie)

	// 发送登录请求
	res, err := client.Do(req)

	if err != nil {
		fmt.Println("请求错误", loginURL, err)
		return "", err
	}

	defer res.Body.Close()
	if err != nil {
		return "", err
	}
	str, err := io.ReadAll(res.Body)
	if err != nil {
		return "", err
	}

	// 解析HTML
	doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(str)))
	if err != nil {
		return "", err
	}

	doc.Find("input[name='csrf_token']").Each(func(i int, s *goquery.Selection) {
		csrfToken, isExist = s.Attr("value")
		fmt.Println("查找1---", csrfToken, isExist) // 输出: testUser
	})

	if isExist == false {
		return "", errors.New("没有查找到csrf_token")
	}

	return csrfToken, nil
}

// createAccount 创建用户mail
func (m *IRedMail) createAccount(cookies []*http.Cookie, info CreateAccountInfo) error {
	cookieJar, _ := cookiejar.New(nil)

	values := url.Values{}
	values.Set("name", info.Cn)
	values.Set("user", info.Username)
	values.Set("domain", m.Domain)
	values.Set("passwordPlaintext", info.Password)

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	u, err := url.Parse("http://106.12.56.142")
	if err != nil {
		log.Fatal(err)
		return err
	}

	cookieJar.SetCookies(u, cookies)

	// 创建一个HTTP客户端，并设置cookie jar
	client := &http.Client{
		Jar:       cookieJar,
		Transport: tr,
		//CheckRedirect:
	}

	// 创建登录请求
	loginURL := CreateUrl
	req, err := http.NewRequest("POST", loginURL, strings.NewReader(values.Encode()))
	if err != nil {
		fmt.Println("创建请求失败:", err)
		return err
	}
	req.Header.Set("content-type", "application/x-www-form-urlencoded")

	// 发送登录请求
	res, err := client.Do(req)

	if err != nil {
		fmt.Println("请求错误", loginURL, err)
		return err
	}

	defer res.Body.Close()

	fmt.Println("状态码", res.StatusCode)
	fmt.Println("状态码", res.Status)

	return nil
}
