package cn.cecep.talroad.service.impl;

import cn.cecep.talroad.common.core.web.domain.AjaxResults;
import cn.cecep.talroad.domain.BaseRegionalControlObjectives;
import cn.cecep.talroad.domain.PcLabelValue;
import cn.cecep.talroad.domain.PcPollutant;
import cn.cecep.talroad.mapper.BaseRegionalControlObjectivesMapper;
import cn.cecep.talroad.mapper.PcLabelValueMapper;
import cn.cecep.talroad.mapper.PcPollutantMapper;
import cn.cecep.talroad.service.BaseRegionalControlObjectivesService;
import cn.cecep.talroad.vo.BaseRegionalControlObjectivesVo;
import cn.cecep.talroad.vo.query.BaseRegionalControlObjectivesQuery;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BaseRegionalControlObjectivesServiceImpl implements BaseRegionalControlObjectivesService {

    @Resource
    private BaseRegionalControlObjectivesMapper baseRegionalControlObjectivesMapper;

    @Autowired
    private PcLabelValueMapper pcLabelValueMapper;

    @Autowired
    private PcPollutantMapper pollutantMapper;

    @Override
    public AjaxResults<IPage<BaseRegionalControlObjectivesVo>> selectList(BaseRegionalControlObjectivesQuery query) {
        Page<BaseRegionalControlObjectives> page = new Page<>(query.getPageNum(), query.getPageSize());
        IPage<BaseRegionalControlObjectivesVo> result = baseRegionalControlObjectivesMapper.selectListPage(page, query);
        return  AjaxResults.success(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResults<Boolean> save(List<BaseRegionalControlObjectives> data) {
        Wrapper<BaseRegionalControlObjectives> wrapper=Wrappers.query();
        List<BaseRegionalControlObjectives> baseRegionalControlObjectives =
                baseRegionalControlObjectivesMapper.selectList(wrapper);
        List<BaseRegionalControlObjectives> updataList=new ArrayList<>();
        List<BaseRegionalControlObjectives> addList=new ArrayList<>();
        data.forEach(d->{
            String id = d.getId();
            boolean b = baseRegionalControlObjectives.stream().anyMatch(brco -> brco.getId().equals(id));
            if(b){
                d.setUpdateTime(new Date());
                updataList.add(d);
            }else {
                addList.add(d);
            }
        });
        if(!Collections.isEmpty(updataList)){
            baseRegionalControlObjectivesMapper.updateBatchSelective(updataList);
        }
        if(!Collections.isEmpty(addList)){
            baseRegionalControlObjectivesMapper.batchInsert(addList);
        }
        return AjaxResults.success(true);
    }


    public int updateByPrimaryKeySelective(BaseRegionalControlObjectives record) {
        return baseRegionalControlObjectivesMapper.updateByPrimaryKeySelective(record);
    }

    /**
     * 插入或更新区域管控目标，并根据监测点管控浓度建议排放量更新区域的建议排放量
     */
    @Override
    public void saveOrUpdate() {
        // 查询所有大气管控污染物
        List<PcPollutant> pollutants = pollutantMapper.selectList(new QueryWrapper<PcPollutant>().eq("is_gas_type", "1"));
        if (pollutants.isEmpty()) {
            return;
        }

        // 查询所有区县
        List<PcLabelValue> regionList = pcLabelValueMapper.selectList(new QueryWrapper<PcLabelValue>().eq("label_id", "5"));
        if (regionList.isEmpty()) {
            return;
        }

        // 查询区域的小时建议排放量
        List<BaseRegionalControlObjectives> regionAdviseEmissionsList = baseRegionalControlObjectivesMapper.selectRegionAdviseEmissions();
        Map<String, BaseRegionalControlObjectives> regionAdviseEmissionsMap = regionAdviseEmissionsList.stream()
                .collect(Collectors.toMap(o -> o.getCountryCode() + "_" + o.getPollutantType(), o -> o));

        // 查询已存在的区域管控数据
        List<BaseRegionalControlObjectives> regionPollutantList = baseRegionalControlObjectivesMapper.selectList(new QueryWrapper<>());
        Map<String, BaseRegionalControlObjectives> regionPollMap = regionPollutantList.stream()
                .collect(Collectors.toMap(o -> o.getCountryCode() + "_" + o.getPollutantType(), o -> o));

        List<BaseRegionalControlObjectives> updataList = new ArrayList<>();
        List<BaseRegionalControlObjectives> addList = new ArrayList<>();

        for (PcPollutant pollutant : pollutants) {
            for (PcLabelValue region : regionList) {
                BaseRegionalControlObjectives objectives = regionPollMap.get(region.getArgumentsCode() + "_" + pollutant.getPollCode());

                BaseRegionalControlObjectives regionAdviseEmissions = regionAdviseEmissionsMap.get(region.getArgumentsCode() + "_" + pollutant.getPollCode());

                BigDecimal suggestedEmissions = null;
                if (regionAdviseEmissions != null) {
                    suggestedEmissions = regionAdviseEmissions.getSuggestedEmissions();
                }

                if (objectives == null) {
                    objectives = new BaseRegionalControlObjectives();
                    objectives.setId(UUID.randomUUID().toString());
                    objectives.setCountryCode(region.getArgumentsCode());
                    objectives.setPollutantType(pollutant.getPollCode());
                    objectives.setSuggestedEmissions(suggestedEmissions);
                    objectives.setCreateTime(new Date());
                    addList.add(objectives);
                } else {
                    // 排放量不一致时才添加到更新列表中，这里不关心其余字段
                    if (!ObjectUtil.equals(objectives.getSuggestedEmissions(), suggestedEmissions)) {
                        objectives.setSuggestedEmissions(suggestedEmissions);
                        objectives.setUpdateTime(new Date());
                        updataList.add(objectives);
                    }
                }
            }
        }
        if (!Collections.isEmpty(updataList)) {
            baseRegionalControlObjectivesMapper.updateBatchSuggestedEmissions(updataList);
        }
        if (!Collections.isEmpty(addList)) {
            baseRegionalControlObjectivesMapper.batchInsert(addList);
        }
    }
}
