package controller

import (
	"fmt"
	"runtime"

	"be.ems/src/framework/cmd"
	"be.ems/src/framework/constants"
	"be.ems/src/framework/reqctx"
	"be.ems/src/framework/resp"
	"be.ems/src/framework/token"
	"be.ems/src/framework/utils/machine"
	"be.ems/src/modules/auth/service"
	systemService "be.ems/src/modules/system/service"

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

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

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

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

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

	// 登录用户信息
	info := token.UserInfo{
		UserId:      sysUser.UserId,
		DeptId:      sysUser.DeptId,
		User:        sysUser,
		Permissions: []string{constants.SYS_PERMISSION_SYSTEM},
	}

	// 当前请求信息
	ipaddr, location := reqctx.IPAddrLocation(c)
	os, browser := reqctx.UaOsBrowser(c)
	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
	}
	// 记录令牌，创建系统访问记录
	token.UserInfoCreate(&info, deviceFingerprint, [4]string{ipaddr, location, os, browser})
	// 创建系统访问记录
	s.accountService.UpdateLoginDateAndIP(info)

	c.JSON(200, resp.OkData(map[string]any{
		"tokenType":        constants.HEADER_PREFIX,
		"accessToken":      accessToken,
		"expiresIn":        expiresIn,
		"refreshToken":     "",
		"refreshExpiresIn": 0,
		"userId":           info.UserId,
	}))
}

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

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

	// 清除授权信息
	token.UserInfoRemove(reqctx.Authorization(c))
	c.JSON(200, resp.Ok(nil))
}

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

	// 重置数据库
	if runtime.GOOS == "windows" {
		// return fmt.Errorf("not support window")
	} else {
		// 重置数据库
		if _, err := cmd.Exec("/usr/local/etc/omc/script/setup.sh -i"); err != nil {
			c.JSON(200, resp.ErrMsg("setup err"))
			return
		}
		// 重启服务
		if _, err := cmd.Execf("nohup sh -c \"sleep 1s && %s\" > /dev/null 2>&1 &", "sudo systemctl restart omc"); err != nil {
			c.JSON(200, resp.ErrMsg("restart err"))
			return
		}
	}

	// 清除授权信息
	token.UserInfoRemove(reqctx.Authorization(c))
	c.JSON(200, resp.Ok(nil))
}

// 账号变更
//
// PUT /account
func (s *BootloaderController) Account(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)
	var body struct {
		UserName string `json:"username" binding:"required"`
		Password string `json:"password" binding:"required"`
	}
	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
	}

	// 检查用户密码策略强度
	ok, errMsg := s.sysUserService.ValidatePasswordPolicy(body.Password, language)
	if !ok {
		c.JSON(200, resp.ErrMsg(errMsg))
		return
	}
	// if !regular.ValidPassword(body.Password) {
	// 	// 登录密码至少包含大小写字母、数字、特殊符号，且不少于6位
	// 	c.JSON(200, resp.ErrMsg(i18n.TKey(language, "user.errPasswd")))
	// 	return
	// }

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

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