package com.ningdatech.pmapi.common.helper.basic;

import cn.hutool.core.lang.Assert;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.ningdatech.pmapi.common.model.RegionMapKey;
import com.ningdatech.pmapi.sys.convert.RegionConverter;
import com.ningdatech.pmapi.sys.model.dto.RegionDTO;
import com.ningdatech.pmapi.sys.model.entity.Region;
import com.ningdatech.pmapi.sys.service.IRegionService;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * AbstractRegionCache
 * </p>
 *
 * @author WendyYang
 * @since 14:41 2023/3/1
 */
@Slf4j
public abstract class AbstractRegionCacheHelper implements InitializingBean {

    @Autowired
    private IRegionService regionService;

    private LoadingCache<RegionMapKey, RegionDTO> regionsCache;

    private void initRegionCache() {
        List<RegionDTO> allRegions = regionService.all();
        if (allRegions.isEmpty()) {
            log.warn("区域元数据未初始化");
            return;
        }
        allRegions.forEach(w -> {
            RegionMapKey key = RegionMapKey.of(w.getRegionCode(), w.getRegionLevel());
            regionsCache.put(key, w);
        });
    }

    protected RegionDTO get(RegionMapKey key) {
        return regionsCache.get(key);
    }

    protected List<RegionDTO> all() {
        return Lists.newArrayList(regionsCache.asMap().values());
    }

    @Override
    public void afterPropertiesSet() {
        regionsCache = Caffeine.newBuilder()
                .refreshAfterWrite(7, TimeUnit.DAYS)
                .maximumSize(512)
                .build(key -> {
                    Region region = regionService.getOne(key.getRegionCode(), key.getRegionLevel());
                    Assert.notNull(region, "区域不存在：%s", key);
                    return RegionConverter.toRegionDTO(region);
                });
        // 初始化所有区域数据到缓存
        initRegionCache();
    }

}
