package webutils

import (
	"encoding/base64"
	"encoding/json"
	"net/http"

	"github.com/gin-gonic/gin"
	ut "github.com/go-playground/universal-translator"
	"github.com/sirupsen/logrus"
	"gogs.daxia.dev/huanan/pkg.daxia.dev/encrypt"
)

const (
	CodeSuccess      = 20000
	CodeFailed       = -1
	CodeIllegalToken = 50008
	CodeTokenExpired = 50014
	CodeOther        = 50012
)

var (
	trans ut.Translator
)

type RespError struct {
	msg string
}

func NewRespError(msg string) RespError {
	return RespError{
		msg: msg,
	}
}

func (p *RespError) Error() string {
	return ""
}

type Response struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

type ResponseGen[T interface{}] struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data T      `json:"data"`
}

func FailedResponse(c *gin.Context, msg string) {
	if c == nil {
		return
	}

	c.JSON(http.StatusOK, &Response{
		Code: CodeFailed,
		Msg:  msg,
		Data: nil,
	})

	panic(NewRespError("failed"))
}

func FailedResponseEncrypt(c *gin.Context, msg string, encKey []byte) {
	if c == nil {
		return
	}

	if encKey != nil {
		respData, _ := json.Marshal(Response{
			Code: CodeFailed,
			Msg:  msg,
			Data: nil,
		})

		encData, _ := encrypt.AesEncrypt(respData, encKey)
		encDataStr := base64.StdEncoding.EncodeToString(encData)

		c.Data(200, "application/json", []byte(encDataStr))
		panic(NewRespError("failed"))
	}

	c.JSON(http.StatusOK, &Response{
		Code: CodeFailed,
		Msg:  msg,
		Data: nil,
	})

	panic(NewRespError("failed"))
}

func FailedResponseErr(c *gin.Context, err error) {
	if c == nil {
		return
	}

	logrus.Error(err)
	FailedResponse(c, "内部错误")
}

func FailedResponseWithCode(c *gin.Context, code int, msg string) {
	c.JSON(http.StatusOK, &Response{
		Code: code,
		Msg:  msg,
		Data: nil,
	})

	panic(NewRespError("failed"))
}

func SuccessResponse(c *gin.Context, data interface{}) {
	c.JSON(http.StatusOK, &Response{
		Code: CodeSuccess,
		Msg:  "",
		Data: data,
	})

	panic(NewRespError("success"))
}

func SuccessResponseEncrypt(c *gin.Context, data interface{}, encKey []byte) {
	if encKey != nil {
		respData, _ := json.Marshal(Response{
			Code: CodeSuccess,
			Msg:  "",
			Data: data,
		})

		encData, _ := encrypt.AesEncrypt(respData, encKey)
		encDataStr := base64.StdEncoding.EncodeToString(encData)

		c.Data(200, "application/json", []byte(encDataStr))
		panic(NewRespError("failed"))
	}

	c.JSON(http.StatusOK, &Response{
		Code: CodeSuccess,
		Msg:  "",
		Data: data,
	})

	panic(NewRespError("success"))
}
