package controllers

import (
	"WorldEpcho/src/config"
	"WorldEpcho/src/config/e"
	database "WorldEpcho/src/datasource"
	"WorldEpcho/src/models"
	"WorldEpcho/src/service"
	"WorldEpcho/src/utils"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"strings"
	"time"
)

//服务商用户注册接口
func MiGuServiceProviderRegister1(c *gin.Context) {
	//获取表单信息
	//userName := c.PostForm("username") //MiGu

	uuid := utils.GenerateUUID()
	userName := "MiGu" + "@" + uuid
	//phone := c.PostForm("phone")       //手机号
	phone := userName

	//AuthId := c.PostForm("AuthId")     //服务商Id
	AuthId := c.GetHeader("AuthId") //服务商Id
	// 从请求头中获取 JWT token
	tokenString := c.GetHeader("Token")
	if tokenString == "" {
		fmt.Printf("no Authorization token provided")
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "请求头中无token信息!"})
	}
	isValid, err := service.IsValidMiGuToken(tokenString)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "解析token出错!"})
	}
	if !isValid {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "无效的token"})
	}
	//开启事务
	session := database.Engine.NewSession()
	defer session.Close() //延迟关闭session
	err = session.Begin()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "开启事务失败!"})
		fmt.Println("开启事务失败")
		return
	}
	//用户角色标签
	Tags := c.PostForm("tags")
	if Tags == "" {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户角色标签不能为空!"})
		fmt.Println("用户角色标签不能为空")
		return
	}
	//可以访问的标签
	TagsArr := []string{}
	// 分割字符串，得到单独的字符串
	tagsSplit := strings.Split(Tags, ",")
	for _, tagStr := range tagsSplit {
		// 将转换后的字符串添加到数组
		TagsArr = append(TagsArr, tagStr)
	}

	var SP *models.ServiceProvider
	//var err error

	if AuthId != "" {
		SP, err = models.GetServiceProviderById_Tx(session, AuthId)
		if err != nil {
			fmt.Println("根据服务商id查询出错:", err)
			c.JSON(http.StatusOK, gin.H{"code": 0, "message": "根据服务商id查询服务商出错"})
			return
		}
		fmt.Println("SP ===>", SP)
		if SP == nil {
			c.JSON(http.StatusOK, gin.H{"code": 0, "message": "非法的服务商"})
			return
		}
	} else {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "服务商ID不能为空"})
		return
	}

	//注册之前先判断该用户名是否已经被注册，如果已经注册，返回错误
	id, err := models.QueryUserWithUsernameAndPhone(userName, phone)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "根据用户名和手机号查询数据错误!"})
		return
	}
	fmt.Println("id:", id)
	if id > 0 {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "用户名已经存在，该手机已注册!"})
		return
	}

	password := c.PostForm("password")
	fmt.Println("用户名: ", userName, "用户加密前密码: ", password, "手机号:", phone)

	//注册用户名和密码
	//存储的密码是md5后的数据，那么在登录的验证的时候，也是需要将用户的密码md5之后和数据库里面的密码进行判断
	fmt.Println("=== md5后: ===", utils.MD5(password))
	/*
	   调用工具类的MD5加盐的函数
	*/
	salt := config.Conf.Md5Salt
	md5String, err := utils.MD5BySalf(password, salt)
	if err != nil {
		log.Println("密码加盐失败！")
	}
	fmt.Println("用户密码加盐后：", md5String)

	//判断是否存在邀请码
	//code := c.PostForm("invite_code")

	NewUser := models.User{
		Username:         userName,
		Phone:            phone,
		Password:         md5String,
		Status:           0,
		Createtime:       time.Now().Unix(),
		Level:            9,
		RegisteredSource: SP.Name,
		Tags:             TagsArr,
	}

	//添加用户
	rows, user_id, err := models.AddUser(session, &NewUser)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "注册失败"})
		log.Println(err.Error())
		return
	}
	if rows <= 0 {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "注册失败"})
		fmt.Println("用户注册失败！")
		return
	}

	/*
	 添加用户详情信息, 根据注册用户id，查询注册用户的详细信息是否已经在详细信息表中
	*/
	_, exist, err := models.GetUserInfoByPhone(session, phone)
	if err != nil {
		fmt.Println("根据手机号查询用户是否存在，查询失败")
		c.JSON(http.StatusInternalServerError, gin.H{"code": 0, "message": "根据手机查询用户详情信息是否存在出错"})
		return
	}
	//创建用户详情信息
	UserSex := "不详"
	userinfoName := "不详"
	userinfo := &models.UserInfo{
		UserName: userinfoName,
		UserSex:  UserSex,
		Phone:    phone,
	}
	userinfo.UserId = user_id
	if !exist {
		//用户详情信息表操作
		err = models.FindOrCreateOrUpdateUserInfoByPhone(session, userinfo)
		if err != nil {
			fmt.Printf("向用户信息表添加用户数据失败")
			c.JSON(http.StatusInternalServerError, gin.H{"code": 0, "message": err.Error()})
			return
		}
	}

	//提交事务
	err = session.Commit()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 0, "message": "注册失败"})
		return
	} else {
		c.JSON(http.StatusOK, gin.H{"code": 1, "userId": user_id, "message": "注册成功!"})
	}

}

