package controller

import (
	"encoding/json"
	"fmt"
	"sort"
	"strings"

	"be.ems/src/framework/constants"
	"be.ems/src/framework/database/redis"
	"be.ems/src/framework/resp"
	"be.ems/src/framework/token"
	"be.ems/src/framework/utils/parse"
	"be.ems/src/modules/monitor/model"
	"be.ems/src/modules/monitor/service"

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

// 实例化控制层 SysUserOnlineController 结构体
var NewSysUserOnline = &SysUserOnlineController{
	sysUserOnlineService: service.NewSysUserOnline,
}

// 在线用户监控
//
// PATH /monitor/online
type SysUserOnlineController struct {
	sysUserOnlineService *service.SysUserOnline // 在线用户服务
}

// 在线用户列表
//
// GET /list
//
//	@Tags			monitor/online
//	@Accept			json
//	@Produce		json
//	@Success		200	{object}	object	"Response Results"
//	@Security		TokenAuth
//	@Summary		System Online User List
//	@Description	System Online User List
//	@Router			/monitor/online/list [get]
func (s *SysUserOnlineController) List(c *gin.Context) {
	loginIp := c.Query("loginIp")
	userName := c.Query("userName")

	// 获取所有在线用户key
	keys, _ := redis.GetKeys("", constants.CACHE_TOKEN_DEVICE+":*")

	// 分批获取
	arr := make([]string, 0)
	for i := 0; i < len(keys); i += 20 {
		end := i + 20
		if end > len(keys) {
			end = len(keys)
		}
		chunk := keys[i:end]
		values, _ := redis.GetBatch("", chunk)
		for _, v := range values {
			arr = append(arr, fmt.Sprint(v))
		}
	}

	// 遍历字符串信息解析组合可用对象
	var userOnlines []model.SysUserOnline
	for _, str := range arr {
		if str == "" {
			continue
		}

		var info token.UserInfo
		err := json.Unmarshal([]byte(str), &info)
		if err != nil {
			continue
		}

		onlineUser := s.sysUserOnlineService.UserInfoToUserOnline(info)
		if onlineUser.TokenID != "" {
			userOnlines = append(userOnlines, onlineUser)
		}
	}

	// 根据查询条件过滤
	filteredUserOnline := make([]model.SysUserOnline, 0)
	if loginIp != "" && userName != "" {
		for _, o := range userOnlines {
			if strings.Contains(o.LoginIp, loginIp) && strings.Contains(o.UserName, userName) {
				filteredUserOnline = append(filteredUserOnline, o)
			}
		}
	} else if loginIp != "" {
		for _, o := range userOnlines {
			if strings.Contains(o.LoginIp, loginIp) {
				filteredUserOnline = append(filteredUserOnline, o)
			}
		}
	} else if userName != "" {
		for _, o := range userOnlines {
			if strings.Contains(o.UserName, userName) {
				filteredUserOnline = append(filteredUserOnline, o)
			}
		}
	} else {
		filteredUserOnline = userOnlines
	}

	// 按登录时间排序
	sort.Slice(filteredUserOnline, func(i, j int) bool {
		return filteredUserOnline[j].LoginTime > filteredUserOnline[i].LoginTime
	})

	c.JSON(200, resp.OkData(map[string]any{
		"total": len(filteredUserOnline),
		"rows":  filteredUserOnline,
	}))
}

// Logout 在线用户强制退出
//
// DELETE /logout/:tokenId
func (s SysUserOnlineController) Logout(c *gin.Context) {
	tokenIdStr := c.Param("tokenId")
	if tokenIdStr == "" || strings.Contains(tokenIdStr, "*") {
		c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_CHEACK, "bind err: tokenId is empty"))
		return
	}

	// 处理字符转id数组后去重
	uniqueIDs := parse.RemoveDuplicatesToArray(tokenIdStr, ",")
	for _, v := range uniqueIDs {
		key := constants.CACHE_TOKEN_DEVICE + ":" + v
		if err := redis.Del("", key); err != nil {
			c.JSON(200, resp.ErrMsg(err.Error()))
			return
		}
	}

	c.JSON(200, resp.Ok(nil))
}
