package com.project.common.core.redis;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.project.common.core.domain.entity.LargeCache;
import com.project.common.mapper.cache.PlatCacheMapper;
import com.project.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
public class MyCache {

    @Autowired
    private PlatCacheMapper platCacheMapper;

    // 使用ConcurrentHashMap作为数据的存储
//    private ConcurrentHashMap<String, Object> storage = new ConcurrentHashMap<>();

    /**
     * 使用caffeineCache作为数据的存储
     */
    private Cache<String, Object> caffeineCache;

    /**
     * 初始化 Caffeine Cache 配置
     */
    @PostConstruct
    public void init() {
        caffeineCache = Caffeine.newBuilder()
                .expireAfterWrite(30, TimeUnit.DAYS) // 设置缓存过期时间
                .maximumSize(1000) // 设置缓存最大容量
                .recordStats() // 启用缓存统计
                .build();
    }

    // getName获取cache的名称，存取数据的时候用来区分是针对哪个cache操作
//    @Override
//    public String getName() {
//        return null;
//    }

//    @Override
//    public Object getNativeCache() {
//        return null;
//    }

//    public boolean hasKey(String key){
//        return storage.containsKey(key);
//    }

    /**
     * 查询某个缓存是否存在
     * @param key
     * @return
     */
    public boolean hasKey(String key){
        if (StringUtils.isBlank(key)){
            return false;
        }
        LargeCache cache = platCacheMapper.selectCache(key);
        if (cache == null || StringUtils.isBlank(cache.getKey())){
            return false;
        }
        /*不要过期*/
        LocalDateTime createTimePlus30 = cache.getCreateTime().toInstant()
                .atZone(java.time.ZoneId.systemDefault())
                .toLocalDateTime()
                .plusDays(cache.getExpirationDate());
        LocalDateTime now = LocalDateTime.now();
        if (createTimePlus30.isBefore(now)){
            platCacheMapper.deleteCache(key);
            return false;
        }
        return true;
//        if (caffeineCache.getIfPresent(key) != null){
//            return true;
//        }
//        return false;
    }

//    @Override
//    public ValueWrapper get(Object key) {
//        String k = key.toString();
//        Object value = storage.get(k);
//
//        // 注意返回的数据，要和存放时接收到数据保持一致，要将数据反序列化回来。
//        return Objects.isNull(value) ? null : new SimpleValueWrapper(value);
//    }

    /**
     * get方法， 获取缓存数据
     * @param key
     * @return
     */
    public Object get(Object key) {
//        String k = key.toString();
//        return caffeineCache.getIfPresent(k);
        if (Objects.isNull(key)){
            return null;
        }
        if (key.toString().equals("hq-service:sys_config:sys.account.captchaEnabled_sxgw24")){
            return "true";
        }
        LargeCache cache = platCacheMapper.selectCache(key.toString());
        /*不要过期*/
        if (cache == null || StringUtils.isBlank(cache.getKey())){
            return null;
        }
        LocalDateTime createTimePlus30 = cache.getCreateTime().toInstant()
                .atZone(java.time.ZoneId.systemDefault())
                .toLocalDateTime()
                .plusDays(cache.getExpirationDate());
        LocalDateTime now = LocalDateTime.now();
        if (createTimePlus30.isBefore(now)){
            platCacheMapper.deleteCache(key.toString());
            return null;
        }
        return cache.getData();
    }

//    @Override
//    public <T> T get(Object key, Class<T> type) {
//        return null;
//    }

//    @Override
//    public <T> T get(Object key, Callable<T> valueLoader) {
//        return null;
//    }

    // put方法，就是执行将数据进行缓存
//    @Override
//    public void put(Object key, Object value) {
//        if (Objects.isNull(value)) {
//            return;
//        }
//        //存值
//        storage.put(key.toString(), value);
//    }

    /**
     * put方法，就是执行将数据进行缓存
     * @param key
     * @param value
     */
    public void put(Object key, Object value) {
//        if (Objects.nonNull(value)) {
//            caffeineCache.put(key.toString(), value);
//        }
        if (hasKey(key.toString())){
            return;
        }
        if (Objects.isNull(value)){
            return;
        }
        if (value instanceof String){
            platCacheMapper.insertCache(key.toString(), value.toString());
        }
        else {
            platCacheMapper.insertCache(key.toString(), JSON.toJSONString(value));
        }
    }

    // evict方法，是用来清除某个缓存项
//    @Override
//    public void evict(Object key) {
//        storage.remove(key.toString());
//    }

    /**
     * evict方法，是用来清除某个缓存项
     * @param key
     */
    public void evict(Object key) {
//        caffeineCache.invalidate(key.toString());
        if (Objects.isNull(key)){
            return;
        }
        platCacheMapper.deleteCache(key.toString());
    }

    // 删除集合
//    public boolean deleteObject(final Collection collection){
//        collection.forEach(o -> {
//            storage.remove(o.toString());
//        } );
//        return true;
//    }

    /**
     * 删除集合
     * @param collection
     * @return
     */
    public boolean deleteObject(final Collection collection){
//        collection.forEach(o -> {
//            caffeineCache.invalidate(o.toString());
//        } );
//        return true;
        List<String> list = new ArrayList<>();
        collection.forEach(o -> {
            list.add(o.toString());
        });
        platCacheMapper.deleteCaches(list);
        return true;
    }

    // 获取所有的keys
//    public Collection<String> keys(final String pattern){
//        return storage.keySet();
//    }

    /**
     * 获取所有的keys
     * @param pattern
     * @return
     */
    public Collection<String> keys(final String pattern){
//        return caffeineCache.asMap().keySet();
        return platCacheMapper.selectKeys();
    }

//    @Override
//    public void clear() {
//
//    }

    /**
     * 清除所有缓存
     */
    public void clear() {
//        caffeineCache.invalidateAll();
        platCacheMapper.clearAll();
    }
}
