/*
 * Author: wangjian
 * 生成ServiceImpl
 */
package com.tofly.xrtygis.custom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tofly.common.core.util.StringUtil;
import com.tofly.xrtygis.custom.entity.Customize;
import com.tofly.xrtygis.custom.entity.dto.CustomizeDto;
import com.tofly.xrtygis.custom.mapper.CustomizeMapper;
import com.tofly.xrtygis.custom.service.CustomizeService;
import com.tofly.xrtygis.custom.util.DateTimeUtil;
import com.tofly.xrtygis.em.Constant;
import com.tofly.xrtygis.entity.DmaStatistical;
import com.tofly.xrtygis.entity.Dmaregion;
import com.tofly.xrtygis.entity.TotalStatistical;
import com.tofly.xrtygis.service.DmaStatisticalService;
import com.tofly.xrtygis.service.DmaregionService;
import com.tofly.xrtygis.service.TotalStatisticalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 自定义指标修正记录表
 *
 * @author admin
 * @date Thu Apr 28 00:00:00 CST 2022
 */
@Service("customizeService")
public class CustomizeServiceImpl extends ServiceImpl<CustomizeMapper, Customize> implements CustomizeService {

    @Autowired
    private DmaStatisticalService dmaStatisticalService;
    @Autowired
    private DmaregionService dmaregionService;
    @Autowired
    private TotalStatisticalService totalStatisticalService;

