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

import cn.cecep.talroad.domain.*;
import cn.cecep.talroad.domain.analysis.SRaActionReportsAuditRecord;
import cn.cecep.talroad.domain.analysis.SRaActionReportsAuditResult;
import cn.cecep.talroad.domain.analysis.SRaSelfMonitoringData;
import cn.cecep.talroad.enums.EmlTypeEnums;
import cn.cecep.talroad.enums.ProblemTypeEnum;
import cn.cecep.talroad.mapper.*;
import cn.cecep.talroad.mapper.analysis.SRaActionReportsAuditRecordMapper;
import cn.cecep.talroad.mapper.analysis.SRaActionReportsAuditResultMapper;
import cn.cecep.talroad.service.impl.SEnvGasRealServiceImpl;
import cn.cecep.talroad.service.impl.SEnvWaterMonRealServiceImpl;
import cn.cecep.talroad.util.DateUtil;
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.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 任务 66 差异 20%
 */
@Slf4j
@Service
public class ExcessiveDifferenceService {

    @Autowired
    private SEnvGasMonHourMapper sEnvGasMonHourMapper;

    @Autowired
    private SEnvWaterMonDayMapper sEnvWaterMonDayMapper;

    @Autowired
    private BStatTableZxbgPflAirMapper bStatTableZxbgPflAirMapper;

    @Autowired
    private BStatTableZxbgPflWaterMapper bStatTableZxbgPflWaterMapper;

    @Autowired
    private BMainActionReportsMapper actionReportsMapper;

    @Autowired
    private SRaActionReportsAuditResultMapper mapper;

    @Autowired
    private SRaActionReportsAuditRecordMapper recordMapper;

