package controller

import (
	commonConstants "nms_nbi/src/framework/constants/common"
	"nms_nbi/src/framework/constants/token"
	"nms_nbi/src/framework/i18n"
	"nms_nbi/src/framework/utils/ctx"
	tokenUtils "nms_nbi/src/framework/utils/token"
	"nms_nbi/src/framework/vo/result"
	commonService "nms_nbi/src/modules/common/service"
	systemService "nms_nbi/src/modules/system/service"

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

// 实例化控制层 SecurityController 结构体
var NewSecurity = &SecurityController{
	accountService:     commonService.NewAccountImpl,
	sysLogLoginService: systemService.NewSysLogLoginImpl,
}

// 安全管理接口
//
// PATH /securityManagement
type SecurityController struct {
	// 账号身份操作服务
	accountService commonService.IAccount
	// 系统登录访问
	sysLogLoginService systemService.ISysLogLogin
}

// 鉴权登录接口
//
// POST /:apiVersion/oauth/token
func (s *SecurityController) OauthTokenLogin(c *gin.Context) {
	var body struct {
		GrantType string `json:"grantType" binding:"required,oneof=password"`
		UserName  string `json:"userName" binding:"required"`
		Value     string `json:"value" binding:"required"`
	}
	if err := c.ShouldBindJSON(&body); err != nil {
		c.JSON(400, map[string]any{})
		return
	}

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

	// 登录用户信息
	loginUser, err := s.accountService.LoginByUsername(body.UserName, body.Value)
	if err != nil {
		c.JSON(400, map[string]any{})
		return
	}

	// 生成令牌，创建系统访问记录
	tokenStr := tokenUtils.Create(&loginUser, ipaddr, location, os, browser)
	if tokenStr == "" {
		c.JSON(400, map[string]any{})
		return
	} else {
		s.accountService.UpdateLoginDateAndIP(&loginUser)
		// 登录成功
		s.sysLogLoginService.CreateSysLogLogin(
			body.UserName, commonConstants.STATUS_YES, "app.common.loginSuccess",
			ipaddr, location, os, browser,
		)
	}

	expires := (loginUser.ExpireTime - loginUser.LoginTime) / 1000
	c.JSON(200, map[string]any{
		token.ACCESS_TOKEN: tokenStr,
		"expires":          expires,
	})
}

// 握手消息接口
//
// POST /:apiVersion/oauth/handshake
func (s *SecurityController) Handshake(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	loginUser, err := ctx.LoginUser(c)
	if err != nil {
		c.JSON(401, result.CodeMsg(401, i18n.TKey(language, err.Error())))
		return
	}

	c.JSON(200, map[string]any{
		"userID": loginUser.UserID,
	})
}

// 退出消息接口
//
// DELETE /:apiVersion/oauth/token
func (s *SecurityController) OauthTokenLogout(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	tokenStr := ctx.Authorization(c)
	if tokenStr != "" {
		// 存在token时记录退出信息
		userName := tokenUtils.Remove(tokenStr)
		if userName != "" {
			// 当前请求信息
			ipaddr, location := ctx.IPAddrLocation(c)
			os, browser := ctx.UaOsBrowser(c)

			// 创建系统访问记录 退出成功
			s.sysLogLoginService.CreateSysLogLogin(
				userName, commonConstants.STATUS_YES, "app.common.logoutSuccess",
				ipaddr, location, os, browser,
			)
		}
	}

	c.JSON(204, result.OkMsg(i18n.TKey(language, "app.common.logoutSuccess")))
}