// MiGuServiceProviderRegister handles the registration process for service provider users.
func MiGuServiceProviderRegister(c *gin.Context) {

	uuid := utils.GenerateUUID()
	userName := "MiGu@" + uuid
	phone := userName

	// 从请求头获取服务商Id
	AuthId := c.GetHeader("AuthId") //服务商Id

	// 从请求头中获取 JWT token
	tokenString := c.GetHeader("Token")
	if tokenString == "" {
		fmt.Printf("no Authorization token provided")
		c.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "请求头中无token信息!"})
		return
	}
	isValid, err := service.IsValidMiGuToken(tokenString)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": e.TokenAuthError, "data": nil, "message": "解析token出错!"})
		return
	}
	if !isValid {
		c.JSON(http.StatusOK, gin.H{"code": e.InvalidToken, "data": nil, "message": "无效的token"})
		return
	}

	session := database.Engine.NewSession()
	defer session.Close()

	if err := session.Begin(); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": e.InternalError, "data": nil, "message": "开启事务失败!"})
		return
	}

	// 检查服务商
	var SP *models.ServiceProvider
	if AuthId != "" {
		SP, err = models.GetServiceProviderById_Tx(session, AuthId)
		if err != nil || SP == nil {
			c.JSON(http.StatusOK, gin.H{"code": e.IllegalServiceProvider, "data": nil, "message": "非法的服务商"})
			return
		}
	} else {
		c.JSON(http.StatusOK, gin.H{"code": e.EmptyParamsError, "data": nil, "message": "服务商ID不能为空"})
		return
	}

	// 检查用户是否已经注册
	id, err := models.QueryUserWithUsernameAndPhone(userName, phone)
	if err != nil || id > 0 {
		c.JSON(http.StatusOK, gin.H{"code": e.InvalidParams, "data": nil, "message": "用户名已经存在，该手机已注册!"})
		return
	}

	// Hash the password
	password := "88888888abc"
	fmt.Println("用户名: ", userName, "用户加密前密码: ", password, "手机号:", phone)
	fmt.Println("=== md5后: ===", utils.MD5(password))
	/*
	   调用工具类的MD5加盐的函数
	*/
	salt := config.Conf.Md5Salt
	md5String, err := utils.MD5BySalf(password, salt)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": e.InternalError, "data": nil, "message": "密码加密失败"})
		return
	}
	// 默认用户标签
	TagArray := []string{"训战"}
	//创建新的用户
	NewUser := models.User{
		Username:         userName,
		Phone:            phone,
		Password:         md5String,
		Status:           0,
		Createtime:       time.Now().Unix(),
		Level:            9,
		RegisteredSource: SP.Name,
		Tags:             TagArray,
		AuthId:           AuthId,
	}

	rows, user_id, err := models.AddUser(session, &NewUser)
	if err != nil || rows <= 0 {
		c.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": "注册失败"})
		return
	}
	/*
	 添加用户详情信息, 根据注册用户id，查询注册用户的详细信息是否已经在详细信息表中
	*/
	_, exist, err := models.GetUserInfoByPhone(session, phone)
	if err != nil {
		fmt.Println("根据手机号查询用户是否存在，查询失败")
		c.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": "根据手机查询用户详情信息是否存在出错"})
		return
	}
	//创建用户详情信息
	UserSex := "不详"
	userinfoName := "不详"
	userinfo := &models.UserInfo{
		UserName: userinfoName,
		UserSex:  UserSex,
		Phone:    phone,
	}
	userinfo.UserId = user_id
	if !exist {
		//用户详情信息表操作
		err = models.FindOrCreateOrUpdateUserInfoByPhone(session, userinfo)
		if err != nil {
			fmt.Printf("向用户信息表添加用户数据失败")
			c.JSON(http.StatusOK, gin.H{"code": e.ErrorDatabase, "data": nil, "message": err.Error()})
			return
		}
	}
	// 提交事务
	if err := session.Commit(); err != nil {
		c.JSON(http.StatusOK, gin.H{"code": e.InternalError, "data": nil, "message": "提交事务失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"code": e.SUCCESS, "data": gin.H{"userId": user_id}, "message": "创建用户成功!"})
}

// 刷新jwt token
func RefreshJwtToken(c *gin.Context) {
	// 从请求头 Authorization 中提取令牌
	tokenString := c.GetHeader("Token")
	if tokenString != "" {
		// 解析并验证 JWT 令牌
		token, isValid, err := service.ParseMIGUToken(tokenString)
		if err != nil || !isValid {
			c.JSON(http.StatusOK, gin.H{"code": e.InvalidToken, "data": nil, "message": "无效或已过期的令牌"})
			return
		}

		// 打印当前令牌的过期时间
		if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
			oldExp, ok := claims["exp"].(float64)
			if ok {
				fmt.Printf("当前令牌过期时间: %s\n", time.Unix(int64(oldExp), 0).Format("2006-01-02 15:04:05"))
			}

			userID, _ := claims["user_id"].(float64)
			level, _ := claims["level"].(int)

			// 生成新的令牌，并延长有效期
			newToken, newExp, err := GenerateLoginJWTToken2(int64(userID), level)
			if err != nil {
				c.JSON(http.StatusOK, gin.H{"code": e.RenewalTimeTokenError, "data": nil, "message": "令牌续期失败"})
				return
			}

			// 打印新令牌的过期时间
			fmt.Printf("新令牌过期时间: %s\n", time.Unix(newExp, 0).Format("2006-01-02 15:04:05"))

			// 返回新的令牌和成功消息
			c.JSON(http.StatusOK, gin.H{
				"code":    e.SUCCESS,
				"message": "令牌已成功续期",
				"data": gin.H{
					"newToken": newToken,
					"tokenExp": time.Unix(newExp, 0).Format("2006-01-02 15:04:05"),
				},
			})
			return
		}
	} else {
		// 如果未发现令牌，则返回未授权访问的错误消息
		c.JSON(http.StatusOK, gin.H{"code": e.UnauthorizedStatus, "data": nil, "message": "未授权访问"})
	}

}