    public void execute(List<String> reportIds){
        //复杂 无法批量  直接遍历报告id 进行审核
        LambdaQueryWrapper<BMainActionReports> queryWrapper = new QueryWrapper<BMainActionReports>().lambda()
                .in(BMainActionReports::getId, reportIds);
        List<BMainActionReports> bMainActionReports = actionReportsMapper.selectList(queryWrapper);
        for (BMainActionReports bMainActionReport : bMainActionReports) {
            String factoryId = bMainActionReport.getFactoryId();
            String reportsType = bMainActionReport.getReportsType();//EmlTypeEnums
            //根据 企业id 加 报告周期 查询到对应报警信息表 是否有超标信息
            //按照报表审核类型的时间 为 查询数据开始的时间
            Calendar startCalendar = Calendar.getInstance();
            Calendar endCalendar = Calendar.getInstance();
            if (EmlTypeEnums.YEAR.getCode().equals(reportsType)) {
                //去年 开始的数据 到今年的数据
                startCalendar.setTime(DateUtil.parseTime(startCalendar.get(Calendar.YEAR) - 1 + "-01-01 00:00:00"));
                endCalendar.setTime(DateUtil.parseTime(endCalendar.get(Calendar.YEAR) + "-01-01 00:00:00"));
            }else if (EmlTypeEnums.QUARTER.getCode().equals(reportsType)) {
                //获取上季度的数据 此处获取到当前季度开始的日期 手动去-3月 上季度结束日期 就是本季度开始
                startCalendar.setTime(DateUtil.getQuarterStart(new Date()));
                startCalendar.set(Calendar.MONTH,startCalendar.get(Calendar.MONTH) - 3);
                endCalendar.setTime(DateUtil.getQuarterStart(new Date()));
            }else if (EmlTypeEnums.MONTH.getCode().equals(reportsType)) {
                //上月开始 到 这月结束的数据
                startCalendar.set(Calendar.DAY_OF_MONTH,0);
                DateUtil.setTimeZero(startCalendar);
                endCalendar.set(Calendar.DAY_OF_MONTH,1);
                DateUtil.setTimeZero(endCalendar);
                startCalendar.set(Calendar.MONTH,startCalendar.get(Calendar.MONTH) - 1);
            }
            Date endTime = endCalendar.getTime();
            Date startTime = startCalendar.getTime();

            // 获取水污染物
            LambdaQueryWrapper<BStatTableZxbgPflWater> bStatTableZxbgPflWaterLambdaQueryWrapper = new QueryWrapper<BStatTableZxbgPflWater>().lambda()
                    .eq(BStatTableZxbgPflWater::getZxbgPeriod, bMainActionReport.getReportsTime())
                    .eq(BStatTableZxbgPflWater::getFactoryId, bMainActionReport.getFactoryId());
            List<BStatTableZxbgPflWater> bStatTableZxbgPflWaters = bStatTableZxbgPflWaterMapper.selectList(bStatTableZxbgPflWaterLambdaQueryWrapper);

            if (CollectionUtils.isNotEmpty(bMainActionReports)){


                LambdaQueryWrapper<SEnvWaterMonDay> sEnvWaterMonDayLambdaQueryWrapper = new QueryWrapper<SEnvWaterMonDay>().lambda()
                        .eq(SEnvWaterMonDay::getFactoryId, factoryId)
                        .ge(SEnvWaterMonDay::getCreateTime,startTime)
                        .le(SEnvWaterMonDay::getCreateTime,endTime);
                List<SEnvWaterMonDay> sEnvWaterMonDays = sEnvWaterMonDayMapper.selectList(sEnvWaterMonDayLambdaQueryWrapper);
                for (BStatTableZxbgPflWater bStatTableZxbgPflWater : bStatTableZxbgPflWaters) {

                    String zxbgPollutant = bStatTableZxbgPflWater.getZxbgPollutant();
                    SEnvWaterMonRealServiceImpl.PollutantEnum pollutantEnum = null;
                    for (SEnvWaterMonRealServiceImpl.PollutantEnum value : SEnvWaterMonRealServiceImpl.PollutantEnum.values()) {
                        if (value.label.equals(zxbgPollutant)){
                            pollutantEnum = value;
                        }
                    }

                    if (pollutantEnum!=null){
                        Class<SEnvWaterMonDay> sEnvWaterMonDayClass = SEnvWaterMonDay.class;
                        BigDecimal bigDecimal = new BigDecimal(0);
                        for (SEnvWaterMonDay sEnvWaterMonDay : sEnvWaterMonDays) {

                            try {
                                Field field = sEnvWaterMonDayClass.getDeclaredField(pollutantEnum.prop);
                                field.setAccessible(true);
                                BigDecimal bigDecimalWater = (BigDecimal) field.get(sEnvWaterMonDay);
                                if (bigDecimalWater!=null){
                                    bigDecimal.add(bigDecimal);
                                }
                            } catch (NoSuchFieldException | IllegalAccessException e) {
                                log.error("字段 : {} , 不存在",pollutantEnum.prop);
                                e.printStackTrace();
                            }

                        }

                        String zxbgDischargeActual = bStatTableZxbgPflWater.getZxbgDischargeActual();
                        if (StringUtils.isNotBlank(zxbgDischargeActual)){
                            BigDecimal actual = new BigDecimal(zxbgDischargeActual);

                            BigDecimal subtract = bigDecimal.subtract(actual);
                            BigDecimal divide = subtract.divide(bigDecimal);
                            if (divide.doubleValue()>20||divide.doubleValue()<-20){

                                updateReportAuditData(bMainActionReport.getId() , bStatTableZxbgPflWater.getZxbgOutletCode(),bStatTableZxbgPflWater.getZxbgPollutant() , bigDecimal.toString() , actual.toString());

                            }

                        }

                    }

                }

            }

            // 获取气污染物
            LambdaQueryWrapper<BStatTableZxbgPflAir> bStatTableZxbgPflAirLambdaQueryWrapper = new QueryWrapper<BStatTableZxbgPflAir>().lambda()
                    .eq(BStatTableZxbgPflAir::getZxbgPeriod, bMainActionReport.getReportsTime())
                    .eq(BStatTableZxbgPflAir::getFactoryId, bMainActionReport.getFactoryId());
            List<BStatTableZxbgPflAir> bStatTableZxbgPflAirs = bStatTableZxbgPflAirMapper.selectList(bStatTableZxbgPflAirLambdaQueryWrapper);
            if (CollectionUtils.isNotEmpty(bStatTableZxbgPflAirs)){


                LambdaQueryWrapper<SEnvGasMonHour> sEnvWaterMonDayLambdaQueryWrapper = new QueryWrapper<SEnvGasMonHour>().lambda()
                        .eq(SEnvGasMonHour::getFactoryId, factoryId)
                        .ge(SEnvGasMonHour::getCreateTime,startTime)
                        .le(SEnvGasMonHour::getCreateTime,endTime);
                List<SEnvGasMonHour> sEnvGasMonHours = sEnvGasMonHourMapper.selectList(sEnvWaterMonDayLambdaQueryWrapper);
                for (BStatTableZxbgPflAir bStatTableZxbgPflAir : bStatTableZxbgPflAirs) {

                    String zxbgPollutant = bStatTableZxbgPflAir.getZxbgPollutant();
                    SEnvGasRealServiceImpl.PollutantEnum pollutantEnum = null;
                    for (SEnvGasRealServiceImpl.PollutantEnum value : SEnvGasRealServiceImpl.PollutantEnum.values()) {
                        if (value.label.equals(zxbgPollutant)){
                            pollutantEnum = value;
                        }
                    }

                    if (pollutantEnum!=null){
                        Class<SEnvWaterMonDay> sEnvWaterMonDayClass = SEnvWaterMonDay.class;
                        BigDecimal bigDecimal = new BigDecimal(0);
                        for (SEnvGasMonHour sEnvGasMonHour : sEnvGasMonHours) {

                            try {
                                Field field = sEnvWaterMonDayClass.getDeclaredField(pollutantEnum.prop);
                                field.setAccessible(true);
                                BigDecimal bigDecimalWater = (BigDecimal) field.get(sEnvGasMonHour);
                                if (bigDecimalWater!=null){
                                    bigDecimal.add(bigDecimal);
                                }
                            } catch (NoSuchFieldException | IllegalAccessException e) {
                                log.error("字段 : {} , 不存在",pollutantEnum.prop);
                                e.printStackTrace();
                            }

                        }

                        String zxbgDischargeActual = bStatTableZxbgPflAir.getZxbgDischargeActual();
                        if (StringUtils.isNotBlank(zxbgDischargeActual)){
                            BigDecimal actual = new BigDecimal(zxbgDischargeActual);

                            BigDecimal subtract = bigDecimal.subtract(actual);
                            BigDecimal divide = subtract.divide(bigDecimal);
                            if (divide.doubleValue()>20||divide.doubleValue()<-20){

                                updateReportAuditData(bMainActionReport.getId() , bStatTableZxbgPflAir.getZxbgOutletCode(),bStatTableZxbgPflAir.getZxbgPollutant() , bigDecimal.toString() , actual.toString());

                            }

                        }

                    }

                }

            }

        }
    }

