package system

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"sun-panel/api/api_v1/common/apiReturn"
	"sun-panel/api/api_v1/common/base"
	"sun-panel/global"
	"sun-panel/lib/cmn"
	"sun-panel/lib/cmn/systemSetting"
	"sun-panel/models"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"gorm.io/gorm"
)

type LoginApi struct {
}

// 登录输入验证
type LoginLoginVerify struct {
	Username string `json:"username" validate:"required"`
	Password string `json:"password" validate:"required,max=50"`
	VCode    string `json:"vcode" validate:"max=6"`
	Email    string `json:"email"`
}
type getTokenVerify struct {
	Username string `json:"username" validate:"required"`
}

// @Summary 登录账号
// @Accept application/json
// @Produce application/json
// @Param LoginLoginVerify body LoginLoginVerify true "登陆验证信息"
// @Tags user
// @Router /login [post]

func (l LoginApi) Login(c *gin.Context) {
	param := LoginLoginVerify{}
	if err := c.ShouldBindJSON(&param); err != nil {
		apiReturn.ErrorParamFomat(c, err.Error())
		return
	}

	if errMsg, err := base.ValidateInputStruct(param); err != nil {
		apiReturn.ErrorParamFomat(c, errMsg)
		return
	}

	settings := systemSetting.ApplicationSetting{}
	global.SystemSetting.GetValueByInterface("system_application", &settings)

	mUser := models.User{}
	var (
		err  error
		info models.User
	)
	bToken := ""
	param.Username = strings.TrimSpace(param.Username)
	if info, err = mUser.GetUserInfoByUsernameAndPassword(param.Username, cmn.PasswordEncryption(param.Password)); err != nil {
		// 未找到记录 账号或密码错误
		if err == gorm.ErrRecordNotFound {
			apiReturn.ErrorByCode(c, 1003)
			return
		} else {
			// 未知错误
			apiReturn.Error(c, err.Error())
			return
		}

	}

	// 停用或未激活
	if info.Status != 1 {
		apiReturn.ErrorByCode(c, 1004)
		return
	}

	bToken = info.Token
	if info.Token == "" {
		// 生成token
		buildTokenOver := false
		for !buildTokenOver {
			bToken = cmn.BuildRandCode(32, cmn.RAND_CODE_MODE2)
			if _, err := mUser.GetUserInfoByToken(bToken); err != nil {
				// 保存token
				mUser.UpdateUserInfoByUserId(info.ID, map[string]interface{}{
					"token": bToken,
				})
				buildTokenOver = true
			}
		}
		info.Token = bToken
	}
	info.Password = ""
	info.ReferralCode = ""

	// global.UserToken.SetDefault(bToken, info)
	cToken := uuid.NewString() + "-" + cmn.Md5(cmn.Md5("userId"+strconv.Itoa(int(info.ID))))
	global.CUserToken.SetDefault(cToken, bToken)
	global.Logger.Debug("token:", cToken, "|", bToken)
	global.Logger.Debug(global.CUserToken.Get(cToken))

	// 设置当前用户信息
	c.Set("userInfo", info)
	info.Token = cToken // 重要 采用cToken,隐藏真实token
	apiReturn.SuccessData(c, info)
}

// 安全退出
func (l *LoginApi) Logout(c *gin.Context) {
	// userInfo, _ := base.GetCurrentUserInfo(c)
	cToken := c.GetHeader("token")
	global.CUserToken.Delete(cToken)
	apiReturn.Success(c)
}

/**
 * @Author: wintsa
 * @Date: 2024-04-09 11:01:55
 * @LastEditors: wintsa
 * @Description: token生成
 * @return {*}
 */
