package com.zcxk.service;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcxk.dao.MonthReportMapper;
import com.zcxk.dto.*;
import com.zcxk.entity.MonitorDataEntity;
import com.zcxk.entity.MonthReportEntity;
import com.zcxk.model.LoginUser;
import com.zcxk.util.MongoDbUtil;
import com.zcxk.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 日报Service接口
 *
 * @author: WYY
 * @date 2020-12-03 16:20
 */
@Service
public class MonthReportService extends AbstractReportService<MonthReportMapper, MonthReportEntity> {

    @Resource
    private MonthReportMapper monthReportMapper;

    @Autowired
    MongoDbUtil mongoDbUtil;

    /**
     * 查列表
     */
    public List<MonthReportEntity> findList(MonthReportEntity monthReportEntity) {
        return monthReportMapper.findList(monthReportEntity);
    }


    /**
     * 保存
     */
    public boolean addMonthReport(MonthReportEntity monthReport) {
        if (this.save(monthReport)) {
            return true;
        }
        return false;
    }


    /**
     * 根居ID获取对象
     */
    public MonthReportEntity findMonthReportById(Long id) {
        return monthReportMapper.findMonthReportById(id);
    }

    public Page<ReportDto> findPage(IPage<ReportDto> page, Long[] ids, Integer year, Integer month, Integer day) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        Page<ReportDto> reportPage = new Page<>();
        //查询场景下的所有设备信息
        List<DeviceDto> devices = new ArrayList<>();
        DeviceDto deviceDto = new DeviceDto();
        for (Long id : ids) {
            deviceDto.setSceneIds(sceneService.findByParentIdsLike(id));
            if (deviceDto.getSceneIds().size() > 0) {
                devices.addAll(deviceService.selectList(deviceDto));
            }
        }
        if (devices.size() > 0) {
            MonthReportEntity monthReportEntity = new MonthReportEntity();
            monthReportEntity.setYear(year);
            monthReportEntity.setMonth(month);
            monthReportEntity.setTenantId(currentUser.getTenantId());
            monthReportEntity.setParentSceneIds(ids);
            monthReportEntity.setDeviceIds(devices);
            reportPage = monthReportMapper.findPage(page, monthReportEntity);
            //查询标题
            ReportDto reportDto = new ReportDto();
            reportDto.setYear(year);
            reportDto.setMonth(month);
            reportDto.setDeviceIds(devices);
            reportDto.setParentSceneIds(ids);
            List<ReportAttributeDto> reportAttributeDtos2 = deviceParmService.findAttributeNameList(reportDto);
            List<String> dataTitle = new ArrayList<>();
            Map<String, Integer> mapsTitle = new LinkedHashMap<>();
            int numCount = 0;
            for (ReportAttributeDto title : reportAttributeDtos2) {
                dataTitle.add(title.getAttributeName());
                if (!mapsTitle.containsKey(title.getAttributeName())) {
                    mapsTitle.put(title.getAttributeName(), numCount++);
                }
            }
            //固定参数项
            List<ReportDto> reportDtos = monthReportMapper.findReport(reportDto);
            //单个属性值
            for (ReportDto item : reportPage.getRecords()) {
                item.setCollectDate(item.getYear() + "-" + String.format("%02d", item.getMonth()) + "-" + String.format("%02d", item.getDay()));
                item.setDeviceIds(devices);
                item.setDataTitle(dataTitle);
                //固定参数项
                calcUsage(item, reportDtos);
                //动态参数项
                List<ReportAttributeDto> reportAttributeDtos = monthReportMapper.findAttributeList(item);
                // item.setDataValues(reportAttributeDtos);
                Map<String, ReportAttributeDto> mapData = new LinkedHashMap<>();
                for (ReportAttributeDto itemData : reportAttributeDtos) {
                    if (!mapData.containsKey(itemData.getAttributeName())) {
                        mapData.put(itemData.getAttributeName(), itemData);
                    }
                }
                List<Map<String, Object>> maps = new ArrayList<>();
                for (String key : mapsTitle.keySet()) {
                    Map<String, Object> map = new LinkedHashMap<>();
                    map.put("attributeName", mapData.get(key) == null ? key : mapData.get(key).getAttributeName());
                    map.put("minValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getMinValue() == null ? "-" : (double) Math.round(mapData.get(key).getMinValue() * 1000) / 1000);
                    map.put("maxValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getMaxValue() == null ? "-" : (double) Math.round(mapData.get(key).getMaxValue() * 1000) / 1000);
                    map.put("avgValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getAvgValue() == null ? "-" : (double) Math.round(mapData.get(key).getAvgValue() * 1000) / 1000);
                    map.put("sumValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getSumValue() == null ? "-" : (double) Math.round(mapData.get(key).getSumValue() * 1000) / 1000);
                    map.put("latestValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getLatestValue() == null ? "-" : (double) Math.round(mapData.get(key).getLatestValue() * 1000) / 1000);
                    maps.add(map);
                }
                item.setDataMapValues(maps);
            }
        }
        return reportPage;
    }

    //计算固定的参数项
    @Override
    public void calcUsage(ReportDto item, List<ReportDto> reportDtos) {
        if (item == null || reportDtos.size() == 0) {
            return;
        }
        //固定参数项
        int index = -1;
        for (int i = 0; i < reportDtos.size(); i++) {
            if (reportDtos.get(i).getDay().equals(item.getDay())) {
                index = i;
            }
        }
        if (index == -1) {
            return;
        }
        Double power = reportDtos != null && reportDtos.get(index) != null ? reportDtos.get(index).getPowerUsage() : 0;
        Double water = reportDtos != null && reportDtos.get(index) != null ? reportDtos.get(index).getIntakeWaterUsage() : 0;
        Double yieldWaterUsage = reportDtos != null && reportDtos.get(index) != null ? reportDtos.get(index).getYieldWaterUsage() : 0;
        if (item.getSceneTypeName() != null && "水源水厂".indexOf(item.getSceneTypeName()) != -1) {
            item.setPowerUsage(doubleDivideValue(power));
            item.setIntakeWaterUsage(doubleDivideValue(water));
            item.setYieldWaterUsage(doubleDivideValue(yieldWaterUsage));
        } else {
            item.setPowerUsage(power);
            item.setIntakeWaterUsage(water);
            item.setYieldWaterUsage(yieldWaterUsage);
        }
        item.setDrugUsage(reportDtos != null && reportDtos.get(index) != null ? reportDtos.get(index).getDrugUsage() : 0);
//        if (index != -1) {
//            if ((index + 2) <= reportDtos.size()) {
//                item.setYieldWaterUsage(reportDtos.get(index).getYieldWaterUsage() - reportDtos.get(index + 1).getYieldWaterUsage());
//                item.setIntakeWaterUsage(reportDtos.get(index).getIntakeWaterUsage() - reportDtos.get(index + 1).getIntakeWaterUsage());
//                item.setPowerUsage(reportDtos.get(index).getPowerUsage() - reportDtos.get(index + 1).getPowerUsage());
//                item.setDrugUsage(reportDtos.get(index).getDrugUsage() - reportDtos.get(index + 1).getDrugUsage());
//            } else {
//                item.setYieldWaterUsage(0d);
//                item.setIntakeWaterUsage(0d);
//                item.setPowerUsage(0d);
//                item.setDrugUsage(0d);
//            }
//        }
    }


    public Page<DevicePressReportAttributeDto> findDevicePressPage(IPage<DevicePressReportAttributeDto> page, Long[] ids, Integer year, Integer month, Integer day, Integer type) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        Page<DevicePressReportAttributeDto> reportPage = new Page<>();
        //查询场景下的所有设备信息
        List<DeviceDto> devices = new ArrayList<>();
        for (Long id : ids) {
            DeviceDto deviceDto = new DeviceDto();
            deviceDto.setId(id);
            devices.add(deviceDto);
        }
        if (devices.size() > 0) {
            //根据设备ID查询报表测点信息
            MonthReportEntity monthReportEntity = new MonthReportEntity();
            monthReportEntity.setYear(year);
            monthReportEntity.setMonth(month);
            monthReportEntity.setTenantId(currentUser.getTenantId());
            monthReportEntity.setType(type);
            monthReportEntity.setDeviceIds(devices);
            //查询到分页的行数
            reportPage = monthReportMapper.findDevicePressPage(page, monthReportEntity);
        }
        return reportPage;
    }

    public Page<DeviceWaterReportAttributeDto> findDeviceWaterPage(IPage<DeviceWaterReportAttributeDto> page, Long[] ids, Integer year, Integer month, Integer day) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        Page<DeviceWaterReportAttributeDto> reportPage = new Page<>();
        //查询场景下的所有设备信息
        List<DeviceDto> devices = new ArrayList<>();
        for (Long id : ids) {
            DeviceDto deviceDto = new DeviceDto();
            deviceDto.setId(id);
            devices.add(deviceDto);
        }
        if (devices.size() > 0) {
            //根据设备ID查询报表测点信息
            MonthReportEntity monthReportEntity = new MonthReportEntity();
            monthReportEntity.setYear(year);
            monthReportEntity.setMonth(month);
            monthReportEntity.setTenantId(currentUser.getTenantId());
            monthReportEntity.setDeviceIds(devices);
            //查询到分页的行数
            reportPage = monthReportMapper.findDeviceWaterPage(page, monthReportEntity);
        }
        return reportPage;
    }

    public List<MonthReportEntity> findAmountBySceneIds(MonthReportEntity monthReportEntity) {
        return monthReportMapper.findAmountBySceneIds(monthReportEntity);
    }

    public List<MonthReportEntity> findAmountTotalBySceneIds(MonthReportEntity monthReportEntity) {
        return monthReportMapper.findAmountTotalBySceneIds(monthReportEntity);
    }

    List<ReportAttributeDto> findAttributeListForMonth(ReportDto reportDto) {
        return monthReportMapper.findAttributeListForMonth(reportDto);
    }


    @Override
    List<ReportDto> findReport(ReportDto reportDto) {
        return monthReportMapper.findReport(reportDto);
    }


    @Override
    List<ReportAttributeDto> findAttributeList(ReportDto item) {
        return monthReportMapper.findAttributeList(item);
    }


    public Page<ReportDto> findDevicePressPageReport(IPage<ReportDto> page, ReportQueryDto queryDto) {
        Page<ReportDto> reportPage = new Page<>();
        List<DeviceDto> devices = devicesToList(queryDto.getIds());
        if (devices.size() == 0) {
            return reportPage;
        }

        reportPage = monthReportMapper.findPageReprot(page, getReportPageQuery(queryDto, devices, true));
        reportDataHandle(queryDto, devices, reportPage, true);
        return reportPage;
    }

    /**
     * 查询历史数据压力及流量统计
     * @param page
     * @param queryDto
     * @return
     */
    public Page<ReportDto> findHistoryDataDevicePressPageReport(IPage<ReportDto> page, ReportQueryDto queryDto) {
        Page<ReportDto> reportPage = new Page<>();
        List<DeviceDto> devices = devicesToList(queryDto.getIds());
        if (devices.size() == 0) {
            return reportPage;
        }
        List<Long> deviceIds = new ArrayList<>();
        deviceIds = devices.stream().map(DeviceDto::getId).collect(Collectors.toList());
        Query query = new Query();
        Sort sort = new Sort(Sort.Direction.ASC, "deviceId").and(new Sort(Sort.Direction.ASC, "collectDate"));
        query.addCriteria(Criteria.where("deviceId").in(deviceIds));
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            query.addCriteria(Criteria.where("collectDate").gte(format.parse(queryDto.getStartTime())).lt(format.parse(queryDto.getEndTime())));
        } catch (ParseException e) {
            System.out.println("异常");
        }
        query.with(sort);
        Page<MonitorDataEntity> info = mongoDbUtil.pagination(MonitorDataEntity.class, page.getSize(), page.getCurrent(), query);
        reportHistoryDataHandle(queryDto, devices, reportPage, info,true);
        return reportPage;
    }

    public Page<ReportDto> findPageReport(IPage<ReportDto> page, ReportQueryDto queryDto) {
        Page<ReportDto> reportPage = new Page<>();
        // 查询场景下的所有设备信息
        List<DeviceDto> devices = findDevices(queryDto.getIds());
        if (devices.size() == 0) {
            return reportPage;
        }
        reportPage = monthReportMapper.findPageReprot(page, getReportPageQuery(queryDto, devices, false));
        reportDataHandle(queryDto, devices, reportPage, false);
        return reportPage;
    }

    /**
     * 查询历史数据
     *
     * @param page
     * @param queryDto
     * @return
     */
    public Page<ReportDto> findHistoryDataPageReport(IPage<ReportDto> page, ReportQueryDto queryDto) {
        Page<ReportDto> reportPage = new Page<>();
        // 查询场景下的所有设备信息
        List<DeviceDto> devices = findDevicesForReport(queryDto.getIds());
        if (devices.size() == 0) {
            return reportPage;
        }
        List<Long> deviceIds = new ArrayList<>();
        deviceIds = devices.stream().map(DeviceDto::getId).collect(Collectors.toList());
        Query query = new Query();
        Sort sort = new Sort(Sort.Direction.ASC, "deviceId").and(new Sort(Sort.Direction.ASC, "collectDate"));
        query.addCriteria(Criteria.where("deviceId").in(deviceIds));
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            query.addCriteria(Criteria.where("collectDate").gte(format.parse(queryDto.getStartTime())).lt(format.parse(queryDto.getEndTime())));
        } catch (ParseException e) {
          System.out.println("异常");
        }
        query.with(sort);
        Page<MonitorDataEntity> info = mongoDbUtil.pagination(MonitorDataEntity.class, page.getSize(), page.getCurrent(), query);
        reportHistoryDataHandle(queryDto, devices, reportPage, info,false);
        return reportPage;
    }
}