    public void updateReportAuditData(String problemReportId,String outletCode, String pollutantsName,String business , String reality){
        LambdaQueryWrapper<SRaActionReportsAuditRecord> recordQueryWrapper = new QueryWrapper<SRaActionReportsAuditRecord>()
                .lambda()
                .select(SRaActionReportsAuditRecord::getId,SRaActionReportsAuditRecord::getReportId)
                .eq(SRaActionReportsAuditRecord::getReportId, problemReportId);
        List<SRaActionReportsAuditRecord> sRaActionReportsAuditRecords = recordMapper.selectList(recordQueryWrapper);
        if (CollectionUtil.isEmpty(sRaActionReportsAuditRecords)){
            log.warn("执行报告审核记录不存在！");
            return;
        }
        List<String> recordIds = sRaActionReportsAuditRecords.stream().map(SRaActionReportsAuditRecord::getId).collect(Collectors.toList());
        LambdaQueryWrapper<SRaActionReportsAuditResult> queryWrapper = new QueryWrapper<SRaActionReportsAuditResult>().lambda().in(SRaActionReportsAuditResult::getRecordId, recordIds);
        List<SRaActionReportsAuditResult> sRaActionReportsAuditResults = mapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(sRaActionReportsAuditResults)){
            log.warn("执行报告规范性审核结果记录不存在！");
            return;
        }
        //“排口编号”“污染物种类”根据在线监测及手工监测核算排放量为“xxxkg"，企业填报实际排放量"xxxkg",差异超过20%，请进一步核实。
        sRaActionReportsAuditResults.forEach(data -> data.setExcessiveEmissions("“"+outletCode+"”“"+pollutantsName+"”根据在线监测及手工监测核算排放量为"+"“"+business+"”"+"企业填报实际排放量"+"“"+reality+"”"+"，差异超过20%，请进一步核实。"));
        mapper.batchUpdate(sRaActionReportsAuditResults);
    }

}
