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

import cn.cecep.talroad.domain.PcLabel;
import cn.cecep.talroad.domain.PcLabelFactory;
import cn.cecep.talroad.domain.analysis.SRaActionReportsActualEmissions;
import cn.cecep.talroad.enums.LabelFactoryEnum;
import cn.cecep.talroad.enums.LabelValueEnum;
import cn.cecep.talroad.enums.TimeTypeEnum;
import cn.cecep.talroad.mapper.PcLabelFactoryMapper;
import cn.cecep.talroad.mapper.PcLabelMapper;
import cn.cecep.talroad.mapper.analysis.SRaActionReportsActualEmissionsMapper;
import cn.cecep.talroad.util.DateUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author hehongyu
 * @description: 计算每个污染物实际排放量与许可证排放量的差距
 * @date 2023/7/17 22:28
 */
@Slf4j
@Service
public class GapLabelTaskService {

    @Autowired
    private SRaActionReportsActualEmissionsMapper mapper;

    @Autowired
    private PcLabelMapper labelMapper;

    @Autowired
    private PcLabelFactoryMapper labelFactoryMapper;

    public void execute(){

        //执行方法
        LambdaQueryWrapper<SRaActionReportsActualEmissions> query = new LambdaQueryWrapper<SRaActionReportsActualEmissions>()
                //分析频次
                .eq(SRaActionReportsActualEmissions::getReportType, TimeTypeEnum.MONTH.getCode())
                .eq(SRaActionReportsActualEmissions::getReportTime, DateUtil.format(DateUtil.getDayOfMonth(-1),"yyyy-MM"));

        List<SRaActionReportsActualEmissions> queryList = mapper.selectList(query);
        if (CollectionUtil.isEmpty(queryList)){
            return;
        }
        //根据企业id分组
        Map<String, List<SRaActionReportsActualEmissions>> groupDataMap =
                queryList.stream().collect(Collectors.groupingBy(SRaActionReportsActualEmissions::getFactoryId));
        //企业id 与 标签code 映射map
        Map<String, String> factoryIdLabelMap = new HashMap<>();
        for (Map.Entry<String, List<SRaActionReportsActualEmissions>> entry : groupDataMap.entrySet()) {
            List<SRaActionReportsActualEmissions> value = entry.getValue();
            List<BigDecimal> labelValues = new ArrayList<>();
            for (SRaActionReportsActualEmissions data : value) {
                //只保留最大的标签
                //实际排放
                BigDecimal actualEmissions = data.getActualEmissions();
                if (actualEmissions == null){
                    log.warn("企业执行报告实际排放 实际排放无数据！id:{}",data.getId());
                    continue;
                }
                //许可排放
                BigDecimal permittedEmissions = data.getPermittedEmissions();
                if (permittedEmissions == null){
                    log.warn("企业执行报告实际排放 许可排放无数据！id:{}",data.getId());
                    continue;
                }
                //计算公式=（实际-许可）/许可*100
                BigDecimal subtract = actualEmissions.subtract(permittedEmissions);
                BigDecimal labelValue = subtract.divide(permittedEmissions).multiply(new BigDecimal(100));
                labelValues.add(labelValue);
            }
            if (CollectionUtil.isEmpty(labelValues)){
                log.warn("labelValues is empty");
                continue;
            }
            labelValues.sort(BigDecimal::compareTo);
            //升序排序 取最大记录标签
            BigDecimal maxLabelValue = labelValues.get(labelValues.size()-1);
            LabelValueEnum labelValueEnum = intervalJudgment(maxLabelValue);
            factoryIdLabelMap.put(entry.getKey(),labelValueEnum.getArgumentsCode());
        }
        batchCreateLabelFactory(factoryIdLabelMap);
    }

    @Transactional(rollbackFor = Exception.class)
    public void batchCreateLabelFactory(Map<String, String> factoryIdLabelMap){
        ArrayList<String> labelCodes = new ArrayList<>();
        labelCodes.add(LabelFactoryEnum.PF024.getEnumId());
        labelCodes.add(LabelFactoryEnum.PF025.getEnumId());
        labelCodes.add(LabelFactoryEnum.PF026.getEnumId());
        List<PcLabel> labelList = labelMapper.selectList(
                new QueryWrapper<PcLabel>().lambda().in(PcLabel::getLabelCode,labelCodes)
        );
        Map<String, String> labelMap =
                labelList.stream().collect(Collectors.toMap(PcLabel::getLabelCode, PcLabel::getId));
        ArrayList<PcLabelFactory> pcLabelFactories = new ArrayList<>();
        for (Map.Entry<String, String> entry : factoryIdLabelMap.entrySet()) {
            String labelMapValue = null;
            if (LabelValueEnum.CODE_1060.getArgumentsCode().equals(entry.getValue())){
                labelMapValue = labelMap.get(LabelFactoryEnum.PF024.getEnumId());
            }else if (LabelValueEnum.CODE_1061.getArgumentsCode().equals(entry.getValue())){
                labelMapValue = labelMap.get(LabelFactoryEnum.PF025.getEnumId());
            }else{
                labelMapValue = labelMap.get(LabelFactoryEnum.PF026.getEnumId());
            }
            if (StringUtils.isBlank(labelMapValue)){
                continue;
            }
            PcLabelFactory pcLabelFactory = buildPcLabelFactory(entry.getKey(), labelMapValue, entry.getValue());
            pcLabelFactories.add(pcLabelFactory);
        }
        //查询对应企业 和 标签 是否存在 存在修改 不存在新增
        LambdaQueryWrapper<PcLabelFactory> wrapper = Wrappers.<PcLabelFactory>lambdaQuery()
                .in(PcLabelFactory::getFactoryId, pcLabelFactories.stream().map(PcLabelFactory::getFactoryId).collect(Collectors.toList()))
                .in(PcLabelFactory::getLabelId, labelMap.values());
        //删除原本的对应标签 和 企业的 关联关系
        labelFactoryMapper.delete(wrapper);
        //重新添加新的企业 标签 关联关系
        if (CollectionUtil.isNotEmpty(pcLabelFactories)){
            labelFactoryMapper.batchSave(pcLabelFactories);
        }
    }

    /**
     * 构建企业标签关联关系实体
     */
    private PcLabelFactory buildPcLabelFactory(String factoryId, String labelId, String labelValue){
        PcLabelFactory pcLabelFactory = new PcLabelFactory();
        pcLabelFactory.setId(UUID.randomUUID().toString());
        pcLabelFactory.setFactoryId(factoryId);
        pcLabelFactory.setLabelId(labelId);
        pcLabelFactory.setLabelValue(labelValue);
        pcLabelFactory.setLableUseing("0");
        return pcLabelFactory;
    }
    /**
     * 判断标签区间
     */
    public LabelValueEnum intervalJudgment(BigDecimal maxLabelValue){
        int intValue = maxLabelValue.intValue();
        if (intValue < 10){
            return null;
        }
        if (intValue <= 30){
            return LabelValueEnum.CODE_1060;
        }
        if (intValue <= 50){
            return LabelValueEnum.CODE_1061;
        }
        return LabelValueEnum.CODE_1062;
    }

}
