package controller

import (
	"be.ems/src/framework/constants/cachekey"
	"be.ems/src/framework/i18n"
	"be.ems/src/framework/redis"
	"be.ems/src/framework/utils/ctx"
	"be.ems/src/framework/vo/result"
	"be.ems/src/modules/monitor/model"

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

// 实例化控制层 SysCacheController 结构体
var NewSysCache = &SysCacheController{}

// 缓存监控信息
//
// PATH /monitor/cache
type SysCacheController struct{}

// Redis信息
//
// GET /
func (s *SysCacheController) Info(c *gin.Context) {
	c.JSON(200, result.OkData(map[string]any{
		"info":         redis.Info(""),
		"dbSize":       redis.KeySize(""),
		"commandStats": redis.CommandStats(""),
	}))
}

// 缓存名称列表
//
// GET /getNames
func (s *SysCacheController) Names(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	caches := []model.SysCache{
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.user"), cachekey.LOGIN_TOKEN_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.sys_config"), cachekey.SYS_CONFIG_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.sys_dict"), cachekey.SYS_DICT_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.captcha_codes"), cachekey.CAPTCHA_CODE_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.repeat_submit"), cachekey.REPEAT_SUBMIT_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.rate_limit"), cachekey.RATE_LIMIT_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.pwd_err_cnt"), cachekey.PWD_ERR_CNT_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.ne_info"), cachekey.NE_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.ne_data"), cachekey.NE_DATA_KEY),
	}
	c.JSON(200, result.OkData(caches))
}

// 缓存名称下键名列表
//
// GET /getKeys/:cacheName
func (s *SysCacheController) Keys(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	cacheName := c.Param("cacheName")
	if cacheName == "" {
		c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
		return
	}
	caches := []model.SysCache{}

	// 遍历组装
	cacheKeys, _ := redis.GetKeys("", cacheName+":*")
	for _, key := range cacheKeys {
		caches = append(caches, model.NewSysCacheKeys(cacheName, key))
	}

	c.JSON(200, result.OkData(caches))
}

// 缓存内容
//
// GET /getValue/:cacheName/:cacheKey
func (s *SysCacheController) Value(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	cacheName := c.Param("cacheName")
	cacheKey := c.Param("cacheKey")
	if cacheName == "" || cacheKey == "" {
		c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
		return
	}

	cacheValue, err := redis.Get("", cacheName+":"+cacheKey)
	if err != nil {
		c.JSON(200, result.ErrMsg(err.Error()))
		return
	}
	sysCache := model.NewSysCacheValue(cacheName, cacheKey, cacheValue)
	c.JSON(200, result.OkData(sysCache))
}

// 删除缓存名称下键名列表
//
// DELETE /clearCacheName/:cacheName
func (s *SysCacheController) ClearCacheName(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	cacheName := c.Param("cacheName")
	if cacheName == "" {
		c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
		return
	}

	cacheKeys, err := redis.GetKeys("", cacheName+":*")
	if err != nil {
		c.JSON(200, result.ErrMsg(err.Error()))
		return
	}
	ok, _ := redis.DelKeys("", cacheKeys)
	if ok {
		c.JSON(200, result.Ok(nil))
		return
	}
	c.JSON(200, result.Err(nil))
}

// 删除缓存键名
//
// DELETE /clearCacheKey/:cacheName/:cacheKey
func (s *SysCacheController) ClearCacheKey(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	cacheName := c.Param("cacheName")
	cacheKey := c.Param("cacheKey")
	if cacheName == "" || cacheKey == "" {
		c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
		return
	}

	ok, _ := redis.Del("", cacheName+":"+cacheKey)
	if ok {
		c.JSON(200, result.Ok(nil))
		return
	}
	c.JSON(200, result.Err(nil))
}

// 安全清理缓存名称
//
// DELETE /clearCacheSafe
func (s *SysCacheController) ClearCacheSafe(c *gin.Context) {
	language := ctx.AcceptLanguage(c)
	caches := []model.SysCache{
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.user"), cachekey.LOGIN_TOKEN_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.sys_config"), cachekey.SYS_CONFIG_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.sys_dict"), cachekey.SYS_DICT_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.captcha_codes"), cachekey.CAPTCHA_CODE_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.repeat_submit"), cachekey.REPEAT_SUBMIT_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.rate_limit"), cachekey.RATE_LIMIT_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.pwd_err_cnt"), cachekey.PWD_ERR_CNT_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.ne_info"), cachekey.NE_KEY),
		model.NewSysCacheNames(i18n.TKey(language, "cache.name.ne_data"), cachekey.NE_DATA_KEY),
	}
	for _, v := range caches {
		cacheKeys, err := redis.GetKeys("", v.CacheName+":*")
		if err != nil {
			continue
		}
		redis.DelKeys("", cacheKeys)
	}
	c.JSON(200, result.Ok(nil))
}
