package com.sundot.airport.common.cache;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sundot.airport.common.utils.SecurityUtils;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Date;
import java.util.StringJoiner;

/**
 * 统计缓存自定义缓存Key生成器
 */
@Component("statisticsKeyGenerator")
public class StatisticsKeyGenerator implements KeyGenerator {

    @Override
    public Object generate(Object target, Method method, Object... params) {
        StringBuilder key = new StringBuilder();

        // 1. 类名和方法名
        key.append(target.getClass().getSimpleName())
                .append(".")
                .append(method.getName());

        // 2. 用户ID（确保用户隔离）
        key.append("_user").append(getCurrentUserId());

        // 3. 精确的参数处理
        if (params != null && params.length > 0) {
            key.append("_args");
            for (Object param : params) {
                key.append("_").append(generateParamHash(param));
            }
        }

        return key.toString();
    }

    /**
     * 生成精确的参数哈希
     */
    private String generateParamHash(Object param) {
        if (param == null) {
            return "null";
        }

        try {
            // 对于基本类型，直接使用值
            if (param instanceof String || param instanceof Number || param instanceof Boolean) {
                return param.getClass().getSimpleName() + ":" + param.toString();
            }

            // 对于日期类型，使用时间戳
            if (param instanceof Date) {
                return "Date:" + ((Date) param).getTime();
            }

            // 对于集合类型，生成详细哈希
            if (param instanceof Collection) {
                return generateCollectionHash((Collection<?>) param);
            }

            if (param instanceof Object[]) {
                return generateArrayHash((Object[]) param);
            }

            // 对于对象，使用JSON序列化+哈希
            return generateObjectHash(param);

        } catch (Exception e) {
            // 出错时使用备用方案
            return "err:" + System.identityHashCode(param);
        }
    }

    private String generateCollectionHash(Collection<?> collection) {
        if (collection == null || collection.isEmpty()) {
            return "emptyCollection";
        }

        StringJoiner sj = new StringJoiner(",");
        for (Object item : collection) {
            sj.add(generateParamHash(item));
        }
        return "Collection[" + sj.toString() + "]";
    }

    private String generateArrayHash(Object[] array) {
        if (array == null || array.length == 0) {
            return "emptyArray";
        }

        StringJoiner sj = new StringJoiner(",");
        for (Object item : array) {
            sj.add(generateParamHash(item));
        }
        return "Array[" + sj.toString() + "]";
    }

    private String generateObjectHash(Object obj) {
        try {
            // 尝试使用JSON序列化
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writeValueAsString(obj);
            int hash = json.hashCode();
            return "Object:" + hash + ":" + json.length();
        } catch (Exception e) {
            // 备用方案：使用toString和哈希
            return "Object:" + obj.toString().hashCode() + ":" + obj.getClass().getSimpleName();
        }
    }

    private String getCurrentUserId() {
        try {
            Long userId = SecurityUtils.getUserId();
            return userId != null ? userId.toString() : "anonymous";
        } catch (Exception e) {
            return "unknown";
        }
    }

}
