package gpt

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"regexp"
	"strings"
	"time"
)

var (
	host     string
	telNum   string
	password string
)

type auth struct {
	expiredAt time.Time
	auth      string
}

type LoginData struct {
	Status int         `json:"status"`
	Data   User        `json:"data"`
	Msg    string      `json:"msg"`
	Code   int         `json:"code"`
	Error  interface{} `json:"error"`
	Err    string      `json:"err"`
	Keys   []string    `json:"keys"`
}
type User struct {
	Token string `json:"Token"`
}

type GptRes struct {
	Status int         `json:"status"`
	Data   Data        `json:"data"`
	Msg    string      `json:"msg"`
	Code   int         `json:"code"`
	Error  interface{} `json:"error"`
	Err    string      `json:"err"`
	Keys   interface{} `json:"keys"`
}

type Data struct {
	Answer string `json:"answer"`
}

var authObj = auth{}

func InitSet(tempHost, tel, paw string) {
	host = tempHost
	telNum = tel
	password = paw
}

// 登陆url
func getGetLoginUrl() string {
	return host + "/user/login"
}

func getGptTextUrl() string {
	return host + "/chat/completion-text"
}

// getLoginAuth 冲登陆中获取 登陆标志
func getLoginAuth() (string, error) {

	userRes := &LoginData{}
	//登陆
	bodyStr := `{"TelNum": "` + telNum + `","Password": "` + password + `"}`

	// 目标URL
	url := getGetLoginUrl()

	fmt.Println(bodyStr)
	// 创建POST请求
	requestObj, err := http.NewRequest("POST", url, bytes.NewBufferString(bodyStr))
	if err != nil {
		fmt.Println("Error creating request:", err)
		return "", err
	}

	// 设置Headers
	requestObj.Header.Set("Content-Type", "application/json")
	// 初始化HTTP客户端
	client := &http.Client{}
	fmt.Println(1)

	// 发送请求
	response, err := client.Do(requestObj)
	if err != nil {
		fmt.Println("Error sending POST request:", err)
		return "", err
	}
	defer response.Body.Close()
	fmt.Println(2)

	// 检查HTTP响应状态码
	if response.StatusCode != http.StatusOK {
		fmt.Printf("Error: HTTP status code is %d\n", response.StatusCode)
		return "", errors.New(fmt.Sprintf("Error: HTTP status code is %d\n", response.StatusCode))
	}

	fmt.Println(3)
	// 直接将响应内容复制到标准输出
	body, err := io.ReadAll(response.Body)
	if err != nil {
		// 处理复制内容时出现的错误
		fmt.Printf("Error copying response to stdout: %s\n", err)
		return "", err
	}
	fmt.Println(4)
	err = json.Unmarshal(body, &userRes)
	if err != nil {
		// 处理复制内容时出现的错误
		fmt.Printf("json.Error copying response to stdout: %s\n", err)
		return "", err
	}

	if userRes.Status != 0 {
		// 处理复制内容时出现的错误
		fmt.Printf("json.Error copying response to stdout: %s\n", err)
		return "", errors.New("翻译失败,帐号信息 " + userRes.Msg)
	}

	return userRes.Data.Token, nil
}

// getLoginAuth 获取登陆标志,过期则重新获取
func getAuth() (string, error) {

	fmt.Println(authObj.expiredAt)
	fmt.Println(authObj.expiredAt.After(time.Now()))

	//帐号未过期
	if authObj.expiredAt.After(time.Now()) {
		return authObj.auth, nil
	}

	//重新获取
	authCode, err := getLoginAuth()
	if err != nil {
		return "", err
	}

	authObj.expiredAt = time.Now().Add(2 * time.Hour)
	authObj.auth = authCode
	return authCode, err
}

func setAuthExpire() {
	authObj.expiredAt = authObj.expiredAt.AddDate(-1, 0, 0)
}

// GptContentLand gpt翻译成语言
func GptContentLand(content, land string) (newContent string, err error) {
	if isDefaultLang(land) {
		return content, nil
	}

	val := cache.RedisClient.HGet(cache.GetLangHashKey(land), content).Val()

	if val != "" {
		return val, nil
	}

	newContent, err = realGptContentLand(content, land)
	if err != nil {
		return "", err
	}

	cache.RedisClient.HSet(cache.GetLangHashKey(land), content, newContent)

	return newContent, err
}

