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

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.ningdatech.kqapi.common.constant.BizConst;
import com.ningdatech.kqapi.zzsfw.model.entity.ComponentsMatterEliminateEntity;
import com.ningdatech.kqapi.zzsfw.service.ComponentsMatterEliminateService;
import com.ningdatech.kqapi.zzsfw.model.entity.DscSxAdsShareItemQltQlsxCommonIDVKq;
import com.ningdatech.kqapi.zzsfw.model.entity.MatterKey;
import com.ningdatech.kqapi.zzsfw.model.entity.KqZzsfwMattersDeduplicate;
import com.ningdatech.kqapi.zzsfw.service.IDscSxAdsShareItemQltQlsxCommonIDVKqService;
import com.ningdatech.kqapi.zzsfw.service.IKqZzsfwMatterDeduplicateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * AbstractMatterCache
 * </p>
 *
 * @author ZPF
 * @since 14:41 2023/3/1
 */
@Slf4j
public abstract class AbstractMatterCacheHelper implements InitializingBean {

    @Autowired
    private IDscSxAdsShareItemQltQlsxCommonIDVKqService kqService;

    @Autowired
    private IKqZzsfwMatterDeduplicateService deduplicateService;

    protected LoadingCache<MatterKey, KqZzsfwMattersDeduplicate> mattersDupCache;

    protected LoadingCache<String, String> mattersUrlCache;

    @Autowired
    private ComponentsMatterEliminateService componentsMatterEliminateService;

    private static final String KQ_ZZS_BASE_URL = "https://www.zjzwfw.gov.cn/zjservice-fe/#/workguide?localInnerCode=&siteCode=330000000000";

    private Boolean initMatterCache() {
        // 首先，查询ComponentsMatterEliminateEntity中isDelete不为1的qlName列表, 未被剔除
        List<String> eliminatedQlNames = componentsMatterEliminateService.list(
                Wrappers.<ComponentsMatterEliminateEntity>lambdaQuery()
                        .select(ComponentsMatterEliminateEntity::getQlName)
                        .ne(ComponentsMatterEliminateEntity::getIsDelete, 1)
        ).stream().map(ComponentsMatterEliminateEntity::getQlName).collect(Collectors.toList());

        // 然后，使用eliminatedQlNames来过滤DscSxAdsShareItemQltQlsxCommonIDVKq查询
        List<DscSxAdsShareItemQltQlsxCommonIDVKq> allMatters = kqService
                .list(Wrappers.<DscSxAdsShareItemQltQlsxCommonIDVKq>lambdaQuery()
                        .select(DscSxAdsShareItemQltQlsxCommonIDVKq::getRowguid,
                                DscSxAdsShareItemQltQlsxCommonIDVKq::getQlName,
                                DscSxAdsShareItemQltQlsxCommonIDVKq::getQlState,
                                DscSxAdsShareItemQltQlsxCommonIDVKq::getQlInnerCode,
                                DscSxAdsShareItemQltQlsxCommonIDVKq::getWebapplyurl)
                        .isNotNull(DscSxAdsShareItemQltQlsxCommonIDVKq::getWebapplyurl)
                        .isNotNull(DscSxAdsShareItemQltQlsxCommonIDVKq::getQlInnerCode)
                        .notIn(!eliminatedQlNames.isEmpty(), DscSxAdsShareItemQltQlsxCommonIDVKq::getQlName, eliminatedQlNames)
                        // 过滤掉那些在eliminatedQlNames中的记录
                        .orderByDesc(DscSxAdsShareItemQltQlsxCommonIDVKq::getUpdateDate));
        if (allMatters.isEmpty()) {
            log.warn("事项数据未初始化");
            return Boolean.FALSE;
        }
        allMatters.forEach(m -> {
            // 3-14日修改新的url匹配规则，取事项状态为1且qlInnerCode不为空的进行拼接，新的url规则如下
            String kqUrl = KQ_ZZS_BASE_URL.replace("localInnerCode=", "localInnerCode=" + m.getQlInnerCode());
            MatterKey key = MatterKey.of(m.getQlName(), kqUrl);
            if (!mattersUrlCache.asMap().containsKey(m.getQlName())) {
                mattersUrlCache.put(m.getQlName(), kqUrl);
            } else {
                String url = mattersUrlCache.get(m.getQlName());
                if (StringUtils.isNotBlank(url) && !url.equals(kqUrl)) {
                    return;
                }
            }
            if (mattersDupCache.asMap().containsKey(key)) {
                KqZzsfwMattersDeduplicate dup = mattersDupCache.get(key);
                dup.setCountNum(dup.getCountNum() + 1);
                mattersDupCache.put(key, dup);
            } else {
                mattersDupCache.put(key, KqZzsfwMattersDeduplicate.of(m.getQlName(), kqUrl));
            }
        });
        return Boolean.TRUE;
    }