    @Override
    public Boolean saveInfo(CustomizeDto dto, String flag) {
        String dmaIds = dto.getDmaIds();
        String months = dto.getMonths();
        BigDecimal leakCoefficient = dto.getLeakCoefficient();
        BigDecimal poorProductionCoefficient = dto.getPoorProductionCoefficient();
        if(StringUtil.isEmpty(flag)){
            if(leakCoefficient.compareTo(BigDecimal.ONE)==0 && (poorProductionCoefficient.compareTo(BigDecimal.ONE) ==0)){
                return true;
            }
        }


        // 分区,月份解析
        List<Long> dmaIdList = Arrays.stream(dmaIds.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                .collect(Collectors.toList());
        List<Date> monthList = Arrays.stream(months.split(Constant.CSV)).map(m->DateTimeUtil.localDateToDate(DateTimeUtil.fromString2LocalDate(m.trim(),DateTimeUtil.DAY_FORMAT)))
                .collect(Collectors.toList());
        List<DmaStatistical> list = dmaStatisticalService.list(new QueryWrapper<DmaStatistical>().lambda()
                .in(DmaStatistical::getDmaId, dmaIdList).in(DmaStatistical::getStatisticalDate,monthList));
        // 判断是否存在分区和时间相同的数据,相同则覆盖
        List<Customize> customizes = list(new QueryWrapper<Customize>().lambda().in(Customize::getDmaId, dmaIdList).in(Customize::getReviseDate, monthList));
        Map<Long, Dmaregion> dmaregionMap = dmaregionService.list(new QueryWrapper<Dmaregion>().lambda().in(Dmaregion::getId, dmaIdList)
                .select(Dmaregion::getId, Dmaregion::getDmaName, Dmaregion::getDmaCode, Dmaregion::getPartitionLevel))
                .stream().collect(Collectors.toMap(Dmaregion::getId, m -> m, (key1, key2) -> key2));
        if(null!=list && list.size()>0){
            List<Customize> customizeList = new ArrayList<>();
            // 已有数据
            Map<Long, List<Customize>> listMap = customizes.stream().collect(Collectors.groupingBy(Customize::getDmaId));
            // DMA分组
            Map<Long, List<DmaStatistical>> collect = list.stream().collect(Collectors.groupingBy(DmaStatistical::getDmaId));
            collect.forEach((k,v)->{
                // 已有对象
                Map<Date, List<Customize>> map = new HashMap<>(12);
                if(null!=listMap && listMap.size()>0){
                    List<Customize> customizeMap = listMap.get(k);
                    if(null!=customizeMap && customizeMap.size()>0){
                        map.putAll(customizeMap.stream().collect(Collectors.groupingBy(Customize::getReviseDate)));
                    }

                }
                // 按照时间分组
                Map<Date, List<DmaStatistical>> dateListMap = v.stream().collect(Collectors.groupingBy(DmaStatistical::getStatisticalDate));
                dateListMap.forEach((n,m)->{
                    List<Customize> customizes1 = map.get(n);
                    Customize customize = new Customize();
                    if(null!=customizes1 && customizes1.size()>0){
                        customize.setId(customizes1.get(0).getId());
                    }
                    Dmaregion dmaregion = dmaregionMap.get(k);
                    Integer partitionLevel = dmaregion.getPartitionLevel();
                    customize.setDmaCode(dmaregion.getDmaCode());
                    customize.setDmaName(dmaregion.getDmaName());
                    customize.setDmaLevel(partitionLevel);
                    customize.setDmaId(k);
                    customize.setLeakCorrectionFactor(leakCoefficient);
                    customize.setCxcCorrectionFactor(poorProductionCoefficient);
                    customize.setReviseDate(n);
                    if(null!=m && m.size()>0){
                        // 每个分区每个月份只有一条数据
                        DmaStatistical dmaStatistical = m.get(0);
                        // 计算漏损率
                        BigDecimal pathpatroled = dmaStatistical.getLeakageRate() ==null ?BigDecimal.ZERO:dmaStatistical.getLeakageRate();
                        BigDecimal decimal = pathpatroled == null ? BigDecimal.ZERO:pathpatroled.divide(BigDecimal.valueOf(m.size()), 2, BigDecimal.ROUND_HALF_UP);
                        customize.setBeforLeak(decimal);
                        if(leakCoefficient.compareTo(BigDecimal.ONE)!=0){
                            customize.setAfterLeak(leakCoefficient.multiply(decimal));
                        }else {
                            customize.setAfterLeak(BigDecimal.ZERO);
                        }
                        // 计算产销差
                        BigDecimal poor = dmaStatistical.getPoorProductionRate() ==null?BigDecimal.ZERO:dmaStatistical.getPoorProductionRate();
                        BigDecimal decimal1 = poor == null ? BigDecimal.ZERO:poor.divide(BigDecimal.valueOf(m.size()), 2, BigDecimal.ROUND_HALF_UP);
                        customize.setBeforCxc(decimal1);
                        if(poorProductionCoefficient.compareTo(BigDecimal.ONE)!=0){
                            customize.setAfterCxc(leakCoefficient.multiply(decimal1));
                        }else {
                            customize.setAfterCxc(BigDecimal.ZERO);
                        }
                        if (StringUtil.isEmpty(flag)) {
                            // 修改统计表各自DMA分区漏损率
                            dmaStatistical.setLeakageRate(customize.getAfterLeak());
                            dmaStatistical.setPoorProductionRate(customize.getAfterLeak());
                            dmaStatisticalService.updateById(dmaStatistical);
                            // 判断是否为1级分区 若为一级分区修改总统计指标表漏损率
                            if (1 == partitionLevel) {
                                TotalStatistical totalStatistical = totalStatisticalService.getOne(new QueryWrapper<TotalStatistical>().lambda().eq(TotalStatistical::getStatisticalDate, n));
                                if (null != totalStatistical) {
                                    // 获取统计指标表中所有一级分区的漏损率 求和(除当前修正dma分区漏损率)
                                    List<DmaStatistical> statisticalList = dmaStatisticalService.list(new QueryWrapper<DmaStatistical>().lambda()
                                            .eq(DmaStatistical::getStatisticalDate, n)
                                            .ne(DmaStatistical::getDmaId, k));
                                    if (null != statisticalList && statisticalList.size() > 0) {
                                        BigDecimal leakTotal = statisticalList.stream()
                                                .map(DmaStatistical::getLeakageRate).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                                        BigDecimal add = leakTotal.add(customize.getAfterLeak());
                                        BigDecimal leakNew = add.divide(BigDecimal.valueOf(statisticalList.size() + 1), 2, BigDecimal.ROUND_HALF_UP);
                                        totalStatistical.setLeakageRate(leakNew);
                                        BigDecimal poorRate = statisticalList.stream()
                                                .map(DmaStatistical::getPoorProductionRate).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                                        BigDecimal add1 = poorRate.add(customize.getAfterCxc());
                                        BigDecimal poorNew = add1.divide(BigDecimal.valueOf(statisticalList.size() + 1), 2, BigDecimal.ROUND_HALF_UP);
                                        totalStatistical.setPoorProductionRate(poorNew);
                                    } else {
                                        totalStatistical.setLeakageRate(customize.getAfterLeak());
                                        totalStatistical.setPoorProductionRate(customize.getAfterCxc());
                                    }
                                    totalStatisticalService.updateById(totalStatistical);
                                }
                            }
                        }
                    }
                    customizeList.add(customize);
                });

            });

            return this.saveOrUpdateBatch(customizeList);
        }

        return true;
    }
}
