package incheon.uis.ums.service.impl;

import incheon.uis.ums.mapper.CommonCodeMapper;
import incheon.uis.ums.service.UisCommonCodeService;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
@RequiredArgsConstructor
public class UisCommonCodeServiceImpl implements UisCommonCodeService {

    private final CommonCodeMapper commonCodeMapper;

    // 서버 캐싱(간단한 메모리 캐시, TTL 적용)
    private final Map<String, CacheEntry> cache = new ConcurrentHashMap<>();
    private static final long CACHE_TTL_MILLIS = 10 * 60 * 1000; // 10분

    @Override
    @SuppressWarnings("unchecked")
    public List<CodeOption> getOptionsByListId(String listId) {
        long now = Instant.now().toEpochMilli();
        CacheEntry cached = cache.get(listId);
        if (cached != null && (now - cached.cachedAtMillis) < CACHE_TTL_MILLIS) {
            return (List<CodeOption>) cached.options;
        }
        List<CodeOption> fetched = commonCodeMapper.selectOptionsByListId(listId);
        if (fetched == null) fetched = new ArrayList<>();
        cache.put(listId, new CacheEntry(now, fetched));
        return fetched;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<CodeOption> getOptionsByListIds(List<String> listIds) {
        long now = Instant.now().toEpochMilli();
        String cacheKey = listIds.toString();
        CacheEntry cached = cache.get(cacheKey);
        if (cached != null && (now - cached.cachedAtMillis) < CACHE_TTL_MILLIS) {
            return (List<CodeOption>) cached.options;
        }
        List<CodeOption> fetched = commonCodeMapper.selectOptionsByListIds(listIds);
        if (fetched == null) fetched = new ArrayList<>();
        cache.put(cacheKey, new CacheEntry(now, fetched));
        return fetched;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<CodeOptionLayer> getOptionsByLayerId(String layerId) {
        long now = Instant.now().toEpochMilli();
        CacheEntry cached = cache.get(layerId);
        if (cached != null && (now - cached.cachedAtMillis) < CACHE_TTL_MILLIS) {
            return (List<CodeOptionLayer>) cached.options;
        }
        List<CodeOptionLayer> fetched = commonCodeMapper.selectOptionsByLayerId(StringUtils.upperCase(layerId));

        if (fetched == null) fetched = new ArrayList<>();
        cache.put(layerId, new CacheEntry(now, fetched));
        return fetched;
    }

    @AllArgsConstructor
    private static class CacheEntry {
        long cachedAtMillis;
        List<?> options;
    }
}


