package router

import (
	"errors"
	"sync/atomic"

	"github.com/go-playground/validator/v10"
	"github.com/gorilla/websocket"
	jsoniter "github.com/json-iterator/go"
	"github.com/sirupsen/logrus"
	"gogs.daxia.dev/huanan/pkg.daxia.dev/validate_utils"
	"nn.daxia.dev/model"
)

var validate = validator.New()
var uniqueIndex = int64(1)

type HandleFunc func(*websocket.Conn, []byte, map[string]interface{}) error

// 校验登录信息
func GameAuthMiddleware(conn *websocket.Conn, message []byte, handleFunc HandleFunc) (map[string]interface{}, error) {
	type GameAuth struct {
		Token string `json:"token" validate:"required"`
		Once  string `json:"once" validate:"required"`
	}

	ctx := map[string]interface{}{
		"userModel": nil,
	}

	err := func() error {
		gameAuth := GameAuth{}
		err := jsoniter.Unmarshal(message, &gameAuth)
		if err != nil {
			return err
		}

		err = validate.Struct(&gameAuth)
		if err != nil {
			errStr := validate_utils.SetErrorStr(err, func(tag string) string {
				switch tag {
				case "Token.required":
					return "Token不能为空"
				}

				return "内部错误"
			})

			return errors.New(errStr(0))
		}

		userToken := gameAuth.Token

		userModel := model.User{}
		var valid bool

		if valid, err = userModel.TokenIsValid(userToken); err != nil {
			logrus.Error(err)
			return errors.New("internel error")
		}

		if !valid {
			logrus.Errorf("权限检测不通过:%d, err:%v", userModel.ID, err)

			return errors.New("internel error")
		}

		ctx["userModel"] = userModel
		ctx["once"] = gameAuth.Once
		ctx["unique_index"] = atomic.AddInt64(&uniqueIndex, 1)

		logrus.Infof("权限检测通过, userID:%d", userModel.ID)

		return nil
	}()

	if err != nil {
		logrus.Errorf("check auth error:%v", err)

		conn.Close()
		return nil, err
	}

	userModel := ctx["userModel"].(model.User)
	logrus.Infof("finish auth: %d, handle func:%v", userModel.ID, handleFunc)

	return ctx, handleFunc(conn, message, ctx)
}
