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

import cn.cecep.talroad.domain.BMainActionReports;
import cn.cecep.talroad.domain.BMainPollDisSelfMon;
import cn.cecep.talroad.domain.BStatTableZxbgGasEmissionStatistics;
import cn.cecep.talroad.domain.analysis.SRaActionReportsAuditRecord;
import cn.cecep.talroad.domain.analysis.SRaActionReportsAuditResult;
import cn.cecep.talroad.enums.EmlTypeEnums;
import cn.cecep.talroad.mapper.BMainActionReportsMapper;
import cn.cecep.talroad.mapper.BMainPollDisSelfMonMapper;
import cn.cecep.talroad.mapper.BStatTableZxbgGasEmissionStatisticsMapper;
import cn.cecep.talroad.mapper.analysis.SRaActionReportsAuditRecordMapper;
import cn.cecep.talroad.mapper.analysis.SRaActionReportsAuditResultMapper;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author hehongyu
 * @description: （正常监测时段）无组织废气污染物排放浓度监测数据统计表
 * @date 2023/8/12 17:06
 */
@Slf4j
@Service
public class FugitiveExhaustPollutantsService {
    @Autowired
    private BMainActionReportsMapper actionReportsMapper;

    @Autowired
    private BMainPollDisSelfMonMapper pollDisSelfMonMapper;

    @Autowired
    private BStatTableZxbgGasEmissionStatisticsMapper statTableZxbgGasEmissionStatisticsMapper;

    @Autowired
    private SRaActionReportsAuditResultMapper auditResultMapper;

    @Autowired
    private SRaActionReportsAuditRecordMapper recordMapper;

    public void execute(List<String> reportIds){
        //复杂 无法批量  直接遍历报告id 进行审核
        LambdaQueryWrapper<BMainActionReports> reportQueryWrapper = new QueryWrapper<BMainActionReports>().lambda()
                .in(BMainActionReports::getId, reportIds);
        List<BMainActionReports> bMainActionReports = actionReportsMapper.selectList(reportQueryWrapper);
        List<SRaActionReportsAuditResult> updateList = new ArrayList<>();
        //执行报告id 和 执行报告审核结果的映射关系
        Map<String, SRaActionReportsAuditResult> reportRecordMap = getReportRecordMap(reportIds);
        for (BMainActionReports bMainActionReport : bMainActionReports) {
            String factoryId = bMainActionReport.getFactoryId();
            String reportsType = bMainActionReport.getReportsType();//EmlTypeEnums
            //根据企业查询到所有频次 然后根据 报告类型判断 生产设施/无组织排放编号要用许可系统的无组织编号全部查一下 以排污许可自行监测为主表进行判断
            LambdaQueryWrapper<BMainPollDisSelfMon> pollQueryWrapper = new QueryWrapper<BMainPollDisSelfMon>().lambda()
                    .select(BMainPollDisSelfMon::getFactoryId, BMainPollDisSelfMon::getOutletCode, BMainPollDisSelfMon::getPollutantType)
                    .eq(BMainPollDisSelfMon::getFactoryId, factoryId);
            List<BMainPollDisSelfMon> bMainPollDisSelfMons = pollDisSelfMonMapper.selectList(pollQueryWrapper);
            if (CollectionUtil.isEmpty(bMainPollDisSelfMons)){
                log.warn("bMainActionReport:{} 无自行监测频率数据！", JSON.toJSONString(bMainActionReport));
                continue;
            }
            Map<String, Integer> shouldDatCountMap = new HashMap<>();
            //需要建立一个 排放口编号-污染物种类：检测频率 的映射
            for (BMainPollDisSelfMon bMainPollDisSelfMon : bMainPollDisSelfMons) {
                String monitoringManualFrequency = bMainPollDisSelfMon.getMonitoringManualFrequency();
                //如果是年报则判断 手工检测频次1年1次 或者1季度1次*4 或者1月一次*12 就是 需要填报数据的总次数
                int count = getCount(monitoringManualFrequency, reportsType);
                //此处能获取到排口-污染物：报表对应需要检测的次数
                shouldDatCountMap.put(buildKey(bMainPollDisSelfMon.getOutletCode(),bMainPollDisSelfMon.getPollutantType()),count);
            }
            for (Map.Entry<String, Integer> entry : shouldDatCountMap.entrySet()) {
                String outletCode = getOutletCodeByKey(entry.getKey());
                String pollutantType = getPollutantTypeByKey(entry.getKey());
                //需要根据排口编号 和 污染物种类 去对比 报告实际填报了多少数据
                LambdaQueryWrapper<BStatTableZxbgGasEmissionStatistics> queryWrapper = new QueryWrapper<BStatTableZxbgGasEmissionStatistics>().lambda()
                        .eq(BStatTableZxbgGasEmissionStatistics::getFactoryId, factoryId)
                        .eq(BStatTableZxbgGasEmissionStatistics::getZxbgType, reportsType)
                        .eq(BStatTableZxbgGasEmissionStatistics::getFacilitiesCode, outletCode)
                        .eq(BStatTableZxbgGasEmissionStatistics::getZxbgPollutantType, pollutantType);
                List<BStatTableZxbgGasEmissionStatistics> dataList = statTableZxbgGasEmissionStatisticsMapper.selectList(queryWrapper);
                if (CollectionUtil.isEmpty(dataList)){
                    log.warn("执行报告--无组织废气污染物排放浓度监测数据统计对象 排口code:{}，污染物种类:{}，无对应数据！",outletCode,pollutantType);
                    continue;
                }
                //除了判断频次是否达标外   还需要判断是否超标
                for (BStatTableZxbgGasEmissionStatistics data : dataList) {
                    boolean isUpdate = false;
                    SRaActionReportsAuditResult sRaActionReportsAuditResult = reportRecordMap.get(bMainActionReport.getId());
                    if (sRaActionReportsAuditResult == null){
                        continue;
                    }
                    Long monitoringNumber = data.getMonitoringNumber();
                    if (monitoringNumber < entry.getValue()){
                        //不满足 规范
                        sRaActionReportsAuditResult.setMonitoringFrequency("“"+outletCode+"”监测“"+pollutantType+"”的监测频次为“"+entry.getValue()+"”，本次填报数据"+monitoringNumber+"条，缺失"+(entry.getValue().longValue()-monitoringNumber)+"条");
                        isUpdate = true;
                    }
                    //浓度监测结果
                    BigDecimal result = new BigDecimal(data.getMonitoringResultsHour());
                    //许可浓度
                    BigDecimal emission = new BigDecimal(data.getEmissionConcentration());
                    if (result.compareTo(emission) > 0 && !"1".equals(data.getIsExceeded())){
                        //结果 > 许可 但是 报告超标 是不规范的
                        sRaActionReportsAuditResult.setExcessiveEmissions("“"+outletCode+"“"+pollutantType+"” 浓度监测结果与是否超标及超标原因不对应");
                        isUpdate = true;
                    }
                    if (isUpdate){
                        updateList.add(sRaActionReportsAuditResult);
                    }
                }
            }
        }
        //修改审核结果
        if (CollectionUtil.isNotEmpty(updateList)){
            auditResultMapper.batchUpdate(updateList);
        }
    }

