package com.skr.mdm.api.app.excel;

import cn.hutool.json.JSONUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.google.common.collect.Lists;
import com.skr.mdm.api.app.service.AppConfigService;
import com.skr.mdm.constant.RegexConstants;
import com.skr.mdm.entity.AppConfigDO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author nfq
 * @date 2022-11-07 14:22
 */
@Slf4j
public class AppConfigImportDataListener extends AnalysisEventListener<AppConfigImportData> {

    private final Integer companyId;
    private final String adminName;
    private final AppConfigService appConfigService;
    private Set<String> packageNameSet;
    /**
     * 缓存的数据
     */
    private List<AppConfigImportData> list = Lists.newArrayListWithCapacity(64);

    public AppConfigImportDataListener(Integer companyId, String adminName, AppConfigService appConfigService) {
        this.companyId = companyId;
        this.adminName = adminName;
        this.appConfigService = appConfigService;
        this.packageNameSet = initData();
    }

    @Override
    public void invoke(AppConfigImportData data, AnalysisContext analysisContext) {
        log.info("应用配置解析到一条数据:{}", JSONUtil.toJsonStr(data));
        if (StringUtils.isBlank(data.getAppName())) {
            log.info("应用名为空");
            return;
        }
        if (StringUtils.isBlank(data.getPackageName())) {
            log.info("包名为空");
            return;
        }
        if (!Pattern.matches(RegexConstants.PACKAGE_NAME_REGEX, data.getPackageName())) {
            log.info("包名格式错误");
            return;
        }
        // 重复校验
        String packageName = data.getPackageName();
        if (StringUtils.isNotBlank(data.getAppSign())) {
            packageName = packageName + data.getAppSign();
        }
        if (CollectionUtils.isNotEmpty(packageNameSet) && packageNameSet.contains(packageName)) {
            log.info("包名重复：{}", packageName);
            return;
        }
        packageNameSet.add(packageName);
        list.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("应用配置导入{}条数据，开始存储数据库！", list.size());
        save();
        packageNameSet.clear();
        log.info("存储数据库成功！");
    }

    private void save() {
        if (CollectionUtils.isNotEmpty(list)) {
            List<AppConfigDO> appConfigDOList = list.stream()
                    .map(data -> AppConfigDO.builder()
                            .appName(data.getAppName())
                            .packageName(data.getPackageName())
                            .appSign(data.getAppSign())
                            .operator(adminName)
                            .companyId(companyId)
                            .build())
                    .collect(Collectors.toList());
            appConfigService.saveBatch(appConfigDOList);
        }
    }

    private Set<String> initData() {
        return new LambdaQueryChainWrapper<>(appConfigService.getBaseMapper())
                .eq(AppConfigDO::getCompanyId, companyId)
                .list()
                .stream()
                .map(appConfigDO -> {
                    if (StringUtils.isBlank(appConfigDO.getAppSign())) {
                        return appConfigDO.getPackageName();
                    }
                    return appConfigDO.getPackageName() + appConfigDO.getAppSign();
                }).collect(Collectors.toSet());
    }
}
