package system

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"hongze/fms_api/global"
	"hongze/fms_api/models/system"
	"hongze/fms_api/utils"
	"strconv"
	"time"
)

func Login(adminName, password string, isRemember bool) (ret system.LoginResp, err error, errMsg string) {
	//查询管理员账号是否存在
	admin := new(system.SysAdmin)
	adminInfo, err := admin.GetAdminByAdminName(adminName)
	if err != nil {
		if err == utils.ErrNoRow {
			errMsg = "登录失败,账号错误"
			err = errors.New(errMsg + "Err:" + err.Error())
			return
		}
		errMsg = "登录失败,查询账号出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	//查询密码是否匹配
	if adminInfo.Password != password {
		errMsg = "登录失败,密码错误"
		err = errors.New(errMsg)
		return
	}
	//查询账号是否有效
	if adminInfo.Enabled == 0 {
		errMsg = "您的账号已被禁用,如需登录,请联系管理员"
		err = errors.New(errMsg + "已禁用账号:" + adminInfo.AdminName + " " + adminInfo.RealName)
		return
	}
	//生成token
	token, err := utils.GenToken(strconv.Itoa(int(adminInfo.AdminId)) + adminInfo.AdminName)
	if err != nil {
		errMsg = "登录失败,生成token出错"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	//新增session记录
	sysSession := new(system.LoginTokenContent)
	sysSession.AdminId = adminInfo.AdminId
	sysSession.Password = adminInfo.Password
	sysSession.IsRemember = isRemember

	tokenStr, _ := json.Marshal(sysSession)
	//将session保存到redis当中
	global.Redis.SetEX(context.TODO(), utils.SYSTEM_LOGIN_TOKEN+token, tokenStr, 120*time.Minute)

	// 获取不可信的登录态,并将该登录态重置掉,不允许多次登录
	noTrustLoginKey := fmt.Sprint(utils.SYSTEM_LOGIN_TOKEN_NO_TRUST, adminInfo.AdminId)
	noTrustLoginToken, _ := global.Redis.Get(context.TODO(), noTrustLoginKey).Result()
	if noTrustLoginToken != `` { // 如果存在不可信设备,那么将其下架
		global.Redis.Del(context.TODO(), utils.SYSTEM_LOGIN_TOKEN+noTrustLoginToken)
	}

	// 如果当前是不可信设备,那么将其加入到不可信名单
	if !isRemember {
		noTrustLoginKey := fmt.Sprint(utils.SYSTEM_LOGIN_TOKEN_NO_TRUST, adminInfo.AdminId)
		global.Redis.Set(context.TODO(), noTrustLoginKey, token, 120*time.Minute)
	}

	//更新用户的最新登录时间
	adminInfo.LastLoginTime = time.Now()
	err = adminInfo.Update([]string{"last_login_time"})
	if err != nil {
		errMsg = "更新登录信息失败"
		err = errors.New(errMsg + "Err:" + err.Error())
		return
	}
	ret.AdminName = adminInfo.AdminName
	ret.RealName = adminInfo.RealName
	ret.AdminId = adminInfo.AdminId
	ret.Token = token
	if password == utils.DefaultPwd {
		ret.ChangePwd = true
	}
	return
}