package com.mosquito.project.service;

import com.mosquito.project.persistence.entity.SystemConfigEntity;
import com.mosquito.project.persistence.repository.SystemConfigRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.OffsetDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Service
public class SystemService {

    private static final Logger log = LoggerFactory.getLogger(SystemService.class);

    // 缓存名称常量（与CacheConfig中定义一致）
    public static final String CACHE_LEADERBOARDS = "leaderboards";
    public static final String CACHE_ACTIVITIES = "activities";
    public static final String CACHE_ACTIVITY_STATS = "activity_stats";
    public static final String CACHE_ACTIVITY_GRAPH = "activity_graph";

    // 所有业务缓存名称列表
    public static final List<String> BUSINESS_CACHES = Arrays.asList(
        CACHE_LEADERBOARDS, CACHE_ACTIVITIES, CACHE_ACTIVITY_STATS, CACHE_ACTIVITY_GRAPH
    );

    private final SystemConfigRepository configRepository;
    private final CacheManager cacheManager;
    private final Map<String, Map<String, Object>> caches = new ConcurrentHashMap<>();

    // 默认配置（仅在首次启动时初始化）
    private static final Map<String, String> DEFAULT_CONFIGS = new HashMap<>();
    static {
        DEFAULT_CONFIGS.put("system.name", "蚊子系统");
        DEFAULT_CONFIGS.put("system.version", "1.0.0");
        DEFAULT_CONFIGS.put("system.timezone", "Asia/Shanghai");
        DEFAULT_CONFIGS.put("reward.points.enabled", "true");
        DEFAULT_CONFIGS.put("reward.coupon.enabled", "true");
        DEFAULT_CONFIGS.put("risk.alert.enabled", "true");
        DEFAULT_CONFIGS.put("risk.auto.block", "false");
    }

    public SystemService(SystemConfigRepository configRepository,
                        @Autowired(required = false) CacheManager cacheManager) {
        this.configRepository = configRepository;
        this.cacheManager = cacheManager;
        initDefaultConfigs();
    }

