package service

import (
	"encoding/json"
	"errors"
	"fmt"

	sysDictDataModel "nms_nbi/features/sys_dict_data/model"
	sysDictDataRepo "nms_nbi/features/sys_dict_data/repo"
	sysDictTypeModel "nms_nbi/features/sys_dict_type/model"
	"nms_nbi/features/sys_dict_type/repo"
	"nms_nbi/lib/core/cache"
	"nms_nbi/lib/core/constants/cachekey"
)

// 实例化服务层 ServiceSysDictType 结构体
var NewServiceSysDictType = &ServiceSysDictType{
	sysDictTypeRepository: *repo.NewRepoSysDictType,
	sysDictDataRepository: *sysDictDataRepo.NewRepoSysDictData,
}

// ServiceSysDictType 字典类型 服务层处理
type ServiceSysDictType struct {
	// 字典类型服务
	sysDictTypeRepository repo.RepoSysDictType
	// 字典数据服务
	sysDictDataRepository sysDictDataRepo.RepoSysDictData
}

// SelectDictTypePage 根据条件分页查询字典类型
func (r *ServiceSysDictType) SelectDictTypePage(query map[string]any) map[string]any {
	return r.sysDictTypeRepository.SelectDictTypePage(query)
}

// SelectDictTypeList 根据条件查询字典类型
func (r *ServiceSysDictType) SelectDictTypeList(sysDictType sysDictTypeModel.SysDictType) []sysDictTypeModel.SysDictType {
	return r.sysDictTypeRepository.SelectDictTypeList(sysDictType)
}

// SelectDictTypeByID 根据字典类型ID查询信息
func (r *ServiceSysDictType) SelectDictTypeByID(dictID string) sysDictTypeModel.SysDictType {
	if dictID == "" {
		return sysDictTypeModel.SysDictType{}
	}
	dictTypes := r.sysDictTypeRepository.SelectDictTypeByIDs([]string{dictID})
	if len(dictTypes) > 0 {
		return dictTypes[0]
	}
	return sysDictTypeModel.SysDictType{}
}

// SelectDictTypeByType 根据字典类型查询信息
func (r *ServiceSysDictType) SelectDictTypeByType(dictType string) sysDictTypeModel.SysDictType {
	return r.sysDictTypeRepository.SelectDictTypeByType(dictType)
}

// CheckUniqueDictName 校验字典名称是否唯一
func (r *ServiceSysDictType) CheckUniqueDictName(dictName, dictID string) bool {
	uniqueId := r.sysDictTypeRepository.CheckUniqueDictType(sysDictTypeModel.SysDictType{
		DictName: dictName,
	})
	if uniqueId == dictID {
		return true
	}
	return uniqueId == ""
}

// CheckUniqueDictType 校验字典类型是否唯一
func (r *ServiceSysDictType) CheckUniqueDictType(dictType, dictID string) bool {
	uniqueId := r.sysDictTypeRepository.CheckUniqueDictType(sysDictTypeModel.SysDictType{
		DictType: dictType,
	})
	if uniqueId == dictID {
		return true
	}
	return uniqueId == ""
}

// InsertDictType 新增字典类型信息
func (r *ServiceSysDictType) InsertDictType(sysDictType sysDictTypeModel.SysDictType) string {
	insertId := r.sysDictTypeRepository.InsertDictType(sysDictType)
	if insertId != "" {
		r.LoadingDictCache(sysDictType.DictType)
	}
	return insertId
}

// UpdateDictType 修改字典类型信息
func (r *ServiceSysDictType) UpdateDictType(sysDictType sysDictTypeModel.SysDictType) int64 {
	data := r.sysDictTypeRepository.SelectDictTypeByIDs([]string{sysDictType.DictID})
	if len(data) == 0 {
		return 0
	}
	// 修改字典类型key时同步更新其字典数据的类型key
	oldDictType := data[0].DictType
	rows := r.sysDictTypeRepository.UpdateDictType(sysDictType)
	if rows > 0 && oldDictType != "" && oldDictType != sysDictType.DictType {
		r.sysDictDataRepository.UpdateDictDataType(oldDictType, sysDictType.DictType)
	}
	// 刷新缓存
	r.ClearDictCache(oldDictType)
	r.LoadingDictCache(sysDictType.DictType)
	return rows
}

