package controllers

import (
	"bytes"
	"context"
	"encoding/base64"
	"encoding/json"
	"errors"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/qit-team/snow-core/redis"
	"gopkg.in/go-playground/validator.v9"
	zh_translations "gopkg.in/go-playground/validator.v9/translations/zh"
	"io/ioutil"
	"net/http"
	"qteam/app/utils"
	"qteam/config"

	"qteam/app/constants/errorcode"

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

/**
 * 成功时返回
 */
func Success(c *gin.Context, data interface{}, message string) {
	if message == "" {
		message = errorcode.GetMsg(errorcode.Success, c.GetHeader("local"))
	}
	if config.GetConf().Env == "production" {
		c.String(http.StatusOK, EncriptJson(gin.H{
			"code":    errorcode.Success,
			"message": message,
			"data":    data,
		}))
	} else {
		c.JSON(http.StatusOK, gin.H{
			"code":    errorcode.Success,
			"message": message,
			"data":    data,
		})
	}

	c.Abort()
}
func EncriptJson(h gin.H) string {
	var data, err = json.Marshal(h)
	if err != nil {
		utils.Log(nil, "encriptJso", err)
	}
	rs, err := utils.Des3Encrypt(data, config.GetConf().AppKey)
	res := base64.StdEncoding.EncodeToString(rs)
	return res
}

/**
 * 失败时返回
 */
func Error(c *gin.Context, code int, msg ...string) {
	message := ""
	if len(msg) > 0 {
		message = msg[0]
	} else {
		message = errorcode.GetMsg(code, "")
	}
	if config.GetConf().Env == "production" {
		c.String(http.StatusOK, EncriptJson(gin.H{
			"code":    code,
			"message": message,
			"data":    make(map[string]string),
		}))
	} else {
		c.JSON(http.StatusOK, gin.H{
			"code":    code,
			"message": message,
			"data":    make(map[string]string),
		})
	}

	c.Abort()
}

func Error404(c *gin.Context) {
	Error(c, errorcode.NotFound, "路由不存在")
}

func Error500(c *gin.Context) {
	Error(c, errorcode.SystemError)
}

type HTTPError struct {
	Code    int    `json:"code" example:"400"`
	Message string `json:"message" example:"status bad request"`
}

/**
 * 将请求的body转换为request数据结构
 * @param c
 * @param request  传入request数据结构的指针 如 new(TestRequest)
 */
func GenRequest(c *gin.Context, request interface{}) (msgs []string, err error) {
	if c.Request.Method == "GET" || c.Request.Method == "DELETE" {
		err = c.ShouldBindQuery(request)
	} else {
		err = c.ShouldBindJSON(request)
	}

	if err == nil {
		validate := validator.New()
		zh_ch := zh.New()

		uni := ut.New(zh_ch)
		trans, _ := uni.GetTranslator("zh")
		//验证器注册翻译器
		zh_translations.RegisterDefaultTranslations(validate, trans)
		errValidate := validate.Struct(request)

		if errValidate != nil {
			for _, v := range errValidate.(validator.ValidationErrors) {
				msgs = append(msgs, v.Translate(trans))
			}
			err = errors.New(errorcode.GetMsg(errorcode.ParamError, ""))
			return
		}
	}
	return
}

// 重复读取body
func ReadBody(c *gin.Context) (body []byte, err error) {
	body, err = ioutil.ReadAll(c.Request.Body)
	if err != nil {
		return
	}
	c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
	return
}

func GetRequest(c *gin.Context) interface{} {
	request, _ := c.Get("request")
	return request
}

func HandRes(c *gin.Context, data interface{}, err error) {
	if err == nil {
		Success(c, data, "")
	} else {
		Error(c, errorcode.SystemError, err.Error())
	}
}
func HandCodeRes(c *gin.Context, data interface{}, code int) {
	if code == errorcode.Success {
		Success(c, data, errorcode.GetMsg(code, c.GetHeader("local")))
	} else {
		Error(c, code, errorcode.GetMsg(code, c.GetHeader("local")))
	}
}
func GetPlayerId(c *gin.Context) string {
	playerId, _ := c.Get("playerId")
	if playerId == nil {
		return ""
	}
	return playerId.(string)
}

func Frequence(key string) bool {
	if rs := redis.GetRedis().Exists(context.Background(), utils.GetRealKey(key)); rs.String() != "" {
		return false
	} else {
		redis.GetRedis().SetEX(context.Background(), utils.GetRealKey(key), 1, 5)
		return true
	}
}
