package com.qaup.collision.common.service;

import com.qaup.collision.common.model.spatial.AirportArea;
import com.qaup.collision.common.model.base.CacheConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

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

/**
 * 机场区域缓存服务类
 * 基于Redis实现机场区域配置和空间查询结果的高性能缓存
 * 
 * 主要功能：
 * 1. 区域配置数据缓存
 * 2. 空间查询结果缓存
 * 3. 区域类型索引缓存
 * 4. 缓存失效和刷新策略
 * 5. 缓存预热功能
 */
@Slf4j
@Service
public class AirportAreaCacheService {

    private final RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    public AirportAreaCacheService(
            @Qualifier("redisTemplate") RedisTemplate<Object, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 缓存机场区域配置
     * 
     * @param airportArea 机场区域配置
     */
    public void cacheAirportArea(AirportArea airportArea) {
        try {
            // 按名称缓存
            String nameKey = CacheConstants.buildAirportAreaKey(airportArea.getName());
            redisTemplate.opsForValue()
                .set(nameKey, airportArea, CacheConstants.AIRPORT_AREA_EXPIRE, TimeUnit.SECONDS);
            
            // 按ID缓存（如果有areaId）
            if (airportArea.getAreaId() != null) {
                String idKey = CacheConstants.buildAirportAreaKey(airportArea.getAreaId());
                redisTemplate.opsForValue()
                    .set(idKey, airportArea, CacheConstants.AIRPORT_AREA_EXPIRE, TimeUnit.SECONDS);
            }
            
            log.debug("缓存机场区域配置: name={}, id={}", airportArea.getName(), airportArea.getAreaId());
        } catch (Exception e) {
            log.warn("缓存机场区域配置失败: name={}", airportArea.getName(), e);
        }
    }

    /**
     * 获取机场区域配置
     * 
     * @param areaNameOrId 区域名称或ID
     * @return 机场区域配置，不存在则返回null
     */
    public AirportArea getAirportArea(String areaNameOrId) {
        try {
            String key = CacheConstants.buildAirportAreaKey(areaNameOrId);
            Object result = redisTemplate.opsForValue().get(key);
            
            if (result instanceof AirportArea) {
                AirportArea area = (AirportArea) result;
                log.debug("获取机场区域配置缓存: nameOrId={}, found={}", areaNameOrId, true);
                return area;
            }
            
            log.debug("机场区域配置缓存未命中: nameOrId={}", areaNameOrId);
            return null;
        } catch (Exception e) {
            log.warn("获取机场区域配置缓存失败: nameOrId={}", areaNameOrId, e);
            return null;
        }
    }

    /**
     * 删除机场区域配置缓存
     * 
     * @param airportArea 机场区域配置
     */
    public void evictAirportArea(AirportArea airportArea) {
        try {
            // 删除名称缓存
            String nameKey = CacheConstants.buildAirportAreaKey(airportArea.getName());
            redisTemplate.delete(nameKey);
            
            // 删除ID缓存（如果有areaId）
            if (airportArea.getAreaId() != null) {
                String idKey = CacheConstants.buildAirportAreaKey(airportArea.getAreaId());
                redisTemplate.delete(idKey);
            }
            
            log.debug("清除机场区域配置缓存: name={}, id={}", airportArea.getName(), airportArea.getAreaId());
        } catch (Exception e) {
            log.warn("清除机场区域配置缓存失败: name={}", airportArea.getName(), e);
        }
    }

    /**
     * 获取缓存统计信息
     * 
     * @return 缓存统计信息
     */
    public Map<String, Object> getCacheStatistics() {
        try {
            Map<String, Object> stats = new HashMap<>();
            
            // 区域配置缓存数量
            String areaPattern = CacheConstants.AIRPORT_AREA_PREFIX + "*";
            Set<Object> areaKeys = redisTemplate.keys(areaPattern);
            stats.put("areaCacheCount", areaKeys != null ? areaKeys.size() : 0);
            
            return stats;
        } catch (Exception e) {
            log.warn("获取机场区域缓存统计信息失败", e);
            return Collections.emptyMap();
        }
    }
} 