package com.mortals.xhx.modules.supplement.listener;

import cn.hutool.core.date.DateTime;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSONObject;
import com.mortals.xhx.common.code.SystemConstant;
import com.mortals.xhx.common.utils.DateByAffairUtils;
import com.mortals.xhx.common.utils.SnowFlakeUtil;
import com.mortals.xhx.modules.implementlist.model.ImplementlistEntity;
import com.mortals.xhx.modules.implementlist.service.ImplementlistService;
import com.mortals.xhx.modules.supplement.dao.SupplementDao;
import com.mortals.xhx.modules.supplement.model.SupplementEntity;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author liaoxin
 * @Date: 2021-07-2021/7/30-15:06
 * @Description:
 */
@Slf4j
public class InformationDataConversionListener extends AnalysisEventListener<SupplementEntity> {

    private SupplementDao supplementDao;

    private ImplementlistService implementlistService;

    /**
     * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 3000;

    /**
     * 这个集合用于接收 读取Excel文件得到的数据
     */
    List<SupplementEntity> entityList = new ArrayList<SupplementEntity>();
    //装入当前excel的事项编码
    List<String> eventCodeList = new ArrayList<>();


    public InformationDataConversionListener(SupplementDao supplementDao, ImplementlistService implementlistService) {
        this.supplementDao = supplementDao;
        this.implementlistService = implementlistService;
    }

    //当前系统编码
    private String SYS_CODE = "";
    private String AREA_CODE = "";

    public void currentSystemCode(String sysCode, String areaCode) {
        this.SYS_CODE = sysCode;
        this.AREA_CODE = areaCode;
    }

    //当前系统剩余多少条办件量（可推送的办件量）=固定阈值-已推送办件
    private int FIXED_AMOUNT = 0;

    public int theAmountOfDeliverablesThatCanBePushed(Integer limitTheNumberOfDocuments, int count) {
        return FIXED_AMOUNT = limitTheNumberOfDocuments - count;

    }


    @SneakyThrows
    @Override
    public void invoke(SupplementEntity supplementEntity, AnalysisContext analysisContext) {
        supplementEntity.setId(SnowFlakeUtil.get().nextId());
        String dateTime = "";
        if (SystemConstant.BEOR) {
            dateTime = DateByAffairUtils.randomDate(SystemConstant.DAYS);
        } else {
            dateTime = DateByAffairUtils.randomBetweenDate(SystemConstant.DAYS);
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date dayRadomWorkingTime = DateByAffairUtils.getDayRadomWorkingTime(simpleDateFormat.parse(dateTime), null, null);
        supplementEntity.setApplyTime(simpleDateFormat.format(dayRadomWorkingTime));
        supplementEntity.setSysCode(SYS_CODE);
        supplementEntity.setIsExecute("0");
        supplementEntity.setIsSuccess("0");
        supplementEntity.setCreateDate(DateTime.now());
        supplementEntity.setUpdateDate(supplementEntity.getCreateDate());
        entityList.add(supplementEntity);
        eventCodeList.add(supplementEntity.getImplCode());
        if (entityList.size() > FIXED_AMOUNT) {
            throw new RuntimeException("数据上传失败，失败原因: 今日推送量已超过5000，请明天再试");
        } else {
            //达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
            if (entityList.size() >= BATCH_COUNT) {
                //判断当前上传的excel表格中那些是非本区域的办件
                Map<String, Object> stringObjectMap = judgeTheProcessingArea(eventCodeList, AREA_CODE);
                //判断当前是否还有数据，如果有数据，则表明当前map存在非本区域办件，则抛出异常
                boolean easyToUseValue = stringObjectMap.get("boolean") != null ? false : true;
                if (easyToUseValue) {
                    supplementDao.insertBatch(entityList);
                    //存储完成清理list
                    entityList.clear();
                } else {
                    throw new RuntimeException("当前excel数据存在非本区域办件:" + stringObjectMap);
                }
            }
        }
    }

    private Map<String, Object> judgeTheProcessingArea(List<String> eventCodeList, String areaCode) {
        String shardKey = areaCode.substring(0, 4);
        Map<String, Object> objectHashMap = new HashMap<>();
        List<Object> objects =new ArrayList<>();
        for (String eventCode : eventCodeList) {
            //装入非本区域办件
            //装入符合条件的办件信息
            Map<String, String> stringStringHashMap = new HashMap<>();
            ImplementlistEntity thImplement = implementlistService.getThImplement(eventCode);
            if (!shardKey.equals(thImplement.getShardKey())) {
                stringStringHashMap.put("eventName", thImplement.getEventName());
                stringStringHashMap.put("eventCode", thImplement.getEventCode());
                objects.add(stringStringHashMap);
            }
        }
        if (objects.size() > 0) {
            objectHashMap.put("affairs", objects);
        }
        if (objectHashMap.size() > 0) {
            objectHashMap.put("code", "500");
            objectHashMap.put("boolean", false);
        } else {
            objectHashMap.put("boolean", null);
        }
        return objectHashMap;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //判断当前上传的excel表格中那些是非本区域的办件
        Map<String, Object> stringObjectMap = judgeTheProcessingArea(eventCodeList, AREA_CODE);
        //判断当前是否还有数据，如果有数据，则表明当前map存在非本区域办件，则抛出异常
        boolean easyToUseValue = stringObjectMap.get("boolean") != null ? false : true;
        if (easyToUseValue) {
            supplementDao.insertBatch(entityList);
        } else {
            throw new RuntimeException("当前excel数据存在非本区域办件:" + JSONObject.toJSONString(stringObjectMap));
        }
        log.info("=======办件数据导入成功===========");
    }

}