    private void initDefaultConfigs() {
        // 初始化默认配置到数据库
        for (Map.Entry<String, String> entry : DEFAULT_CONFIGS.entrySet()) {
            if (configRepository.findByConfigKey(entry.getKey()).isEmpty()) {
                SystemConfigEntity config = new SystemConfigEntity();
                config.setConfigKey(entry.getKey());
                config.setConfigValue(entry.getValue());
                config.setValueType("STRING");
                config.setCategory(entry.getKey().split("\\.")[0].toUpperCase());
                config.setIsSystem(true);
                config.setDefaultValue(entry.getValue());
                config.setCreatedAt(OffsetDateTime.now());
                config.setUpdatedAt(OffsetDateTime.now());
                configRepository.save(config);
                log.info("初始化系统配置: {} = {}", entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * 获取配置列表
     */
    public Map<String, Object> getConfigs(String category, String keyword) {
        List<SystemConfigEntity> configs;
        if (category != null || keyword != null) {
            configs = configRepository.findByFilters(category, keyword);
        } else {
            configs = configRepository.findAll();
        }

        List<Map<String, String>> configList = configs.stream()
            .map(c -> {
                Map<String, String> config = new HashMap<>();
                config.put("key", c.getConfigKey());
                config.put("value", c.getConfigValue());
                config.put("valueType", c.getValueType());
                config.put("category", c.getCategory());
                config.put("description", c.getDescription());
                config.put("isSystem", String.valueOf(c.getIsSystem()));
                return config;
            })
            .collect(Collectors.toList());

        Map<String, Object> result = new HashMap<>();
        result.put("data", configList);
        result.put("total", configList.size());
        return result;
    }

    /**
     * 获取单个配置
     */
    public Map<String, Object> getConfigByKey(String key) {
        Optional<SystemConfigEntity> configOpt = configRepository.findByConfigKey(key);
        if (!configOpt.isPresent()) {
            return null;
        }

        SystemConfigEntity config = configOpt.get();
        Map<String, Object> result = new HashMap<>();
        result.put("key", config.getConfigKey());
        result.put("value", config.getConfigValue());
        result.put("valueType", config.getValueType());
        result.put("category", config.getCategory());
        result.put("description", config.getDescription());
        result.put("isSystem", config.getIsSystem());
        return result;
    }

    /**
     * 保存待审批的配置值
     */
    public String savePendingConfig(String key, String value) {
        Optional<SystemConfigEntity> configOpt = configRepository.findByConfigKey(key);
        if (configOpt.isPresent()) {
            SystemConfigEntity config = configOpt.get();
            config.setPendingValue(value);
            config.setUpdatedAt(OffsetDateTime.now());
            configRepository.save(config);
            log.info("待审批配置已保存: {} = {}", key, value);
            return value;
        }
        // 不存在则创建新的待审批配置
        SystemConfigEntity newConfig = new SystemConfigEntity();
        newConfig.setConfigKey(key);
        newConfig.setConfigValue(null); // 当前值为空，等待审批
        newConfig.setPendingValue(value);
        newConfig.setValueType("STRING");
        newConfig.setCategory(key.split("\\.")[0].toUpperCase());
        newConfig.setIsSystem(false);
        newConfig.setCreatedAt(OffsetDateTime.now());
        newConfig.setUpdatedAt(OffsetDateTime.now());
        configRepository.save(newConfig);
        log.info("待审批配置已创建: {} = {}", key, value);
        return value;
    }

    /**
     * 审批通过后应用配置
     */
    @Transactional
    public boolean applyPendingConfig(String key) {
        Optional<SystemConfigEntity> configOpt = configRepository.findByConfigKey(key);
        if (configOpt.isPresent()) {
            SystemConfigEntity config = configOpt.get();
            if (config.getPendingValue() != null) {
                config.setConfigValue(config.getPendingValue());
                config.setPendingValue(null);
                config.setUpdatedAt(OffsetDateTime.now());
                configRepository.save(config);
                log.info("审批通过，配置已生效: {} = {}", key, config.getConfigValue());
                return true;
            }
        }
        return false;
    }

    /**
     * 更新配置（持久化）
     */
    @Transactional
    public boolean updateConfig(String key, String value) {
        Optional<SystemConfigEntity> configOpt = configRepository.findByConfigKey(key);
        if (configOpt.isPresent()) {
            SystemConfigEntity config = configOpt.get();
            config.setConfigValue(value);
            config.setUpdatedAt(OffsetDateTime.now());
            configRepository.save(config);
            log.info("配置已更新: {} = {}", key, value);
            return true;
        }
        // 不存在则创建
        SystemConfigEntity newConfig = new SystemConfigEntity();
        newConfig.setConfigKey(key);
        newConfig.setConfigValue(value);
        newConfig.setValueType("STRING");
        newConfig.setCategory(key.split("\\.")[0].toUpperCase());
        newConfig.setIsSystem(false);
        newConfig.setCreatedAt(OffsetDateTime.now());
        newConfig.setUpdatedAt(OffsetDateTime.now());
        configRepository.save(newConfig);
        log.info("配置已创建: {} = {}", key, value);
        return true;
    }

    /**
     * 批量更新配置
     */
    @Transactional
    public int batchUpdateConfigs(Map<String, Object> configsToUpdate) {
        int count = 0;
        for (Map.Entry<String, Object> entry : configsToUpdate.entrySet()) {
            if (entry.getValue() != null) {
                updateConfig(entry.getKey(), entry.getValue().toString());
                count++;
            }
        }
        return count;
    }

    /**
     * 重置配置为默认值
     */
    @Transactional
    public boolean resetConfig(String key) {
        Optional<SystemConfigEntity> configOpt = configRepository.findByConfigKey(key);
        if (configOpt.isPresent()) {
            SystemConfigEntity config = configOpt.get();
            if (config.getDefaultValue() != null) {
                config.setConfigValue(config.getDefaultValue());
                config.setUpdatedAt(OffsetDateTime.now());
                configRepository.save(config);
                log.info("配置已重置: {} = {}", key, config.getDefaultValue());
                return true;
            }
        }
        return false;
    }

    /**
     * 清除缓存
     * PRD要求: 能真实清理 leaderboards/activities/activity_stats/activity_graph
     */
    public boolean clearCache(String type) {
        // 优先使用真实CacheManager清理Redis缓存
        if (cacheManager != null) {
            try {
                if (type != null && !type.isEmpty()) {
                    // 清理指定类型的缓存
                    if (BUSINESS_CACHES.contains(type)) {
                        org.springframework.cache.Cache cache = cacheManager.getCache(type);
                        if (cache != null) {
                            cache.clear();
                            log.info("缓存清除成功（Redis）: type={}", type);
                        }
                    }
                    // 也清理内存缓存
                    caches.remove(type);
                } else {
                    // 清理所有业务缓存
                    for (String cacheName : BUSINESS_CACHES) {
                        org.springframework.cache.Cache cache = cacheManager.getCache(cacheName);
                        if (cache != null) {
                            cache.clear();
                        }
                    }
                    caches.clear();
                    log.info("缓存清除成功（Redis）: all");
                }
                return true;
            } catch (Exception e) {
                log.error("清除Redis缓存失败: type={}, error={}", type, e.getMessage());
                // 降级到内存缓存清理
            }
        }

        // 降级到内存缓存清理
        if (type != null && !type.isEmpty()) {
            caches.remove(type);
        } else {
            caches.clear();
        }
        return true;
    }

    /**
     * 键级失效 - 删除缓存中的指定键
     * PRD要求: 支持key级别的失效接口
     */
    public boolean evictCache(String cacheName, String key) {
        if (cacheName == null || key == null) {
            return false;
        }

        try {
            // 优先使用真实CacheManager
            if (cacheManager != null) {
                org.springframework.cache.Cache cache = cacheManager.getCache(cacheName);
                if (cache != null) {
                    cache.evict(key);
                    log.info("缓存键失效成功: cacheName={}, key={}", cacheName, key);
                    return true;
                }
            }
            // 降级到内存缓存
            Map<String, Object> cacheMap = caches.get(cacheName);
            if (cacheMap != null) {
                cacheMap.remove(key);
                log.info("缓存键失效成功（内存）: cacheName={}, key={}", cacheName, key);
                return true;
            }
        } catch (Exception e) {
            log.error("缓存键失效失败: cacheName={}, key={}, error={}", cacheName, key, e.getMessage());
        }
        return false;
    }

    /**
     * 获取缓存列表
     * PRD要求: 支持缓存列表查询
     */
    public List<Map<String, Object>> getCacheList() {
        List<Map<String, Object>> result = new ArrayList<>();

        // 添加业务缓存信息
        if (cacheManager != null) {
            for (String cacheName : BUSINESS_CACHES) {
                org.springframework.cache.Cache cache = cacheManager.getCache(cacheName);
                if (cache != null) {
                    Map<String, Object> info = new HashMap<>();
                    info.put("name", cacheName);
                    info.put("type", "redis");
                    info.put("available", true);
                    result.add(info);
                }
            }
        }

        // 添加内存缓存信息
        for (Map.Entry<String, Map<String, Object>> entry : caches.entrySet()) {
            Map<String, Object> cache = new HashMap<>();
            cache.put("name", entry.getKey());
            cache.put("type", "memory");
            cache.put("size", entry.getValue().size());
            cache.put("available", true);
            result.add(cache);
        }
        return result;
    }

    /**
     * 获取系统信息
     */
    public Map<String, Object> getSystemInfo() {
        Map<String, Object> info = new HashMap<>();
        info.put("version", "1.0.0");
        info.put("uptime", System.currentTimeMillis());
        info.put("memory", Map.of(
            "total", Runtime.getRuntime().totalMemory(),
            "used", Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(),
            "free", Runtime.getRuntime().freeMemory()
        ));
        info.put("cpu", Runtime.getRuntime().availableProcessors());
        info.put("threads", Thread.activeCount());
        return info;
    }
}