func (l LoginApi) GetToken(c *gin.Context) {
	param := getTokenVerify{}

	if err := c.ShouldBindJSON(&param); err != nil {
		apiReturn.ErrorParamFomat(c, err.Error())
		return
	}

	if errMsg, err := base.ValidateInputStruct(param); err != nil {
		apiReturn.ErrorParamFomat(c, errMsg)
		return
	}
	fmt.Print("-----------2")

	settings := systemSetting.ApplicationSetting{}
	global.SystemSetting.GetValueByInterface("system_application", &settings)
	fmt.Print("-----------2")

	mUser := models.User{}
	var (
		err  error
		info models.User
	)
	bToken := ""

	param.Username = strings.TrimSpace(param.Username)
	info, err = mUser.GetUserInfoByUsername(param.Username)

	if err != nil {
		// 未找到记录 账号
		if err == gorm.ErrRecordNotFound {
			fmt.Print("-----------2")
			client := &http.Client{}

			data := url.Values{}
			data.Set("appid", "a2a6cab8-42e2-46d0-b0d2-4013e6708103")
			data.Set("loginid", param.Username)

			// 创建 HTTP 请求
			req, err := http.NewRequest("POST", "https://oa.zwgczx.com/ssologin/getToken", strings.NewReader(data.Encode()))
			if err != nil {
				panic(err)
			}

			// 设置请求头
			req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

			// 发送POST请求
			res, err := client.Do(req)
			if err != nil {
				panic(err)
			}
			defer res.Body.Close()

			// 读取响应
			body, err := ioutil.ReadAll(res.Body)
			if err != nil {
				panic(err)
			}

			if strings.Contains(string(body), "Token获取失败") {
				fmt.Println("请求失败: Token获取失败")
				apiReturn.ErrorNoAccess(c)

				panic("请求失败: Token获取失败")
				return
			}
			mUser := models.User{
				Username:  strings.TrimSpace(param.Username),
				Password:  cmn.PasswordEncryption("zw.123456"),
				Name:      param.Username,
				HeadImage: "",
				Status:    1,
				Role:      2,
				// Mail:      param.Username, 不再保存邮箱账号字段
			}
			userInfo, err := mUser.CreateOne()
			if err != nil {
				apiReturn.ErrorDatabase(c, err.Error())
				return
			}
			info = userInfo
		} else {
			// 未知错误
			apiReturn.Error(c, err.Error())
			return
		}

	}

	// 停用或未激活
	if info.Status != 1 {
		apiReturn.ErrorByCode(c, 1004)
		return
	}

	bToken = info.Token
	if info.Token == "" {
		// 生成token
		buildTokenOver := false
		for !buildTokenOver {
			bToken = cmn.BuildRandCode(32, cmn.RAND_CODE_MODE2)
			if _, err := mUser.GetUserInfoByToken(bToken); err != nil {
				// 保存token
				mUser.UpdateUserInfoByUserId(info.ID, map[string]interface{}{
					"token": bToken,
				})
				buildTokenOver = true
			}
		}
		info.Token = bToken
	}
	info.Password = ""
	info.ReferralCode = ""

	// global.UserToken.SetDefault(bToken, info)
	cToken := uuid.NewString() + "-" + cmn.Md5(cmn.Md5("userId"+strconv.Itoa(int(info.ID))))
	global.CUserToken.SetDefault(cToken, bToken)
	global.Logger.Debug("token:", cToken, "|", bToken)
	global.Logger.Debug(global.CUserToken.Get(cToken))
	fmt.Println("info", info)
	// 设置当前用户信息
	c.Set("userInfo", info)
	apiReturn.SuccessData(c, cToken)
}

/**
 * @Author: wintsa
 * @Date: 2024-04-09 11:02:30
 * @LastEditors: wintsa
 * @Description: token验证
 * @return {*}
 */
func (l LoginApi) VerifyToken(c *gin.Context) {
	// 从请求参数中获取 token
	token := c.Query("token")
	fmt.Println("---------------------------", token)
	// 检查 token 的有效性（这里仅做示例，实际需要根据业务逻辑来验证）
	if bToken, err := global.CUserToken.Get(token); err != false {
		// Token 有效，返回验证成功的响应
		mUser := models.User{}
		userInfo, err := mUser.GetUserInfoByToken(bToken)
		if err != nil {
			apiReturn.ErrorNoAccess(c)

			return
		}
		apiReturn.SuccessData(c, userInfo)

	} else {
		// Token 无效，返回验证失败的响应
		apiReturn.ErrorNoAccess(c)

	}
}
