package com.CUST.brain.common.cache;

import com.CUST.brain.common.enums.ParamTypeEnum;
import com.CUST.brain.dao.domain.system.SysParam;
import com.CUST.brain.service.SysParamService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Lazy;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 参数缓存管理器
 */
@Component
public class ParamCacheManager {

    @Resource(name = "paramRedisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    @Lazy
    private SysParamService sysParamService;

    private static final String PARAM_CACHE_KEY = "sys:param:type:";
    private static final String PARAM_LIST_CACHE_KEY = "sys:param:list:";

    /**
     * 服务启动时初始化参数缓存
     */
    @PostConstruct
    public void init() {
        // 获取所有参数类型
        List<String> typeCodes = Arrays.stream(ParamTypeEnum.values())
                .map(ParamTypeEnum::getCode)
                .collect(Collectors.toList());

        // 批量获取所有参数
        Map<String, List<SysParam>> paramMap = sysParamService.getParamsByTypes(typeCodes);

        // 更新缓存
        paramMap.forEach(this::cacheParamList);
    }

    /**
     * 缓存参数列表
     */
    public void cacheParamList(String typeCode, List<SysParam> params) {
        if (params != null) {
            redisTemplate.opsForValue().set(PARAM_LIST_CACHE_KEY + typeCode, params);
            
            // 缓存参数Map
            Map<String, String> paramValueMap = params.stream()
                    .collect(Collectors.toMap(
                            SysParam::getParamName,
                            SysParam::getParamValue,
                            (v1, v2) -> v1
                    ));
            redisTemplate.opsForValue().set(PARAM_CACHE_KEY + typeCode, paramValueMap);
        }
    }

    /**
     * 获取参数列表
     */
    @SuppressWarnings("unchecked")
    public List<SysParam> getParamList(String typeCode) {
        Object cached;
        try {
            cached = redisTemplate.opsForValue().get(PARAM_LIST_CACHE_KEY + typeCode);
        } catch (RuntimeException e) {
            // 兼容历史序列化格式不一致导致的反序列化失败
            removeParamCache(typeCode);
            return null;
        }
        if (cached == null) {
            return null;
        }
        if (cached instanceof List) {
            List<?> rawList = (List<?>) cached;
            if (rawList.isEmpty() || rawList.get(0) instanceof SysParam) {
                return (List<SysParam>) cached;
            }
            if (rawList.get(0) instanceof Map) {
                // 兼容历史缓存中以 LinkedHashMap 形式存储的对象
                List<SysParam> converted = new ArrayList<>(rawList.size());
                for (Object item : rawList) {
                    if (!(item instanceof Map)) {
                        continue;
                    }
                    Map<?, ?> map = (Map<?, ?>) item;
                    SysParam p = new SysParam();
                    Object v;
                    if ((v = map.get("paramType")) != null) p.setParamType(String.valueOf(v));
                    if ((v = map.get("paramName")) != null) p.setParamName(String.valueOf(v));
                    if ((v = map.get("paramValue")) != null) p.setParamValue(String.valueOf(v));
                    if ((v = map.get("dataType")) != null) p.setDataType(String.valueOf(v));
                    if ((v = map.get("sortOrder")) != null) p.setSortOrder(v instanceof Number ? ((Number) v).intValue() : null);
                    if ((v = map.get("status")) != null) p.setStatus(v instanceof Number ? ((Number) v).intValue() : null);
                    if ((v = map.get("remark")) != null) p.setRemark(String.valueOf(v));
                    converted.add(p);
                }
                // 回写成强类型，避免后续再转换
                cacheParamList(typeCode, converted);
                return converted;
            }
        }
        // 类型不匹配时直接清理，避免 ClassCastException 重现
        removeParamCache(typeCode);
        return null;
    }

    /**
     * 获取参数Map
     */
    @SuppressWarnings("unchecked")
    public Map<String, String> getParamMap(String typeCode) {
        return (Map<String, String>) redisTemplate.opsForValue().get(PARAM_CACHE_KEY + typeCode);
    }

    /**
     * 删除参数缓存
     */
    public void removeParamCache(String typeCode) {
        redisTemplate.delete(PARAM_LIST_CACHE_KEY + typeCode);
        redisTemplate.delete(PARAM_CACHE_KEY + typeCode);
    }

    /**
     * 删除所有参数缓存
     */
    public void removeAllParamCache() {
        Arrays.stream(ParamTypeEnum.values())
                .map(ParamTypeEnum::getCode)
                .forEach(this::removeParamCache);
        // 兜底：直接删除所有匹配 key，防止新增类型遗漏
        Set<String> keys1 = redisTemplate.keys(PARAM_LIST_CACHE_KEY + "*");
        if (keys1 != null && !keys1.isEmpty()) {
            redisTemplate.delete(keys1);
        }
        Set<String> keys2 = redisTemplate.keys(PARAM_CACHE_KEY + "*");
        if (keys2 != null && !keys2.isEmpty()) {
            redisTemplate.delete(keys2);
        }
    }
} 