package controllers

import (
	"PaymentCenter/app/utils"
	"PaymentCenter/config"
	"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"
	"reflect"
	"regexp"

	"PaymentCenter/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()
		_ = validate.RegisterValidation("phoneValidation", phoneValidation)
		zh_ch := zh.New()

		uni := ut.New(zh_ch)
		trans, _ := uni.GetTranslator("zh")
		_ = validate.RegisterTranslation("phoneValidation", trans, func(ut ut.Translator) error {
			return ut.Add("phoneValidation", "手机号不合法", true) // 添加翻译
		}, func(ut ut.Translator, fe validator.FieldError) string {
			t, _ := ut.T("phoneValidation", fe.Field()) // 获取翻译
			return t
		},
		)

		//注册一个函数,获取struct tag里自定义的label作为字段名
		validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
			name := fld.Tag.Get("label")
			return name
		})
		//验证器注册翻译器
		_ = 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 utils.IsNil(data) {
		data = struct{}{}
	}
	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
	}
}

// 自定义验证器
func phoneValidation(fl validator.FieldLevel) bool {
	phone := fl.Field().String()
	if phone == "" {
		return true
	}
	// 使用正则表达式验证手机号
	phoneRegex := `^1[3-9]\d{9}$`
	reg := regexp.MustCompile(phoneRegex)
	return reg.MatchString(phone)
}