package cn.cecep.talroad.data.analyse.task.execute.report;

import cn.cecep.talroad.common.core.utils.DateUtils;
import cn.cecep.talroad.domain.AmProblemFi;
import cn.cecep.talroad.domain.BStatTableZxbgJbxxInfo;
import cn.cecep.talroad.mapper.BStatTableZxbgJbxxInfoMapper;
import cn.cecep.talroad.service.IAmProblemFiService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: Frank
 * @createTime: 2023年07月25日 15:27:24
 * @version:
 * @Description:
 */
@Service
@AllArgsConstructor
@Slf4j
public class PollutionDischargeProcessServiceImpl implements PollutionDischargeProcessService {

    private final BStatTableZxbgJbxxInfoMapper bStatTableZxbgJbxxInfoMapper;

    private final IAmProblemFiService amProblemFiService;

    private final Integer pageSize = 1000;


    private List<BStatTableZxbgJbxxInfo> queryData() {
        String period = LocalDate.now().minusMonths(1).toString().substring(0, 7);
        List<String> records = Lists.newArrayList("原料", "主要原料用量", "能源消耗", "运行时间和生产负荷", "主要产品产量", "取排水");
        List<BStatTableZxbgJbxxInfo> bStatTableZxbgJbxxInfoList = bStatTableZxbgJbxxInfoMapper.selectByPeriodAndPeriod("0", period, records);
        log.info("查询出排污单位基本信息表数据:{}", bStatTableZxbgJbxxInfoList);
        return bStatTableZxbgJbxxInfoList;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void process() {

        List<AmProblemFi> amProblemFis = Lists.newArrayList();
        PageHelper.startPage(1, pageSize);
        List<BStatTableZxbgJbxxInfo> dataList = queryData();
        PageInfo<BStatTableZxbgJbxxInfo> dataListPage = new PageInfo<>(dataList);
        addProblem(dataListPage.getList(), amProblemFis);
        int pages = dataListPage.getPages();
        if (pages <= 1) {
            //如果只有一页 阻断
            return;
        }
        for (int i = 2; i <= pages; i++) {
            PageHelper.startPage(i, pageSize);
            List<BStatTableZxbgJbxxInfo> data = queryData();
            PageInfo<BStatTableZxbgJbxxInfo> pageInfo = new PageInfo<>(data);
            addProblem(pageInfo.getList(), amProblemFis);
        }

        if (CollUtil.isNotEmpty(amProblemFis)) {
            List<List<AmProblemFi>> partition = ListUtils.partition(amProblemFis, 2000);
            for (List<AmProblemFi> amProblemFi : partition) {
                log.info("---------------:{}", JSON.toJSONString(amProblemFi));
                amProblemFiService.saveBatch(amProblemFi);
            }
        }
    }


    private AmProblemFi buildAmProblemFi(String factoryId, String message) {
        AmProblemFi problemFi = new AmProblemFi();
        problemFi.setId(IdUtil.simpleUUID());
        problemFi.setFactoryId(factoryId);
        problemFi.setType(1);
        problemFi.setCreateTime(new Date());
        problemFi.setInputStartTime(DateUtils.dateTime());
        problemFi.setInputEndTime(DateUtils.dateTime());
        problemFi.setProblemTreatmentState("1");
        problemFi.setProblemDetails(message);
        return problemFi;
    }


    private void addProblem(List<BStatTableZxbgJbxxInfo> bStatTableZxbgJbxxInfos, List<AmProblemFi> amProblemFis) {
        Map<String, List<BStatTableZxbgJbxxInfo>> mapData = bStatTableZxbgJbxxInfos.stream().collect(Collectors.groupingBy(BStatTableZxbgJbxxInfo::getFactoryId));
        for (Map.Entry<String, List<BStatTableZxbgJbxxInfo>> entry : mapData.entrySet()) {
            List<BStatTableZxbgJbxxInfo> value = entry.getValue();
            String factoryId = entry.getKey();
            if (CollUtil.isNotEmpty(value)) {
                List<String> data = entry.getValue().stream().map(BStatTableZxbgJbxxInfo::getZxbgParam).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
                if (isParamAllEmpty(data)) {
                    log.info("企业ID:{},提示语句:{}", factoryId, "未填报排污单位基本信息表");
                    amProblemFis.add(buildAmProblemFi(factoryId, "未填报排污单位基本信息表"));
                    continue;
                }
                Map<String, List<BStatTableZxbgJbxxInfo>> map = value.stream().collect(Collectors.groupingBy(BStatTableZxbgJbxxInfo::getZxbgRecord));
                paramAnyEmpty(map, entry.getKey(), amProblemFis);
                runTimeExceedThreshold(map, factoryId, amProblemFis);
                //TODO  .主要产品产量超过许可证中设计产能
            }
        }
    }

    private void runTimeExceedThreshold(Map<String, List<BStatTableZxbgJbxxInfo>> mapData, String factoryId, List<AmProblemFi> amProblemFis) {
        List<BStatTableZxbgJbxxInfo> infos = mapData.get("运行时间和生产负荷");
        for (BStatTableZxbgJbxxInfo info : infos) {
            if (Objects.nonNull(info) && Objects.nonNull(info.getZxbgNum()) && info.getZxbgNum() > 8760) {
                log.info("企业ID:{},提示语句:{}", factoryId, "生产单元”正常运行时间超过8760小时不规范");
                amProblemFis.add(buildAmProblemFi(factoryId, "生产单元”正常运行时间超过8760小时不规范"));
            }
        }
    }


    private boolean isParamAllEmpty(List<String> stringList) {
        for (String str : stringList) {
            if (!(StringUtils.isEmpty(str) || str.equals("/"))) {
                return false;
            }
        }
        return true;
    }

    private void paramAnyEmpty(Map<String, List<BStatTableZxbgJbxxInfo>> mapData, String factoryId, List<AmProblemFi> amProblemFis) {
        for (Map.Entry<String, List<BStatTableZxbgJbxxInfo>> entry : mapData.entrySet()) {
            List<BStatTableZxbgJbxxInfo> value = entry.getValue();
            for (BStatTableZxbgJbxxInfo bStatTableZxbgJbxxInfo : value) {
                String zxbgParam = bStatTableZxbgJbxxInfo.getZxbgParam();
                if (StringUtils.isEmpty(zxbgParam) || zxbgParam.equals("/")) {
                    log.info("企业ID:{},提示语句:{}", factoryId, "未填报【" + bStatTableZxbgJbxxInfo.getZxbgRecord() + "】排污单位基本信息表");
                    amProblemFis.add(buildAmProblemFi(factoryId, "排污单位基本信息表中" + bStatTableZxbgJbxxInfo.getZxbgRecord() + "未填报数据"));
                }
            }
        }
    }
}