func isDefaultLang(lang string) bool {

	if lang != "Ja" && lang != "ZhTW" && lang != "EN" {
		return true
	}

	return false
}

// realGptContentLand gpt翻译成语言
func realGptContentLand(content, land string) (newContent string, err error) {

	if land == "Ja" {
		newContent, err = gptContent("翻译成日语:" + content)
		fmt.Println(newContent)

	} else if land == "ZhTW" {
		newContent, err = gptContent("翻译成繁体:" + content)
	} else if land == "EN" {
		newContent, err = gptContent("翻译成英语:" + content)
		if err == nil {
			parts := strings.Split(newContent, "\n")
			fmt.Println(newContent)
			fmt.Println(parts)
			if len(parts) > 1 {
				newContent = parts[1]
				newContent = strings.Replace(newContent, "\\", "", 0)
			}
		}

	} else {
		newContent = content
	}

	//去重空格
	fmt.Println("1-------", newContent)
	newContent = removeAfterNewline(newContent)

	fmt.Println("2-------", newContent)

	return newContent, err
}

func removeAfterNewline(s string) string {
	// 编译正则表达式,匹配第一个换行符(包括 \n, \r\n, \r)及其后的内容
	re := regexp.MustCompile(`(\r\n|\r|\n|\\n).*`)
	// 替换匹配部分为空字符串
	return re.ReplaceAllString(s, "")
}

func gptContent(content string) (string, error) {

	authCode, err := getAuth()
	if err != nil {
		return "", err
	}
	fmt.Println(content)

	res, err := getGptContent(content, authCode)
	if err != nil {
		errMsg := err.Error()
		if errMsg == "请先登陆" {
			setAuthExpire()
			authCode1, err1 := getAuth()
			if err1 != nil {
				return "", err
			}

			res1, err1 := getGptContent(content, authCode1)
			if err1 != nil {
				return "", err1
			}
			return res1, nil
		}
		return "", err
	}
	return res, nil

}

// GetGptContent 获取翻译
func getGptContent(content, authCode string) (string, error) {
	var res *GptRes

	if content == "" {
		return "", errors.New("内容不能为空")
	}

	//增加文字的黄反鉴别
	strBody := `{
	"model": "gpt-4-1106-preview",
	"max_tokens": 1000,
	"temperature": 1,
	"top_p": 1,
	"presence_penalty": 0,
	"frequency_penalty": 0,
	"messages": [
		{
			"role": "user",
			"content": "` + content + `"
		}
	],
	"listUuid": "",
	"stream": true
}`

	// 目标URL
	url := getGptTextUrl()

	// 创建POST请求
	requestObj, err := http.NewRequest("POST", url, bytes.NewBufferString(strBody))
	if err != nil {
		fmt.Println("Error creating request:", err)
		return "", err
	}

	// 设置Headers
	requestObj.Header.Set("Content-Type", "application/json")
	requestObj.Header.Set("Authorization", authCode)

	// 初始化HTTP客户端
	client := &http.Client{}

	// 发送请求
	response, err := client.Do(requestObj)
	if err != nil {
		fmt.Println("Error sending POST request:", err)
		return "", err
	}
	defer response.Body.Close()

	// 检查HTTP响应状态码
	if response.StatusCode != http.StatusOK {
		fmt.Printf("Error: HTTP status code is %d\n", response.StatusCode)
		return "", errors.New(fmt.Sprintf("Error: HTTP status code is %d\n", response.StatusCode))
	}

	// 直接将响应内容复制到标准输出
	body, err := io.ReadAll(response.Body)
	if err != nil {
		// 处理复制内容时出现的错误
		fmt.Printf("Error copying response to stdout: %s\n", err)
		return "", err
	}
	err = json.Unmarshal(body, &res)
	if err != nil {
		// 处理复制内容时出现的错误
		fmt.Printf("json.Error copying response to stdout: %s\n", err)
		return "", err
	}

	if res.Status != 0 {
		return "", errors.New(res.Msg)
	}

	return res.Data.Answer, nil
}