package com.common.util;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.LinkedHashMap;
import  java.util.List ;
import java.util.stream.Collectors;

@Component
public class SafeCacheUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 安全的缓存获取方法
     */
    @SuppressWarnings("unchecked")
    public <T> T getSafe(String key, Class<T> clazz, Supplier<T> loader) {
        try {
            Object cached = redisTemplate.opsForValue().get(key);

            if (cached == null) {
                // 缓存不存在，从数据源加载
                T value = loader.get();
                if (value != null) {
                    redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
                }
                return value;
            }

            // 类型匹配，直接返回
            if (clazz.isInstance(cached)) {
                return (T) cached;
            }

            // 类型不匹配，尝试转换
            if (cached instanceof LinkedHashMap) {
                return objectMapper.convertValue(cached, clazz);
            }

            // 无法转换，重新加载
            T value = loader.get();
            if (value != null) {
                redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
            }
            return value;

        } catch (Exception e) {
            // 缓存出错，降级到数据源
            return loader.get();
        }
    }

    /**
     * 安全的列表缓存获取
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> getSafeList(String key, Class<T> elementClass, Supplier<List<T>> loader) {
        try {
            Object cached = redisTemplate.opsForValue().get(key);

            if (cached == null) {
                List<T> value = loader.get();
                if (value != null && !value.isEmpty()) {
                    redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
                }
                return value;
            }

            // 已经是正确的类型
            if (cached instanceof List &&
                    !((List<?>) cached).isEmpty() &&
                    elementClass.isInstance(((List<?>) cached).get(0))) {
                return (List<T>) cached;
            }

            // 需要转换
            if (cached instanceof List) {
                List<LinkedHashMap> rawList = (List<LinkedHashMap>) cached;
                List<T> convertedList = rawList.stream()
                        .map(item -> objectMapper.convertValue(item, elementClass))
                        .collect(Collectors.toList());

                // 更新缓存为正确格式
                redisTemplate.opsForValue().set(key, convertedList, 30, TimeUnit.MINUTES);
                return convertedList;
            }

            // 无法处理，重新加载
            List<T> value = loader.get();
            if (value != null && !value.isEmpty()) {
                redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
            }
            return value;

        } catch (Exception e) {
            return loader.get();
        }
    }
}