package controller

import (
	"fmt"

	"be.ems/src/framework/constants"
	"be.ems/src/framework/i18n"
	"be.ems/src/framework/reqctx"
	"be.ems/src/framework/resp"
	"be.ems/src/framework/token"
	"be.ems/src/modules/auth/model"

	"github.com/gin-gonic/gin"
)

// OAuth2CodeURL OAuth2认证跳转登录URL
//
// GET /auth/login/oauth2/authorize
//
//	@Tags			common/authorization
//	@Accept			json
//	@Produce		json
//	@Param			data	body		object	true	"Request Param"
//	@Success		200		{object}	object	"Response Results"
//	@Summary		System Login
//	@Description	System Login
//	@Router			/auth/login/oauth2/authorize [get]
func (s AccountController) OAuth2CodeURL(c *gin.Context) {
	state := c.Query("state")
	if state == "" {
		c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: state is empty"))
		return
	}

	redirectURL, err := s.accountService.ByOAuth2CodeURL(state)
	if err != nil {
		c.JSON(200, resp.ErrMsg(err.Error()))
		return
	}
	c.Redirect(302, redirectURL)
}

// OAuth2 OAuth2认证登录
//
// POST /auth/login/oauth2/token
//
//	@Tags			common/authorization
//	@Accept			json
//	@Produce		json
//	@Param			data	body		object	true	"Request Param"
//	@Success		200		{object}	object	"Response Results"
//	@Summary		System Login
//	@Description	System Login
//	@Router			/auth/login/oauth2/token [post]
func (s AccountController) OAuth2Token(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)
	var body model.LoginSourceOauth2Body
	if err := c.ShouldBindJSON(&body); err != nil {
		errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
		c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
		return
	}

	// 当前请求信息
	ipaddr, location := reqctx.IPAddrLocation(c)
	os, browser := reqctx.UaOsBrowser(c)

	// 登录用户信息
	info, err := s.accountService.ByOAuth2(body)
	if err != nil {
		s.sysLogLoginService.Insert(
			body.State, constants.STATUS_NO, err.Error(),
			[4]string{ipaddr, location, os, browser},
		)
		c.JSON(200, resp.ErrMsg(i18n.TKey(language, err.Error())))
		return
	}

	data := map[string]any{}

	deviceFingerprint := reqctx.DeviceFingerprint(c, info.UserId)

	// 生成访问令牌
	accessToken, expiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "access")
	if accessToken == "" || expiresIn == 0 {
		c.JSON(200, resp.ErrMsg("token generation failed"))
		return
	}
	// 生成刷新令牌
	refreshToken, refreshExpiresIn := token.UserTokenCreate(info.UserId, deviceFingerprint, "refresh")

	// 记录令牌，创建系统访问记录
	token.UserInfoCreate(&info, deviceFingerprint, [4]string{ipaddr, location, os, browser})
	s.accountService.UpdateLoginDateAndIP(info)
	s.sysLogLoginService.Insert(
		body.State, constants.STATUS_YES, "app.common.loginSuccess",
		[4]string{ipaddr, location, os, browser},
	)

	data["tokenType"] = constants.HEADER_PREFIX
	data["accessToken"] = accessToken
	data["expiresIn"] = expiresIn
	data["refreshToken"] = refreshToken
	data["refreshExpiresIn"] = refreshExpiresIn
	data["userId"] = info.UserId
	c.JSON(200, resp.OkData(data))
}