    protected KqZzsfwMattersDeduplicate get(String qlName, String url) {
        MatterKey key = MatterKey.of(qlName, url);
        return mattersDupCache.get(key);
    }

    protected String getUrl(String qlName) {
        return mattersUrlCache.get(qlName);
    }

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

    @Override
    public void afterPropertiesSet() {
        mattersUrlCache = Caffeine.newBuilder()
                .refreshAfterWrite(7, TimeUnit.DAYS)
                .maximumSize(1024 * 100)
                .build(key -> {
                    KqZzsfwMattersDeduplicate dup = deduplicateService.getOne(Wrappers.lambdaQuery(KqZzsfwMattersDeduplicate.class)
                            .eq(KqZzsfwMattersDeduplicate::getQlName, key)
                            .last(BizConst.LIMIT_1)
                            .isNotNull(KqZzsfwMattersDeduplicate::getWebapplyurl));
                    if (Objects.isNull(dup)) {
                        //查不到直接返回null
                        return null;
                    }
                    return dup.getWebapplyurl();
                });
        mattersDupCache = Caffeine.newBuilder()
                .refreshAfterWrite(7, TimeUnit.DAYS)
                .maximumSize(1024 * 100)
                .build(key -> {
                    KqZzsfwMattersDeduplicate dup = deduplicateService.getOne(Wrappers.lambdaQuery(KqZzsfwMattersDeduplicate.class)
                            .eq(KqZzsfwMattersDeduplicate::getQlName, key)
                            .last(BizConst.LIMIT_1)
                            .isNotNull(KqZzsfwMattersDeduplicate::getWebapplyurl));
                    if (Objects.isNull(dup)) {
                        //查不到直接返回null
                        return null;
                    }
                    return dup;
                });
        // 初始化所有事项数据到缓存
//        initMatterCache();
    }

    public Boolean init() {
        mattersUrlCache = Caffeine.newBuilder()
                .refreshAfterWrite(7, TimeUnit.DAYS)
                .maximumSize(1024 * 100)
                .build(key -> {
//                    DscSxAdsShareItemQltQlsxCommonIDVKq matter = kqService.getOne(Wrappers.lambdaQuery(DscSxAdsShareItemQltQlsxCommonIDVKq.class)
//                            .eq(DscSxAdsShareItemQltQlsxCommonIDVKq::getQlName, key)
////                            .eq(DscSxAdsShareItemQltQlsxCommonIDVKq::getQlState, "1")
////                            .isNotNull(DscSxAdsShareItemQltQlsxCommonIDVKq::getQlInnerCodeItem)
//                            .isNotNull(DscSxAdsShareItemQltQlsxCommonIDVKq::getWebapplyurl)
//                            .orderByDesc(DscSxAdsShareItemQltQlsxCommonIDVKq::getUpdateDate)
//                            .last(BizConst.LIMIT_1)
//                    );
                    KqZzsfwMattersDeduplicate dup = deduplicateService.getOne(Wrappers.lambdaQuery(KqZzsfwMattersDeduplicate.class)
                            .eq(KqZzsfwMattersDeduplicate::getQlName, key)
                            .last(BizConst.LIMIT_1)
                            .isNotNull(KqZzsfwMattersDeduplicate::getWebapplyurl));
                    if (Objects.isNull(dup)) {
                        //查不到直接返回null
                        return null;
                    }
                    return dup.getWebapplyurl();
//                    return "https://www.zjzwfw.gov.cn/zjservice-fe/#/workguide?localInnerCode="+ matter.getQlInnerCodeItem() +"&siteCode=330000000000";
                });
        mattersDupCache = Caffeine.newBuilder()
                .refreshAfterWrite(7, TimeUnit.DAYS)
                .maximumSize(1024 * 100)
                .build(key -> {
                    KqZzsfwMattersDeduplicate dup = deduplicateService.getOne(Wrappers.lambdaQuery(KqZzsfwMattersDeduplicate.class)
                            .eq(KqZzsfwMattersDeduplicate::getQlName, key)
                            .last(BizConst.LIMIT_1)
                            .isNotNull(KqZzsfwMattersDeduplicate::getWebapplyurl));
                    if (Objects.isNull(dup)) {
                        //查不到直接返回null
                        return null;
                    }
                    return dup;
                });
        // 初始化所有事项数据到缓存
        return initMatterCache();
    }
}
