package controller

import (
	adminConstants "be.ems/src/framework/constants/admin"
	"be.ems/src/framework/constants/common"
	tokenConstants "be.ems/src/framework/constants/token"
	"be.ems/src/framework/i18n"
	"be.ems/src/framework/utils/ctx"
	"be.ems/src/framework/utils/machine"
	"be.ems/src/framework/utils/regular"
	tokenUtils "be.ems/src/framework/utils/token"
	"be.ems/src/framework/vo"
	"be.ems/src/framework/vo/result"
	commonService "be.ems/src/modules/common/service"
	systemService "be.ems/src/modules/system/service"
	"github.com/gin-gonic/gin"
)

// 实例化控制层 BootloaderController 结构体
var NewBootloader = &BootloaderController{
	accountService: commonService.NewAccount,
	sysUserService: systemService.NewSysUserImpl,
}

// 系统引导初始化
//
// PATH /bootloader
type BootloaderController struct {
	accountService *commonService.Account // 账号身份操作服务
	// 用户信息服务
	sysUserService systemService.ISysUser
}

// 首次引导开始
//
// POST /
func (s *BootloaderController) Start(c *gin.Context) {
	// 是否完成引导
	launchInfo := machine.LaunchInfo
	if launchInfo == nil {
		c.JSON(200, result.Err(nil))
		return
	}
	if v, ok := launchInfo[common.LAUNCH_BOOTLOADER]; ok && !v.(bool) {
		c.JSON(200, result.ErrMsg("bootloader done"))
		return
	}

	// 查询用户登录账号
	sysUser := s.sysUserService.SelectUserById("1")
	if sysUser.UserID != "1" {
		c.JSON(200, result.ErrMsg("not found user data"))
		return
	}

	// 登录用户信息
	loginUser := vo.LoginUser{
		UserID:      sysUser.UserID,
		DeptID:      sysUser.DeptID,
		User:        sysUser,
		Permissions: []string{adminConstants.PERMISSION},
	}

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

	// 生成令牌，创建系统访问记录
	tokenStr := tokenUtils.Create(&loginUser, ipaddr, location, os, browser)
	if tokenStr == "" {
		c.JSON(200, result.Err(nil))
		return
	} else {
		s.accountService.UpdateLoginDateAndIP(&loginUser)
	}

	c.JSON(200, result.OkData(map[string]any{
		tokenConstants.RESPONSE_FIELD: tokenStr,
	}))
}

// 首次引导完成
//
// PUT /
func (s *BootloaderController) Done(c *gin.Context) {
	// 是否完成引导
	launchInfo := machine.LaunchInfo
	if launchInfo == nil {
		c.JSON(200, result.Err(nil))
		return
	}
	if v, ok := launchInfo[common.LAUNCH_BOOTLOADER]; ok && !v.(bool) {
		c.JSON(200, result.ErrMsg("bootloader done"))
		return
	}

	// 标记引导完成
	if err := machine.Bootloader(false); err != nil {
		c.JSON(200, result.ErrMsg(err.Error()))
		return
	}

	// 清除授权信息
	tokenUtils.Remove(ctx.Authorization(c))
	c.JSON(200, result.Ok(nil))
}

// 引导系统数据重置
//
// DELETE /
func (s *BootloaderController) Reset(c *gin.Context) {
	// 是否完成引导
	launchInfo := machine.LaunchInfo
	if launchInfo == nil {
		c.JSON(200, result.Err(nil))
		return
	}
	if v, ok := launchInfo[common.LAUNCH_BOOTLOADER]; ok && v.(bool) {
		c.JSON(200, result.ErrMsg("bootloader not done"))
		return
	}

	if err := machine.Reset(); err != nil {
		c.JSON(200, result.ErrMsg(err.Error()))
		return
	}

	// 清除授权信息
	tokenUtils.Remove(ctx.Authorization(c))
	c.JSON(200, result.Ok(nil))
}

// 账号变更
//
// PUT /account
func (s *BootloaderController) Account(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	var body struct {
		UserName string `json:"username" binding:"required"`
		Password string `json:"password" binding:"required"`
	}
	if err := c.ShouldBindJSON(&body); err != nil {
		c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
		return
	}

	if !regular.ValidPassword(body.Password) {
		// 登录密码至少包含大小写字母、数字、特殊符号，且不少于6位
		c.JSON(200, result.ErrMsg(i18n.TKey(language, "user.errPasswd")))
		return
	}

	// 是否完成引导
	launchInfo := machine.LaunchInfo
	if launchInfo == nil {
		c.JSON(200, result.Err(nil))
		return
	}
	if v, ok := launchInfo[common.LAUNCH_BOOTLOADER]; ok && !v.(bool) {
		c.JSON(200, result.ErrMsg("bootloader done"))
		return
	}

	// 查询用户登录账号
	sysUser := s.sysUserService.SelectUserById("2")
	if sysUser.UserID != "2" {
		c.JSON(200, result.ErrMsg("not found user data"))
		return
	}
	sysUser.UserName = body.UserName
	sysUser.NickName = body.UserName
	sysUser.Password = body.Password
	sysUser.UpdateBy = ctx.LoginUserToUserName(c)
	rows := s.sysUserService.UpdateUser(sysUser)
	if rows > 0 {
		c.JSON(200, result.Ok(nil))
		return
	}
	c.JSON(200, result.Err(nil))
}
