package test

import (
	"github.com/gofiber/fiber/v2"
	"gofiber.study.skcks.cn/common/errorx"
	"gofiber.study.skcks.cn/common/response"
	"gofiber.study.skcks.cn/controller/types"
	"gofiber.study.skcks.cn/global"
)

type Controller struct {
	*types.Controller
}

func (c *Controller) GetRouter() fiber.Router {
	return c.Router
}

func NewController(app *fiber.App) *Controller {
	return &Controller{
		Controller: types.NewController(app, "/test"),
	}
}

// JwtEncode jwt token 生成测试
//
// @Summary      jwt token 生成测试
// @Description  jwt token 生成测试
// @Tags         Test
// @Accept       json
// @Produce      json
// @Param        vo	 body	global.UserClaims	true	"userClaims"
// @Success      200  {object}  response.Response{data=string}
// @Failure	     default {object}  errorx.CodeErrorResponse
// @Router       /test/jwt [post]
func (c *Controller) JwtEncode() {
	c.Router.Add(fiber.MethodPost, "/jwt", func(ctx *fiber.Ctx) error {
		claims := global.UserClaims{}
		err := ctx.BodyParser(&claims)

		if err = errorx.ParseError(err); err != nil {
			return ctx.JSON(err)
		}

		token, err := global.GetToken(claims)

		if err = errorx.ParseError(err); err != nil {
			return ctx.JSON(err)
		}

		return ctx.JSON(response.NewResponse(token))
	})
}

// JwtDecode jwt token 解析测试
//
// @Summary      jwt token 解析测试
// @Description  jwt token 解析测试
// @Tags         Test
// @Accept       json
// @Produce      json
// @Param        token    query    string true  "token"
// @Success      200  {object}  response.Response{data=global.UserClaims}
// @Failure	     default {object}  errorx.CodeErrorResponse
// @Router       /test/jwt [get]
func (c *Controller) JwtDecode() {
	c.Router.Add(fiber.MethodGet, "/jwt", func(ctx *fiber.Ctx) error {
		token := ctx.Query("token")
		claims, err := global.ParseToken(token)

		if err = errorx.ParseError(err); err != nil {
			return ctx.JSON(err)
		}

		return ctx.JSON(response.NewResponse(claims))
	})
}

// SonyFlakeTest sonyFlake id 生成测试
//
// @Summary      sonyFlake id 生成测试
// @Description  sonyFlake id 生成测试
// @Tags         Test
// @Accept       json
// @Produce      json
// @Success      200  {object}  response.Response{data=int}
// @Failure	     default {object}  errorx.CodeErrorResponse
// @Router       /test/sonyFlake [get]
func (c *Controller) SonyFlakeTest() {
	c.Router.Add(fiber.MethodGet, "/sonyFlake", func(ctx *fiber.Ctx) error {
		id, err := global.SonyFlake.NextID()

		if err = errorx.ParseError(err); err != nil {
			return ctx.JSON(err)
		}

		return ctx.JSON(response.NewResponse(id))
	})
}

// NanoIdTest nanoid 生成测试
//
// @Summary      nanoid 生成测试
// @Description  nanoid 生成测试
// @Tags         Test
// @Accept       json
// @Produce      json
// @Success      200  {object}  response.Response{data=string}
// @Failure	     default {object}  errorx.CodeErrorResponse
// @Router       /test/nanoid [get]
func (c *Controller) NanoIdTest() {
	c.Router.Add(fiber.MethodGet, "/nanoid", func(ctx *fiber.Ctx) error {
		id, err := global.GetNanoId()

		if err = errorx.ParseError(err); err != nil {
			return ctx.JSON(err)
		}

		return ctx.JSON(response.NewResponse(id))
	})
}

func (c *Controller) GetCaptcha() {
	c.Router.Add(fiber.MethodGet, "/getCaptcha", func(ctx *fiber.Ctx) error {
		id, content, answer := global.Captcha.Driver.GenerateIdQuestionAnswer()
		item, err := global.Captcha.Driver.DrawCaptcha(content)
		err = global.Captcha.Store.Set(id, answer)
		if err != nil {
			return ctx.JSON(errorx.NewDefaultError("验证码生成失败"))
		}

		type resp struct {
			Id   string `json:"id"`
			Data string `json:"captcha"`
		}
		return ctx.JSON(response.NewResponse(resp{
			id,
			item.EncodeB64string(),
		}))
	})
}

func (c *Controller) VerifyCaptcha() {
	c.Router.Add(fiber.MethodPost, "/verifyCaptcha", func(ctx *fiber.Ctx) error {
		id := ctx.Query("id")
		captcha := ctx.Query("captcha")

		verify := global.Captcha.Verify(id, captcha, true)
		if !verify {
			return ctx.JSON(errorx.NewDefaultError("验证码错误"))
		}

		return ctx.JSON(response.NewResponse("验证成功"))
	})
}
