package com.ecep.contract.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Redis缓存清理工具，用于管理和清理系统中的Redis缓存
 */
@Component
@Slf4j
public class RedisCacheCleaner {

    private final RedisTemplate<String, Object> redisTemplate;

    // 服务名称与缓存前缀的映射关系
    private static final Map<String, String> SERVICE_CACHE_PREFIX_MAP = new HashMap<>();

    // 缓存过期时间（分钟）
    private static final long DEFAULT_CACHE_EXPIRE_MINUTES = 30;

    static {
        // 初始化服务名称与缓存前缀的映射
        SERVICE_CACHE_PREFIX_MAP.put("ContractService", "contract:");
        SERVICE_CACHE_PREFIX_MAP.put("ProjectService", "project:");
        SERVICE_CACHE_PREFIX_MAP.put("SaleOrdersService", "sale_order:");
        SERVICE_CACHE_PREFIX_MAP.put("SalesBillVoucherService", "sales_bill:");
        SERVICE_CACHE_PREFIX_MAP.put("UserService", "user:");
        SERVICE_CACHE_PREFIX_MAP.put("CompanyService", "company:");
    }

    @Autowired
    public RedisCacheCleaner(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 按照模式清理缓存
     * @param pattern 缓存键模式，支持通配符
     * @return 清理的缓存数量
     */
    public int cleanCacheByPattern(String pattern) {
        log.info("清理Redis缓存，模式: {}", pattern);
        Set<String> keys = redisTemplate.keys(pattern);
        if (keys == null || keys.isEmpty()) {
            log.info("没有找到匹配的缓存键");
            return 0;
        }

        int count = keys.size();
        redisTemplate.delete(keys);
        log.info("成功清理缓存数量: {}", count);
        return count;
    }

    /**
     * 清理所有缓存
     * @return 清理的缓存数量
     */
    public int cleanAllCache() {
        log.info("清理所有Redis缓存");
        int totalCount = 0;
        Set<String> keys;
        do {
            keys = redisTemplate.keys("*");
            if (keys != null && !keys.isEmpty()) {
                int count = keys.size();
                redisTemplate.delete(keys);
                totalCount += count;
                log.info("本次清理缓存数量: {}, 累计清理: {}", count, totalCount);
            }
        } while (keys != null && !keys.isEmpty());

        log.info("清理所有缓存完成，总共清理: {}", totalCount);
        return totalCount;
    }

    /**
     * 清理指定键的缓存
     * @param key 缓存键
     * @return 是否清理成功
     */
    public boolean cleanCache(String key) {
        log.info("清理Redis缓存键: {}", key);
        boolean result = redisTemplate.delete(key);
        log.info("清理缓存键结果: {}", result);
        return result;
    }

    /**
     * 清理多个键的缓存
     * @param keys 缓存键数组
     * @return 清理的缓存数量
     */
    public long cleanMultipleKeys(String[] keys) {
        if (keys == null || keys.length == 0) {
            return 0;
        }

        log.info("清理多个Redis缓存键，数量: {}", keys.length);
        long count = redisTemplate.delete(Arrays.asList(keys));
        log.info("清理多个缓存键完成，成功清理: {}", count);
        return count;
    }

    /**
     * 清理特定服务的缓存
     * @param serviceName 服务名称
     * @return 清理的缓存数量
     */
    public int cleanServiceCache(String serviceName) {
        log.info("清理服务缓存，服务名称: {}", serviceName);
        String prefix = SERVICE_CACHE_PREFIX_MAP.getOrDefault(serviceName, serviceName.toLowerCase() + ":");
        return cleanCacheByPattern(prefix + "*");
    }

    /**
     * 清理多个服务的缓存
     * @param serviceNames 服务名称数组
     * @return 清理的缓存总数量
     */
    public int cleanAllServiceCache(String[] serviceNames) {
        if (serviceNames == null || serviceNames.length == 0) {
            return 0;
        }

        log.info("清理多个服务缓存，服务数量: {}", serviceNames.length);
        int totalCount = 0;
        for (String serviceName : serviceNames) {
            int count = cleanServiceCache(serviceName);
            totalCount += count;
        }

        log.info("清理多个服务缓存完成，总共清理: {}", totalCount);
        return totalCount;
    }

    /**
     * 刷新特定服务的缓存
     * @param serviceName 服务名称
     * @return 是否刷新成功
     */
    public boolean refreshServiceCache(String serviceName) {
        log.info("刷新服务缓存，服务名称: {}", serviceName);
        try {
            cleanServiceCache(serviceName);
            log.info("刷新服务缓存完成");
            return true;
        } catch (Exception e) {
            log.error("刷新服务缓存失败", e);
            return false;
        }
    }

    /**
     * 批量清理以特定前缀开头的所有缓存
     * @param prefix 缓存前缀
     * @return 清理的缓存数量
     */
    public int cleanCacheByPrefix(String prefix) {
        return cleanCacheByPattern(prefix + "*");
    }

    /**
     * 获取默认缓存过期时间
     * @return 过期时间（分钟）
     */
    public static long getDefaultCacheExpireMinutes() {
        return DEFAULT_CACHE_EXPIRE_MINUTES;
    }

    /**
     * 获取服务名称对应的缓存前缀
     * @param serviceName 服务名称
     * @return 缓存前缀
     */
    public static String getCachePrefixByServiceName(String serviceName) {
        return SERVICE_CACHE_PREFIX_MAP.getOrDefault(serviceName, serviceName.toLowerCase() + ":");
    }

    /**
     * 注册新的服务与缓存前缀映射
     * @param serviceName 服务名称
     * @param cachePrefix 缓存前缀
     */
    public static void registerServiceCachePrefix(String serviceName, String cachePrefix) {
        if (serviceName != null && cachePrefix != null) {
            SERVICE_CACHE_PREFIX_MAP.put(serviceName, cachePrefix);
            log.info("注册服务缓存前缀: {}, {}", serviceName, cachePrefix);
        }
    }

    /**
     * 获取所有已注册的服务缓存前缀映射
     * @return 服务名称与缓存前缀的映射
     */
    public static Map<String, String> getAllServiceCachePrefixes() {
        return new HashMap<>(SERVICE_CACHE_PREFIX_MAP);
    }
}