package response

import (
	"designs/config"
	"designs/global"
	"fmt"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	"go.uber.org/zap"
)

// 500 程序奔溃
func ServerError(c *gin.Context, msg string) {
	errMsg := "服务程序错误"
	if !config.IsProduction() {
		stack := strings.Split(strings.Replace(msg, "\t", "--", -1), "\n")

		c.JSON(http.StatusInternalServerError, gin.H{
			"code":  http.StatusInternalServerError,
			"msg":   errMsg,
			"stack": stack,
		})
	} else {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": http.StatusInternalServerError,
			"msg":  errMsg,
		})
	}

	c.Abort()
}

func Success(c *gin.Context, data gin.H) {
	//for k, v := range data {
	//
	//}
	data["code"] = 0

	//fmt.Println(data)

	c.JSON(http.StatusOK, data)
}

type causer interface {
	Format(s fmt.State, verb rune)
}

func Next(c *gin.Context, resp interface{}) {
	c.JSON(http.StatusOK, resp)
}

func Fail(c *gin.Context, errorCode int, e interface{}) {
	var msg string
	var stack []string
	if _, ok := e.(string); ok {
		msg = e.(string)
	} else if err, ok := e.(error); ok {
		if _, ok := e.(causer); ok {
			msg = strings.Split(fmt.Sprintf("%v", errors.WithStack(err)), ":")[0]
			if !config.IsProduction() {
				tmp := fmt.Sprintf("%+v", errors.WithStack(err))
				stack = strings.Split(strings.Replace(tmp, "\t", "--", -1), "\n")
			}
		} else {
			msg = fmt.Sprintf(err.Error())
			if !config.IsProduction() {
				tmp := fmt.Sprintf("%v", zap.StackSkip("", 1))
				stack = strings.Split(strings.Replace(tmp, "\t", "--", -1), "\n")
			}
		}
	}

	if len(stack) > 0 {
		c.JSON(http.StatusOK, gin.H{
			"code":  errorCode,
			"msg":   msg,
			"stack": stack,
		})
	} else {
		c.JSON(http.StatusOK, gin.H{
			"code": errorCode,
			"msg":  msg,
		})
	}

	c.Abort()
}

func ValidateFail(c *gin.Context, msg string) {
	Fail(c, global.Errors.ValidateError.ErrorCode, msg)
}

// 422 参数错误使用
func ParameterError(c *gin.Context, msg interface{}) {
	finalMsg := "参数错误"
	if err, ok := msg.(error); ok {
		// release 版本屏蔽掉报错
		if !config.IsProduction() {
			finalMsg = err.Error()
		}
	} else if str, ok := msg.(string); ok {
		finalMsg = str
	}

	c.JSON(http.StatusUnprocessableEntity, gin.H{
		"code": http.StatusUnprocessableEntity,
		"msg":  finalMsg,
	})
	c.Abort()
}

// 401 权限错误
func UnauthorizedRequestsFail(c *gin.Context, msg string) {
	//c.JSON(http.StatusUnauthorized, gin.H{
	c.JSON(http.StatusOK, gin.H{
		"code": http.StatusUnauthorized,
		"msg":  msg,
	})
	c.Abort()
}