// DeleteDictTypeByIDs 批量删除字典类型信息
func (r *ServiceSysDictType) DeleteDictTypeByIDs(dictIDs []string) (int64, error) {
	// 检查是否存在
	dictTypes := r.sysDictTypeRepository.SelectDictTypeByIDs(dictIDs)
	if len(dictTypes) <= 0 {
		return 0, errors.New("no permission to access dictionary type data")
	}
	for _, v := range dictTypes {
		// 字典类型下级含有数据
		useCount := r.sysDictDataRepository.CountDictDataByType(v.DictType)
		if useCount > 0 {
			msg := fmt.Sprintf("[%s] Dictionary data exists and cannot be deleted. ", v.DictName)
			return 0, errors.New(msg)
		}
		// 清除缓存
		r.ClearDictCache(v.DictType)
	}
	if len(dictTypes) == len(dictIDs) {
		rows := r.sysDictTypeRepository.DeleteDictTypeByIDs(dictIDs)
		return rows, nil
	}
	return 0, errors.New("failed to delete dictionary data information")
}

// ResetDictCache 重置字典缓存数据
func (r *ServiceSysDictType) ResetDictCache() {
	r.ClearDictCache("*")
	r.LoadingDictCache("")
}

// getCacheKey 组装缓存key
func (r *ServiceSysDictType) getDictCache(dictType string) string {
	return cachekey.SYS_DICT_KEY + dictType
}

// LoadingDictCache 加载字典缓存数据
func (r *ServiceSysDictType) LoadingDictCache(dictType string) {
	sysDictData := sysDictDataModel.SysDictData{
		Status: "1",
	}

	// 指定字典类型
	if dictType != "" {
		sysDictData.DictType = dictType
		// 删除缓存
		key := r.getDictCache(dictType)
		cache.DeleteLocal(key)
	}

	sysDictDataList := r.sysDictDataRepository.SelectDictDataList(sysDictData)
	if len(sysDictDataList) == 0 {
		return
	}

	// 将字典数据按类型分组
	m := make(map[string][]sysDictDataModel.SysDictData, 0)
	for _, v := range sysDictDataList {
		key := v.DictType
		if item, ok := m[key]; ok {
			m[key] = append(item, v)
		} else {
			m[key] = []sysDictDataModel.SysDictData{v}
		}
	}

	// 放入缓存
	for k, v := range m {
		key := r.getDictCache(k)
		values, _ := json.Marshal(v)
		cache.SetLocal(key, string(values))
	}
}

// ClearDictCache 清空字典缓存数据
func (r *ServiceSysDictType) ClearDictCache(dictType string) bool {
	key := r.getDictCache(dictType)
	keys := cache.GetLocalKeys(key)
	for _, v := range keys {
		cache.DeleteLocal(v)
	}
	return len(keys) > 0
}

// DictDataCache 获取字典数据缓存数据
func (r *ServiceSysDictType) DictDataCache(dictType string) []sysDictDataModel.SysDictData {
	data := []sysDictDataModel.SysDictData{}
	key := r.getDictCache(dictType)
	jsonAny, ok := cache.GetLocal(key)
	if jsonAny != nil && ok {
		err := json.Unmarshal([]byte(jsonAny.(string)), &data)
		if err != nil {
			data = []sysDictDataModel.SysDictData{}
		}
	} else {
		data = r.sysDictDataRepository.SelectDictDataList(sysDictDataModel.SysDictData{
			Status:   "1",
			DictType: dictType,
		})
		if len(data) > 0 {
			cache.DeleteLocal(key)
			values, _ := json.Marshal(data)
			cache.SetLocal(key, string(values))
		}
	}
	return data
}
