package cn.cecep.talroad.data.analyse.task.service;

import cn.cecep.talroad.common.core.utils.DateUtils;
import cn.cecep.talroad.data.analyse.task.service.TaskService;
import cn.cecep.talroad.domain.AmProblemFi;
import cn.cecep.talroad.domain.BMainPollDisSelfMon;
import cn.cecep.talroad.domain.PcFactory;
import cn.cecep.talroad.domain.analysis.SRaSelfMonitoringData;
import cn.cecep.talroad.enums.ProblemTypeEnum;
import cn.cecep.talroad.mapper.BMainPollDisSelfMonMapper;
import cn.cecep.talroad.mapper.PcFactoryMapper;
import cn.cecep.talroad.service.IAmProblemFiService;
import cn.cecep.talroad.service.analysis.ISRaSelfMonitoringDataService;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class FrequencyMeasurementTaskService implements TaskService {

    public static String[] fre = new String[]{"1次/月", "1次/年", "1次/半年", "1次/季","1次/周"};
    @Autowired
    private IAmProblemFiService amProblemFiService;
    @Autowired
    private BMainPollDisSelfMonMapper bMainPollDisSelfMonMapper;
    @Autowired
    private PcFactoryMapper pcFactoryMapper;
    @Autowired
    private ISRaSelfMonitoringDataService isRaSelfMonitoringDataService;

    @Override
    public Object mainProcess(Object dto) {
        doProcessGasData();
        doProcessWaterData();
        return null;
    }

    /**
     * 手工监测频次不满足许可证要求-废气
     * @param
     */
    private void doProcessGasData(){
        long startTime = System.currentTimeMillis();
        log.info("手工监测频次不满足许可证要求-废气##开始");
        List<AmProblemFi> mAmProblemFis = new ArrayList<>();
        Arrays.asList(fre).forEach(data->{
            List<BMainPollDisSelfMon>  pollDisList = bMainPollDisSelfMonMapper.selectGasDataList(data);
            pollDisList.forEach(real->{
                Map<DateTime,DateTime> dateMonths = getDateMonths(data);
                // 开始日期、结束日期
                dateMonths.forEach((start,end)->{
                    QueryWrapper<SRaSelfMonitoringData> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("factory_id",real.getFactoryId());
                    queryWrapper.eq("monitoring_name",real.getOutletName());
                    queryWrapper.eq("pollutants_name",real.getPollutantsName());
                    queryWrapper.eq("pollutants_type","2");
                    queryWrapper.between("monitor_time",start,end);
                    int count = isRaSelfMonitoringDataService.count(queryWrapper);
                    if(count==0){
                        PcFactory pcFactory = pcFactoryMapper.selectById(real.getFactoryId());
                        String message = getMessage(
                                pcFactory.getFactoryName(),
                                real.getOutletName(),
                                real.getPollutantsName(),
                                real.getMonitoringManualFrequency(),
                                DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",start),
                                DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",end));
                        AmProblemFi amProblemFi = getMAmProblemFi(real.getFactoryId(), message, real.getOutletName(), real.getPollutantsName(),start,end);
                        mAmProblemFis.add(amProblemFi);
                    }
                });
            });
        });

        if(mAmProblemFis.size()>0){
            List<List<AmProblemFi>> partition = ListUtil.partition(mAmProblemFis,2000);
            partition.forEach(i->{
                amProblemFiService.saveBatch(i);
            });
        }

        long end = System.currentTimeMillis();
        log.info("手工监测频次不满足许可证要求-废气##结束,耗时"+(end-startTime)+"毫秒");
    }

    /**
     * 手工监测频次不满足许可证要求-废水
     */
    private void doProcessWaterData(){
        long startTime = System.currentTimeMillis();
        log.info("手工监测频次不满足许可证要求-废水##开始");
        List<AmProblemFi> mAmProblemFis = new ArrayList<>();
        Arrays.asList(fre).forEach(data-> {
            List<BMainPollDisSelfMon> pollDisList = bMainPollDisSelfMonMapper.selectWaterDataList(data);
            pollDisList.forEach(real->{
                Map<DateTime,DateTime> dateMonths = getDateMonths(data);
                // 开始日期、结束日期
                dateMonths.forEach((start,end)->{
                    QueryWrapper<SRaSelfMonitoringData> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("factory_id",real.getFactoryId());
                    queryWrapper.eq("monitoring_name",real.getOutletName());
                    queryWrapper.eq("pollutants_name",real.getPollutantsName());
                    queryWrapper.eq("pollutants_type","1");
                    queryWrapper.between("monitor_time",start,end);
                    int count = isRaSelfMonitoringDataService.count(queryWrapper);
                    if(count==0){
                        PcFactory pcFactory = pcFactoryMapper.selectById(real.getFactoryId());
                        String message = getMessage(
                            pcFactory.getFactoryName(),
                            real.getOutletName(),
                            real.getPollutantsName(),
                            real.getMonitoringManualFrequency(),
                            DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",start),
                            DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",end));
                        AmProblemFi amProblemFi = getMAmProblemFi(real.getFactoryId(), message, real.getOutletName(), real.getPollutantsName(),start,end);
                        mAmProblemFis.add(amProblemFi);
                    }
                });
            });
        });
        if(mAmProblemFis.size()>0){
            List<List<AmProblemFi>> partition = ListUtil.partition(mAmProblemFis,2000);
            partition.forEach(i->{
                amProblemFiService.saveBatch(i);
            });
        }
        long end = System.currentTimeMillis();
        log.info("手工监测频次不满足许可证要求-废水##结束,耗时"+(end-startTime)+"毫秒");
    }

    /**
     * 获取日期
     * @param data
     * @return
     */
    private Map<DateTime,DateTime> getDateMonths(String data) {
        Date lastMonth = DateUtils.addDateMonths(new Date(),-1);
        Map<DateTime,DateTime> mp = new HashMap<>();
        DateTime startDate = null;
        DateTime endDate = null;
        if(FrequencyEnum.MONTH.code.equals(data)){
            startDate = DateUtil.beginOfMonth(lastMonth);
            endDate = DateUtil.endOfMonth(lastMonth);
            mp.put(startDate,endDate);
        }else if(FrequencyEnum.WEEK.code.equals(data)){
            Date lastWeek1 = DateUtils.addDateWeeks(new Date(),-1);
            Date lastWeek2 = DateUtils.addDateWeeks(new Date(),-2);
            Date lastWeek3 = DateUtils.addDateWeeks(new Date(),-3);
            Date lastWeek4 = DateUtils.addDateWeeks(new Date(),-4);
            DateTime beginWeek1 = DateUtil.beginOfWeek(lastWeek1);
            DateTime endWeek1 = DateUtil.endOfWeek(lastWeek1);
            mp.put(beginWeek1,endWeek1);
            DateTime beginWeek2 = DateUtil.beginOfWeek(lastWeek2);
            DateTime endWeek2 = DateUtil.endOfWeek(lastWeek2);
            mp.put(beginWeek2,endWeek2);
            DateTime beginWeek3 = DateUtil.beginOfWeek(lastWeek3);
            DateTime endWeek3 = DateUtil.endOfWeek(lastWeek3);
            mp.put(beginWeek3,endWeek3);
            DateTime beginWeek4 = DateUtil.beginOfWeek(lastWeek4);
            DateTime endWeek4 = DateUtil.endOfWeek(lastWeek4);
            mp.put(beginWeek4,endWeek4);
        }else if(FrequencyEnum.HALF.code.equals(data)){
            Date lastM = DateUtils.addDateMonths(lastMonth,-6);
            startDate = DateUtil.beginOfMonth(lastM);
            endDate = DateUtil.endOfMonth(lastMonth);
            mp.put(startDate,endDate);
        }else if(FrequencyEnum.QUATER.code.equals(data)){
            startDate = DateUtil.beginOfQuarter(lastMonth);
            endDate = DateUtil.endOfQuarter(lastMonth);
            mp.put(startDate,endDate);
        }else if(FrequencyEnum.YEAR.code.equals(data)){
            startDate = DateUtil.beginOfYear(lastMonth);
            endDate = DateUtil.endOfYear(lastMonth);
            mp.put(startDate,endDate);
        }
        return mp;
    }


    /**
     * 预警报警数据
     * @param factoryId
     * @param problemDetails
     * @param outletCode
     * @param pollutantSourceAi
     * @return
     */
    protected AmProblemFi getMAmProblemFi(String factoryId , String problemDetails , String outletCode , String pollutantSourceAi,Date startDate,Date endDate){
        AmProblemFi mAmProblemFi = new AmProblemFi();
        mAmProblemFi.setFactoryId(factoryId);
        mAmProblemFi.setProblemDetails(problemDetails);
        mAmProblemFi.setStationId(outletCode);
        mAmProblemFi.setPollutantSourceAi(pollutantSourceAi);
        mAmProblemFi.setAnalyseTime(startDate);
        mAmProblemFi.setAnalyseTimeEnd(endDate);
        mAmProblemFi.setProblemType(ProblemTypeEnum.FREQUENCY_MEASUREMENT.getCode());
        mAmProblemFi.setProblemSources("1");
        mAmProblemFi.setCreateTime(new Date());
        return mAmProblemFi;
    }

    /**
     * 获取报警内容
     * “企业名称”“排口名称”“污染物种类”自行监测频次为“监测频次”，“没有数据的时间范围”缺少自行监测数据。
     * @return
     */
    protected String getMessage(String factoryName , String outletName , String pollName , String frequency , String startTime , String endTime){
       return new StringBuilder().append("\"").append(factoryName).append("\"")
                .append("\"").append(outletName).append("\"")
                .append("\"").append(pollName).append("\"")
                .append("自行监测频次为\"").append(frequency).append("\",")
                .append("\"").append(startTime+"-"+endTime).append("\"")
                .append("缺少自行监测数据。").toString();
    }

    private enum FrequencyEnum {
        MONTH("1次/月"),
        YEAR("1次/年"),
        HALF("1次/半年"),
        QUATER("1次/季"),
        WEEK("1次/周");

        FrequencyEnum(String code){
            this.code = code;
        }

        private String code;

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }
    }
}
