package user

import (
	"github.com/gin-gonic/gin"

	srvv1 "github.com/pingcap-inc/pchub/internal/apiserver/service/v1"
	"github.com/pingcap-inc/pchub/internal/apiserver/store"
	"github.com/pingcap-inc/pchub/internal/pkg/code"
	"github.com/pingcap-inc/pchub/internal/pkg/middleware"
	modelv1 "github.com/pingcap-inc/pchub/model/v1"
	"github.com/pingcap-inc/pchub/pkg/errors"
	"github.com/pingcap-inc/pchub/pkg/log"
	"github.com/pingcap-inc/pchub/pkg/util/ginres"
)

type UserController struct {
	srv srvv1.Service
}

func NewUserController(store store.Factory) *UserController {
	return &UserController{
		srv: srvv1.NewService(store),
	}
}

func (u *UserController) Search(c *gin.Context) {
	log.L(c).Info("UserController.Search controller function called.")

	params := ginres.ParseQuery(c, "kw")
	if params["kw"] == "" {
		ginres.WriteResponse(c, nil, nil)

		return
	}

	res, err := u.srv.User().Search(c, params["kw"])
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}

	ginres.WriteResponse(c, nil, res)
}

func (u *UserController) JoinFeedbackGroup(c *gin.Context) {
	log.L(c).Info("UserController.JoinFeedbackGroup controller function called.")

	authingId, err := middleware.GetAuthingId(c)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}

	user, err := u.srv.User().GetUserByID(c, authingId)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}

	err = u.srv.User().JoinFeedbackGroup(c, user)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}

	ginres.WriteResponse(c, nil, "ok")
}

func (u *UserController) Get(c *gin.Context) {
	log.L(c).Info("GetUserInfo controller function called.")

	var authTokenInfo middleware.AuthingTokenInfo
	v, ok := c.Get("tokenInfo")
	authTokenInfo, typeOk := v.(middleware.AuthingTokenInfo)
	if !ok || !typeOk {
		ginres.WriteResponse(c, errors.WithCode(code.ErrGetAuthingTokenInfo, ""), nil)

		return
	}

	if authTokenInfo.Uid == "" {
		ginres.WriteResponse(c, errors.WithCode(code.ErrGetAuthingTokenInfo, "%s", "No valid userId from auth middleware"), nil)

		return
	}

	params := ginres.ParseQuery(c, "luid")
	if params["luid"] == "" {
		ginres.WriteResponse(c, errors.WithCode(code.ErrValidation, "Param 'luid' missing"), nil)

		return
	}

	mparams := &modelv1.GetUserInfoParams{
		Luid: params["luid"],
	}
	user, err := u.srv.User().GetUserInfo(c, mparams, authTokenInfo.Uid, authTokenInfo.Email)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}

	ginres.WriteResponse(c, nil, user)
}
