package com.crm.rely.backend.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * 缓存切面配置类。
 */
@Slf4j
@Aspect
@Component
public class CacheAspect {
//
//    private static final long CACHE_EXPIRY_MILLISECONDS = 60 * 1000;
//
//    @Autowired
//    private RedisService redisService;
//
//    /**
//     * 定义切点：拦截 Mapper 和 Repository 层的方法。
//     */
//    @Pointcut("execution(* com.crm.*.dao.mapper.*.*(..)) || execution(* com.crm.*.dao.repository.*.*(..))")
//
//    public void daoLayer() {
//    }
//
//    /**
//     * 环绕通知：处理缓存逻辑。
//     */
//    @Around("daoLayer()")
//    public Object cacheHandler(ProceedingJoinPoint joinPoint) throws Throwable {
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        Method method = signature.getMethod();
//        Object[] args = joinPoint.getArgs();
//
//        String methodName = method.getName();
//        Class<?> returnType = method.getReturnType();
//
//        if (isQueryMethod(methodName)) {
//            return handleCacheQuery(joinPoint, method, args, returnType);
//        } else if (isModifyMethod(methodName)) {
//            return handleCacheModification(joinPoint, args);
//        }
//
//        return joinPoint.proceed();
//    }
//
//    /**
//     * 查询逻辑处理。
//     */
//    private Object handleCacheQuery(ProceedingJoinPoint joinPoint, Method method, Object[] args, Class<?>
//            returnType) throws Throwable {
//        String cacheKey = generateCacheKeyForQuery(method, args);
//
//        try {
//            if (List.class.isAssignableFrom(returnType)) {
//                Class<?> elementType = getGenericReturnType(method); // 获取列表的泛型类型
//                if (elementType != null) {
//                    List<?> cachedList = redisService.getList(cacheKey, elementType);
//                    if (cachedList != null) {
//                        log.info("Cache hit for key: {}", cacheKey);
//                        return cachedList;
//                    }
//                }
//            } else {
//                Object cachedEntity = redisService.getEntity(cacheKey, returnType);
//                if (cachedEntity != null) {
//                    log.info("Cache hit for key: {}", cacheKey);
//                    return cachedEntity;
//                }
//            }
//        } catch (Exception e) {
//            log.warn("Failed to retrieve or deserialize cache for key: {}, proceeding with DB call. Error: {}",
//                    cacheKey, e);
//        }
//
//        Object result = joinPoint.proceed();
//
//        try {
//            redisService.save(cacheKey, result, CACHE_EXPIRY_MILLISECONDS);
//            log.info("Cache saved for key: {} with expiry {} milliseconds", cacheKey, CACHE_EXPIRY_MILLISECONDS);
//        } catch (Exception e) {
//            log.warn("Failed to save cache for key: {}", cacheKey, e);
//        }
//
//        return result;
//    }
//
//
//    /**
//     * 增删改逻辑处理。
//     */
//    private Object handleCacheModification(ProceedingJoinPoint joinPoint, Object[] args) throws Throwable {
//
//        // 生成所有相关的缓存键
//        List<String> affectedKeys = generateCacheKeysForModification(args);
//
//        // 清理通配符键
//        for (String key : affectedKeys) {
//            try {
//                redisService.remove(key);
//                log.info("Cache evicted for key: {}", key);
//            } catch (Exception e) {
//                log.warn("Failed to evict cache for key: {}", key, e);
//            }
//        }
//
//        // 执行原始方法
//        Object result = joinPoint.proceed();
//
//        // 再次清理缓存键，防止修改方法的延迟生效导致不一致
//        for (String key : affectedKeys) {
//            try {
//                redisService.remove(key);
//                log.info("Cache evicted post execution for key: {}", key);
//            } catch (Exception e) {
//                log.warn("Failed to evict cache post execution for key: {}", key, e);
//            }
//        }
//
//        return result;
//    }
//
//    /**
//     * 根据查询生成缓存键。
//     */
//    private String generateCacheKeyForQuery(Method method, Object[] args) {
//        StringBuilder keyBuilder = new StringBuilder();
//
//        // 使用类名作为缓存键基础
//        String baseKey = extractBaseKeyFromClass(method.getDeclaringClass());
//        keyBuilder.append(baseKey);
//
//        // 添加方法名
//        keyBuilder.append(":").append(method.getName());
//
//        // 添加参数部分作为缓存键
//        keyBuilder.append(":").append(generateArgsKey(args));
//        return keyBuilder.toString();
//    }
//
//    private List<String> generateCacheKeysForModification(Object[] args) {
//        List<String> keys = new ArrayList<>();
//
//        for (Object arg : args) {
//            if (arg == null) {
//                continue; // 忽略空参数
//            }
//            if (arg instanceof Collection<?>) {
//                // 递归处理 Collection 类型的参数
//                for (Object item : (Collection<?>) arg) {
//                    keys.addAll(generateCacheKeysForModification(new Object[]{item}));
//                }
//                continue;
//            }
//
//            String baseKey = extractBaseKeyFromClass(arg.getClass());
//            if (baseKey == null || baseKey.isEmpty()) {
//                continue; // 忽略无法解析基础键的参数
//            }
//            String uniqueIdentifier = getUniqueIdentifier(arg);
//            if (uniqueIdentifier != null) {
//                keys.add(baseKey + ":get*" + uniqueIdentifier);
//                keys.add(baseKey + ":find*" + uniqueIdentifier);
//            }
//
//            // 添加基础键和参数的 JSON 表示
//            keys.add(baseKey + ":" + JSON.toJSONString(arg));
//
//            // 添加与列表查询和计数相关的键
//            keys.add(baseKey + ":select*");
//            keys.add(baseKey + ":count*");
//        }
//
//        return keys;
//    }
//
//    /**
//     * 判断是否为查询方法。
//     */
//    private boolean isQueryMethod(String methodName) {
//
//        return !methodName.startsWith("find") && (methodName.startsWith("get") || methodName.startsWith("select")
//        || methodName.startsWith("query") ||
//                methodName.startsWith("count"));
//    }
//
//    /**
//     * 判断是否为增删改方法。
//     */
//    private boolean isModifyMethod(String methodName) {
//        return methodName.startsWith("add") || methodName.startsWith("insert") ||
//                methodName.startsWith("update") || methodName.startsWith("save") || methodName.startsWith("delete");
//    }
//
//    private boolean isDeleteMethod(String methodName) {
//        return methodName.startsWith("delete");
//    }
//
//
//    /**
//     * 生成参数的唯一标识。
//     */
//    private String generateArgsKey(Object[] args) {
//        StringBuilder keyBuilder = new StringBuilder();
//        for (Object arg : args) {
//            if (arg instanceof BaseTable) {
//                keyBuilder.append(getUniqueIdentifier((BaseTable) arg));
//            } else if (arg instanceof List) {
//                for (Object item : (List<?>) arg) {
//                    if (item instanceof BaseTable) {
//                        keyBuilder.append(getUniqueIdentifier((BaseTable) item));
//                    }
//                }
//            } else {
//                keyBuilder.append(JSON.toJSONString(arg)); // 对于非实体类参数，保留其字符串形式
//            }
//            keyBuilder.append("|");
//        }
//
//        // 移除最后一个 "|"
//        if (keyBuilder.length() > 0) {
//            keyBuilder.setLength(keyBuilder.length() - 1);
//        }
//
//        return keyBuilder.toString();
//    }
//
//    /**
//     * 提取表名。
//     */
//    private String getTableName(Class<?> clazz) {
//        if (clazz.isAnnotationPresent(Table.class)) {
//            return clazz.getAnnotation(Table.class).name();
//        }
//        return clazz.getSimpleName();
//    }
//
//    /**
//     * 提取泛型类型。
//     */
//    private Class<?> getGenericReturnType(Method method) {
//        try {
//            java.lang.reflect.Type genericReturnType = method.getGenericReturnType();
//            if (genericReturnType instanceof java.lang.reflect.ParameterizedType) {
//                java.lang.reflect.Type[] typeArguments =
//                        ((java.lang.reflect.ParameterizedType) genericReturnType).getActualTypeArguments();
//                if (typeArguments.length > 0) {
//                    return (Class<?>) typeArguments[0];
//                }
//            }
//        } catch (Exception e) {
//            log.warn("Failed to extract generic type for method: {}", method.getName(), e);
//        }
//        return null;
//    }
//
//    /**
//     * 获取 object 实例的唯一标识。
//     * 通常通过主键字段（如 ID）生成。
//     */
//    private String getUniqueIdentifier(Object o) {
//        try {
//            // 尝试通过反射获取 ID 属性的值
//            Method getIdMethod = o.getClass().getMethod("getId");
//            Object id = getIdMethod.invoke(o);
//            if (id != null) {
//                return id.toString();
//            }
//        } catch (Exception e) {
//            log.warn("Failed to extract unique identifier for object: {}", o.getClass().getSimpleName(),
//                    e);
//        }
//        // 如果无法获取 ID，使用类名和 hashCode 作为唯一标识的备选
//        return o.getClass().getSimpleName() + "@" + System.identityHashCode(o);
//    }
//
//    /**
//     * 从类名中提取缓存键的基础部分。
//     * 移除尾部的 "Repository", "Mapper", "Dao" 后缀。
//     */
//    private String extractBaseKeyFromClass(Class<?> clazz) {
//        String className = clazz.getSimpleName();
//        if (className.endsWith("Repository")) {
//            return className.substring(0, className.length() - "Repository" .length());
//        } else if (className.endsWith("Mapper")) {
//            return className.substring(0, className.length() - "Mapper" .length());
//        } else if (className.endsWith("Dao")) {
//            return className.substring(0, className.length() - "Dao" .length());
//        }
//        if (className.endsWith("Table")) {
//            return className.substring(0, className.length() - "Table" .length());
//        }
//        return className; // 如果没有后缀，直接返回类名
//    }
}