    public Map<String,SRaActionReportsAuditResult> getReportRecordMap(List<String> reportIds){
        LambdaQueryWrapper<SRaActionReportsAuditRecord> recordQueryWrapper = new QueryWrapper<SRaActionReportsAuditRecord>()
                .lambda()
                .select(SRaActionReportsAuditRecord::getId,SRaActionReportsAuditRecord::getReportId)
                .in(SRaActionReportsAuditRecord::getReportId, reportIds);
        List<SRaActionReportsAuditRecord> sRaActionReportsAuditRecords = recordMapper.selectList(recordQueryWrapper);
        if (CollectionUtil.isEmpty(sRaActionReportsAuditRecords)){
            log.warn("执行报告审核记录不存在！");
            return null;
        }
        List<String> recordIds = sRaActionReportsAuditRecords.stream().map(SRaActionReportsAuditRecord::getId).collect(Collectors.toList());
        Map<String, String> recordReportIdMap = sRaActionReportsAuditRecords.stream().collect(Collectors.toMap(SRaActionReportsAuditRecord::getId, SRaActionReportsAuditRecord::getReportId));
        LambdaQueryWrapper<SRaActionReportsAuditResult> queryWrapper = new QueryWrapper<SRaActionReportsAuditResult>().lambda().in(SRaActionReportsAuditResult::getRecordId, recordIds);
        List<SRaActionReportsAuditResult> sRaActionReportsAuditResults = auditResultMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(sRaActionReportsAuditResults)){
            log.warn("执行报告规范性审核结果记录不存在！");
            return null;
        }
        return sRaActionReportsAuditResults.stream().collect(Collectors.toMap(data -> recordReportIdMap.get(data.getRecordId()), Function.identity()));
    }

    public String buildKey(String outletCode, String pollutantType){
        return outletCode + "-" + pollutantType;
    }

    public String getOutletCodeByKey(String key){
        if (StringUtils.isBlank(key)){
            return null;
        }
        return key.split("-")[0];
    }

    public String getPollutantTypeByKey(String key){
        if (StringUtils.isBlank(key)){
            return null;
        }
        return key.split("-")[1];
    }

    public int getCount(String monitoringManualFrequency, String reportsType){
        if (EmlTypeEnums.YEAR.getCode().equals(reportsType)){
            return getYearCount(monitoringManualFrequency);
        }else if (EmlTypeEnums.QUARTER.getCode().equals(reportsType)){
            //直接拿年的所有频次去除季度
            int yearCount = getYearCount(monitoringManualFrequency);
            //小于12 代表 获取到的是 季度以上的单位
            if (yearCount < 4){
                return 0;
            }
            return yearCount / 4;
        }else if (EmlTypeEnums.MONTH.getCode().equals(reportsType)){
            //直接拿年的所有频次去除月
            int yearCount = getYearCount(monitoringManualFrequency);
            //小于12 代表 获取到的是月度以上的单位
            if (yearCount < 12){
                return 0;
            }
            return yearCount/12;
        }
        return 0;
    }

    public int getYearCount(String monitoringManualFrequency){
        //返回各种频次对应的 一整年需要多少次 此处周按照一年52周 每月5个星期算
        if (monitoringManualFrequency.contains("周")){
            //直接返回52周
            return 52;
        }
        if (monitoringManualFrequency.contains("月")){
            //每年有12个月
            return 12;
        }
        if (monitoringManualFrequency.contains("季")){
            //每年有4个季度
            return 4;
        }
        if (monitoringManualFrequency.contains("半年")){
            //每年有两个半年
            return 2;
        }
        if (monitoringManualFrequency.contains("年")){
            //每年一次
            return 1;
        }
        return 0;
    }
}
