package controllers

import (
	"github.com/gogf/gf/v2/net/ghttp"
	"yx-dataset-server/app/bll"
	"yx-dataset-server/app/schema"
	"yx-dataset-server/library/gplus"
	"yx-dataset-server/library/logger"
)

func NewLogin(
	bLogin bll.ILogin,
	bVerify bll.IVerifyCode,
	bUser bll.IUser,
) *Login {
	return &Login{
		bLogin:  bLogin,
		bVerify: bVerify,
		bUser:   bUser,
	}
}

type Login struct {
	bLogin  bll.ILogin
	bVerify bll.IVerifyCode
	bUser   bll.IUser
}

// Login 用户登录
// @Summary 用户登录
// @Param body schema.LoginParam true
// @Success 200 schema.LoginTokenInfo "{access_token:访问令牌,token_type:令牌类型,expires_in:过期时长(单位秒)}"
// @Failure 400 schema.HTTPError "{error:{code:0,message:无效的请求参数}}"
// @Failure 500 schema.HTTPError "{error:{code:0,message:服务器错误}}"
// @Router POST /api/v1/login
func (a *Login) Login(r *ghttp.Request) {
	var item schema.LoginParam
	ctx := gplus.NewContext(r)
	if err := gplus.ParseJson(r, &item); err != nil {
		ResError(r, err)
		return
	}

	user, err := a.bLogin.Verify(ctx, item.UserName, item.Password)
	if err != nil {
		ResError(r, err)
		return
	}
	// 将用户ID放入上下文
	gplus.SetUserId(r, user.RecordID)

	tokenInfo, err := a.bLogin.GenerateToken(ctx, user.RecordID)
	if err != nil {
		ResError(r, err)
		return
	}
	logger.StartSpan(gplus.NewContext(r), logger.SetSpanTitle("用户登录"), logger.SetSpanFuncName("Login")).Infof(ctx, "登入系统")
	ResSuccess(r, tokenInfo)
}

// Logout 用户登出
// @Summary 用户登出
// @Success 200 schema.HTTPStatus "{status:OK}"
// @Router POST /api/v1/login/exit
func (a *Login) Logout(r *ghttp.Request) {
	// 检查用户是否处于登录状态，如果是则执行销毁
	userID := gplus.GetUserID(r)
	ctx := gplus.NewContext(r)
	if userID != "" {
		err := a.bLogin.DestroyToken(ctx, gplus.GetToken(r))
		if err != nil {
			logger.Errorf(ctx, err.Error())
		}
		logger.StartSpan(gplus.NewContext(r), logger.SetSpanTitle("用户登出"), logger.SetSpanFuncName("Logout")).Infof(ctx, "登出系统")
	}
	ResSuccess(r, nil)
}

// RefreshToken 刷新令牌
func (a *Login) RefreshToken(r *ghttp.Request) {
	ctx := gplus.NewContext(r)

	token, err := a.bLogin.RefreshToken(ctx)
	if err != nil {
		ResError(r, err)
	}
	ResSuccess(r, token)
}

// GetUserInfo 获取当前用户信息
// @Router GET /web/v1/current/user
func (a *Login) GetUserInfo(r *ghttp.Request) {
	ctx := gplus.NewContext(r)
	userId := gplus.GetUserID(r)
	info, err := a.bUser.GetCurrentUser(ctx, userId)
	if err != nil {
		ResError(r, err)
		return
	}
	ResSuccess(r, info)
}
