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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tofly.xrtygis.em.Constant;
import com.tofly.xrtygis.entity.DmaStatistical;
import com.tofly.xrtygis.entity.Dmaandobser;
import com.tofly.xrtygis.entity.Dmaregion;
import com.tofly.xrtygis.entity.vo.DmaLeakageVo;
import com.tofly.xrtygis.mapper.DmaandobserMapper;
import com.tofly.xrtygis.service.DmaandobserService;
import com.tofly.xrtygis.service.DmaregionService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * DMA分区与观察表关系信息表：TF_YWPN_DMAANDOBSER_W
 *
 * @author admin
 * @date Wed Mar 10 00:00:00 CST 2021
 */
@Service("dmaandobserService")
public class DmaandobserServiceImpl extends ServiceImpl<DmaandobserMapper, Dmaandobser> implements DmaandobserService {

    @Autowired
    private DmaregionService dmaregionService;

    @Override
    public void insertBatch(List<Dmaandobser> dmaandobserList) {
        baseMapper.insertBatch(dmaandobserList);
    }

    @Override
    public List<DmaLeakageVo> leakageRateAnalyse(List<Long> dmaIdList, String startDate, String endDate) {
        List<DmaLeakageVo> res = new ArrayList<>();
        List<Map<String, Object>> list = baseMapper.getDiffByDeviceDay(startDate, endDate);
        List<Dmaandobser> dmaandobserList = this.list();
        List<String> days = getDays(startDate, endDate);
        dmaIdList.forEach(id -> {
            Dmaregion dmaregion = dmaregionService.getById(id);
            List<Dmaandobser> dmaandobserFinalIn = dmaandobserList.stream()
                    .filter(e -> Objects.equals(e.getDmaId(), id) && e.getIsout().equals("0"))
                    .collect(Collectors.toList());
            List<Dmaandobser> dmaandobserFinalOut = dmaandobserList.stream()
                    .filter(e -> Objects.equals(e.getDmaId(), id) && e.getIsout().equals("1"))
                    .collect(Collectors.toList());
            if (CollUtil.isEmpty(dmaandobserFinalIn) || CollUtil.isEmpty(dmaandobserFinalOut)) {
                return;
            }
            List<Long> deviceListOut = dmaandobserFinalOut.stream().map(Dmaandobser::getTableId).collect(Collectors.toList());
            List<Long> deviceListIn = dmaandobserFinalIn.stream().map(Dmaandobser::getTableId).collect(Collectors.toList());
            for (String day : days) {
                List<Map<String, Object>> listFinalOut = list.stream()
                        .filter(e -> e.get("deviceId") != null && e.get("scadaTime") != null
                                && deviceListOut.contains(Long.parseLong(String.valueOf(e.get("deviceId")))) && day.equals(String.valueOf(e.get("scadaTime"))))
                        .collect(Collectors.toList());
                List<Map<String, Object>> listFinalIn = list.stream()
                        .filter(e -> e.get("deviceId") != null && e.get("scadaTime") != null
                                && deviceListIn.contains(Long.parseLong(String.valueOf(e.get("deviceId")))) && day.equals(String.valueOf(e.get("scadaTime"))))
                        .collect(Collectors.toList());
                if (CollUtil.isEmpty(listFinalOut) || CollUtil.isEmpty(listFinalIn) ) {
                    continue;
                }
                DmaLeakageVo dmaLeakageVo = new DmaLeakageVo();
                dmaLeakageVo.setDmaId(id);
                dmaLeakageVo.setDmaName(dmaregion.getDmaName());
                dmaLeakageVo.setScadaTime(day);
                dmaLeakageVo.setOutWaterMeterValue(BigDecimal.valueOf(listFinalOut.stream().mapToDouble(e -> Double.parseDouble(String.valueOf(e.get("diffValue")))).sum()));
                dmaLeakageVo.setInWaterMeterValue(BigDecimal.valueOf(listFinalIn.stream().mapToDouble(e -> Double.parseDouble(String.valueOf(e.get("diffValue")))).sum()));
                BigDecimal diff = dmaLeakageVo.getInWaterMeterValue().subtract(dmaLeakageVo.getOutWaterMeterValue());
                dmaLeakageVo.setDiffValue(diff);

                float leakageRate = 0.0f;
                if (dmaLeakageVo.getInWaterMeterValue().compareTo(BigDecimal.ZERO) != 0) {
                    leakageRate = diff.divide(dmaLeakageVo.getInWaterMeterValue(), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).floatValue();
                }
                dmaLeakageVo.setLeakageRate(leakageRate);

                res.add(dmaLeakageVo);
            }
        });
        return res;
    }

    @Override
    public List<DmaStatistical> getDmaStatistical(String startDate, String endDate, String dmaIds) {
        List<Long> dmaIdList = null;
        if (StringUtils.isNotBlank(dmaIds)) {
            dmaIdList = Arrays.stream(dmaIds.split(Constant.CSV)).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        }
        List<DmaStatistical> dmaStatisticals = baseMapper.getDmaStatistical(startDate, endDate, dmaIdList);
        if (CollUtil.isNotEmpty(dmaStatisticals)) {
            for (DmaStatistical dmaStatistical : dmaStatisticals) {
                dmaStatistical.setDmaregion(dmaregionService.getById(dmaStatistical.getDmaId()));
            }
        }
        return dmaStatisticals;
    }

    List<String> getDays(String start, String end) {
        List<String> days = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(DateUtil.parse(start, "yyyy-MM-dd HH:mm:ss"));
        while (DateUtil.format(cal.getTime(), "yyyy-MM-dd HH:mm:ss").compareTo(end) <= 0) {
            days.add(DateUtil.format(cal.getTime(), "yyyy-MM-dd"));
            cal.add(Calendar.DAY_OF_MONTH, +1);
        }
        return days;
    }

}
