package org.jeecg.common.util;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.jeecg.common.api.CommonAPI;
import org.jeecg.common.aspect.annotation.Dict;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.util.ConcurrentReferenceHashMap;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
@Log4j2
public class DictAnnotationUtil {
    // 缓存字典项（Key: dictCode, Value: Map<itemValue, itemText>）




    private static final ConcurrentMap<String, Map<String, String>> DICT_CACHE =
            new ConcurrentReferenceHashMap<>(512);

    // Spring CacheManager（用于二级缓存，如Redis）
    private static CacheManager cacheManager;


    private static CommonAPI commonAPI;

    /**
     * 注入CacheManager（需在Spring容器初始化后调用）
     */
    public static void setCacheManager(CacheManager manager) {
        cacheManager = manager;
    }
    public static void setCommonAPI(CommonAPI common) {
        commonAPI = common;
    }

    /**
     * 批量翻译集合中的字典字段
     */
    public static void translateDictList(Collection<?> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        System.out.println(JSONObject.toJSONString(list));
        try {
            list.forEach(DictAnnotationUtil::translateDict);
        } catch (Exception e) {
            // 生产环境打印警告日志，避免中断主流程
            log.warn("字典翻译异常: {}", e.getMessage());
        }
    }

    /**
     * 翻译单个对象的字典字段
     */
    public  static void translateDict(Object obj) {
        if (obj == null) return;

        System.out.println(JSONObject.toJSONString(obj));
        Class<?> clazz = obj.getClass();
        // 缓存类字段信息，避免重复反射
        Field[] fields = getCachedFields(clazz);

        for (Field field : fields) {
            Dict dictAnnotation = field.getAnnotation(Dict.class);
            if (dictAnnotation == null) continue;

            try {
                String dictCode = dictAnnotation.dicCode();
                Object fieldValue = FieldUtils.readField(field, obj, true);
                if (fieldValue == null) continue;

                // 获取字典文本
                String dictText = getDictText(dictCode, String.valueOf(fieldValue));
                if (dictText == null) continue;

                // 写入目标字段
                String targetField = field.getName() + "_dictText";
                FieldUtils.writeField(obj, targetField, dictText, true);
            } catch (Exception e) {
                log.warn("字段翻译失败: {}.{}", clazz.getSimpleName(), field.getName());
            }
        }
    }

    /**
     * 获取字典文本（多级缓存策略）
     */
    private static String getDictText(String dictCode, String itemValue) {
        // 1. 优先从本地缓存查询
        Map<String, String> dictMap = DICT_CACHE.get(dictCode);
        if (dictMap != null && dictMap.containsKey(itemValue)) {
            return dictMap.get(itemValue);
        }

        // 2. 从Redis等分布式缓存查询
        if (cacheManager != null) {
            Cache cache = cacheManager.getCache("dictCache");
            if (cache != null) {
                String cacheKey = dictCode + ":" + itemValue;
                String cachedText = cache.get(cacheKey, String.class);
                if (cachedText != null) {
                    return cachedText;
                }
            }
        }

        // 3. 从数据库查询并更新缓存
        String dictText = queryFromDatabase(dictCode, itemValue);
        if (dictText != null) {
            updateCache(dictCode, itemValue, dictText);
        }
        return dictText;
    }

    /**
     * 从数据库查询字典项
     */
    private static String queryFromDatabase(String dictCode, String itemValue) {
        // 伪代码：实际需替换为MyBatis/JDBC查询

        return commonAPI.selectDictText(dictCode, itemValue);
    }

    /**
     * 更新多级缓存
     */
    private static void updateCache(String dictCode, String itemValue, String itemText) {
        // 更新本地缓存
        DICT_CACHE.computeIfAbsent(dictCode, k -> new HashMap<>())
                .put(itemValue, itemText);

        // 更新分布式缓存
        if (cacheManager != null) {
            Cache cache = cacheManager.getCache("dictCache");
            if (cache != null) {
                cache.put(dictCode + ":" + itemValue, itemText);
            }
        }
    }

    /**
     * 缓存类字段信息（减少反射开销）
     */
    private static final Map<Class<?>, Field[]> FIELD_CACHE = new ConcurrentReferenceHashMap<>();
    private static Field[] getCachedFields(Class<?> clazz) {
        return FIELD_CACHE.computeIfAbsent(clazz, FieldUtils::getAllFields);
    }
}
