package middleware

import (
	"context"
	"designs/common"
	"designs/config"
	"designs/global"
	"designs/response"
	"fmt"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
)

/* 包体大小 */
func LimitRequestBodySize(maxSize int64) gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxSize)
		if err := c.Request.ParseForm(); err != nil {
			c.JSON(http.StatusRequestEntityTooLarge, gin.H{"error": "Request body too large"})
			c.Abort()
			return
		}
		c.Next()
	}
}

/* token中间件 */
func TokenAuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		contentLength := c.Request.ContentLength
		if contentLength > config.GetInt64("app.max_content") {
			// 输出请求体的大小
			// fmt.Printf("Request body size: %d bytes\n", contentLength)
			response.Fail(c, 1003, "ruquest too max")
			c.Abort()
			return
		}
		token := c.GetHeader("Authorization")
		//校验token
		if token == "" {
			response.Fail(c, -2, "Unauthorized")
			c.Abort()
			return
		}
		ok, userName := isValidToken(token)
		if !ok {
			response.Fail(c, -1, "authorized invalid!")
			c.Abort()
			return
		}

		//校验请求次数
		//apiPath := c.FullPath()
		//key := fmt.Sprintf("%s:%s:%s:%s:%s", gid, config.Get("app.api_limit_key"), pf, openid, apiPath)
		//count, err := global.App.Redis.Incr(context.Background(), key).Result()
		//if err != nil {
		//	common.RetJson(1001, "server error!", "", c)
		//	c.Abort()
		//	return
		//}
		//if count == 1 {
		//	global.App.Redis.Expire(context.Background(), key, time.Minute).Result()
		//}
		//if count > config.GetInt64("app.api_limit_count") {
		//	common.RetJson(1002, "too many requests!", "", c)
		//	c.Abort()
		//	return
		//}
		//设置上下文数据
		c.Set("userName", userName)
		//如果校验通过

	}
}

/* token是否有效 */
func isValidToken(token string) (bool, string) {
	userName, tokenType := common.ParseJwtWithClaims(token)

	//fmt.Printf("openid:%v,gid:%v,pf:%v,tokenType:%v", openid, gid, pf, tokenType)

	if userName == "" {
		return false, userName
	} else {
		//登录tonken 类型
		if tokenType == 0 {
			return true, userName
		}
		return false, userName
	}
}

/* 刷新token中间件 */
func RefreshTokenAuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		token := c.GetHeader("Authorization")
		//校验token
		if token == "" {
			response.Fail(c, -2, "Unauthorized")

			c.Abort()
			return
		}
		ok, userName := isValidRefreshToken(token)
		if !ok {
			response.Fail(c, -1, "authorized invalid!")
			c.Abort()
			return
		}
		//校验请求次数
		apiPath := c.FullPath()
		key := fmt.Sprintf("%s:%s", config.Get("app.api_limit_key"), apiPath)
		count, err := global.App.Redis.Incr(context.Background(), key).Result()
		if err != nil {
			response.Fail(c, 1001, "server error!")
			c.Abort()
			return
		}
		if count == 1 {
			global.App.Redis.Expire(context.Background(), key, time.Minute).Result()
		}
		if count > config.GetInt64("app.api_limit_count") {
			response.Fail(c, 1002, "too many requests!")
			c.Abort()
			return
		}
		//设置上下文数据
		c.Set("userName", userName)

		//如果校验通过
		c.Next()
	}
}

/* token是否有效 */
func isValidRefreshToken(token string) (bool, string) {
	userName, tokenType := common.ParseJwtWithClaims(token)
	//fmt.Printf("openid:%v,gid:%v", openid, gid)
	if userName == "" {
		return false, userName
	} else {
		//登录刷新tonken 类型
		if tokenType == 1 {
			return true, userName
		}
		return false, userName
	}
}
