package com.zcxk.service;


import com.zcxk.dao.ComdisplayMapLocationMapper;
import com.zcxk.dao.MonitorDataReportMapper;
import com.zcxk.dao.OnlineMonitorMapper;
import com.zcxk.dto.*;
import com.zcxk.entity.ComdisplayMapLocationEntity;
import com.zcxk.entity.MonitorDataEntity;
import com.zcxk.entity.MonitorDataValueEntity;
import com.zcxk.entity.SceneEntity;
import com.zcxk.model.LoginUser;
import com.zcxk.util.ByteArrayUtils;
import com.zcxk.util.OrgInfoUtil;
import com.zcxk.util.RedisUtil;
import com.zcxk.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 地图坐标Service接口
 *
 * @author: WYY
 * @date 2021-02-24 09:58
 */
@Service
public class ComdisplayMapLocationService extends ServiceImpl<ComdisplayMapLocationMapper, ComdisplayMapLocationEntity> {

    @Resource
    private ComdisplayMapLocationMapper comdisplayMapLocationMapper;
    @Autowired
    private SceneService sceneService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private MonitorInfoService monitorInfoService;
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private MonitorDataReportMapper monitorDataReportMapper;
    @Autowired
    private OrgInfoUtil orgInfoUtil;
    @Resource
    private OnlineMonitorMapper onlineMonitorMapper;
    @Resource
    private MonthReportService monthReportService;
    /**
     * 查列表
     */
    public List<ComdisplayMapLocationEntity> findList(ComdisplayMapLocationEntity comdisplayMapLocationEntity) {
        return comdisplayMapLocationMapper.findList(comdisplayMapLocationEntity);
    }

    /**
     * 批量删除
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean delComdisplayMapLocationByIds(Long[] ids) {
        return this.removeByIds(Arrays.asList(ids));
    }

    /**
     * 单个删除
     */
    public boolean delComdisplayMapLocationById(Long id) {
        return this.removeById(id);
    }

    /**
     * 保存
     */
    public boolean addComdisplayMapLocation(ComdisplayMapLocationEntity comdisplayMapLocation) {
        if (this.save(comdisplayMapLocation)) {
            return true;
        }
        return false;
    }

    /**
     * 修改根居ID
     */
    public boolean updateComdisplayMapLocationById(ComdisplayMapLocationEntity comdisplayMapLocation) {
        if (this.updateById(comdisplayMapLocation)) {
            return true;
        }
        return false;
    }

    /**
     * 根居ID获取对象
     */
    public ComdisplayMapLocationEntity findComdisplayMapLocationById(Long id) {
        return comdisplayMapLocationMapper.findComdisplayMapLocationById(id);
    }

    public List<ComdisplayInfoDto> selectMapDataForCompany() {
        LoginUser currentUser = UserUtil.getCurrentUser();
        return  comdisplayMapLocationMapper.selectMapDataForCompany(currentUser.getTenantId());
    }
    //按公司获取取水量和制水量
    public ComdisplayInfoDto selectMapDataForCompany(Long companyOrgId,String typeName) {
        ComdisplayInfoDto sceneUsageDto = new ComdisplayInfoDto();
        sceneUsageDto.setCompanyOrgId(companyOrgId.intValue());
        SceneEntity sceneEntity = new SceneEntity();
        sceneEntity.setSceneTypeName(typeName);
        List<SceneEntity> sceneEntities = sceneService.selectByTypeNameForCom(sceneEntity, companyOrgId);
        LoginUser currentUser = UserUtil.getCurrentUser();
        //查询当月数据
        for (SceneEntity itemScene : sceneEntities) {
            //查询场景下的所有设备信息
            List<DeviceDto> devices = new ArrayList<>();
            DeviceDto deviceDto = new DeviceDto();
            deviceDto.setSceneIds(sceneService.findByParentIdsLike(itemScene.getId()));
            if (deviceDto.getSceneIds().size() == 0)
                continue;
            devices.addAll(deviceService.selectList(deviceDto));
            //按设备获取取水和制水的最新值
            ReportDto reportDto = new ReportDto();
            reportDto.setDeviceIds(devices);
            reportDto.setYear(LocalDateTime.now().getYear());
            reportDto.setMonth(LocalDateTime.now().getMonthValue());
            List<ReportAttributeDto> reportAttributeDtos = monthReportService.findAttributeListForMonth(reportDto);
           for(ReportAttributeDto dto:reportAttributeDtos) {
               switch (dto.getAttributeType()) {
                   case 3:
                       sceneUsageDto.setYieldWaterUsage(sceneUsageDto.getYieldWaterUsage() != null ? (double) Math.round((sceneUsageDto.getYieldWaterUsage() + dto.getSumValue()) * 1000) / 1000 : (double) Math.round((dto.getSumValue()) * 1000) / 1000);
                       break;
                   case 4:
                       sceneUsageDto.setIntakeWaterUsage(sceneUsageDto.getIntakeWaterUsage() != null ? (double) Math.round((sceneUsageDto.getIntakeWaterUsage() + dto.getSumValue()) * 1000) / 1000 : (double) Math.round((dto.getSumValue()) * 1000) / 1000);
                       break;
               }
           }
            //取前一天
            LocalDateTime dateTime = LocalDateTime.now().plusDays(-1);
            for (DeviceDto item : devices) {
                //设备的几个参数值
                SceneDeviceAttributeDto sceneDeviceAttributeDto = new SceneDeviceAttributeDto();
                sceneDeviceAttributeDto.setDeviceId(item.getId());
                sceneDeviceAttributeDto.setYear(dateTime.getYear());
                sceneDeviceAttributeDto.setMonth(dateTime.getMonthValue());
                sceneDeviceAttributeDto.setDay(dateTime.getDayOfMonth());
                sceneDeviceAttributeDto.setSceneId(itemScene.getId());
                List<SceneDeviceAttributeDto> sceneDeviceAttributeDtos = monitorInfoService.findAttributeListForLastDay(sceneDeviceAttributeDto);
                //取缓存里的数据
                byte[] bytes = redisUtil.get(("sms_water_" + item.getDeviceCode()).getBytes());
                if (bytes != null && bytes.length > 0) {
                    MonitorDataEntity monitorDataEntity = (MonitorDataEntity) ByteArrayUtils.bytesToObject(bytes).get();
                    //筛选该设备相同属性的值
                    Map<Long, MonitorDataValueEntity> map = new HashMap<>();
                    //将缓存中的实时数据放到map中方便进行遍历
                    for (MonitorDataValueEntity dateValue : monitorDataEntity.getDataValues()) {
                        map.put(dateValue.getAttributeId(), dateValue);
                    }
                    for (SceneDeviceAttributeDto itemAttribute : sceneDeviceAttributeDtos) {
                        Double attributeDiffValue = 0d;
                        if (!map.containsKey(itemAttribute.getAttributeId())) {
                            continue;
                        }
                        if (map.get(itemAttribute.getAttributeId()).getDataValue() != null && itemAttribute.getLatestValue() != null) {
                            attributeDiffValue = map.get(itemAttribute.getAttributeId()).getDataValue() - itemAttribute.getLatestValue();
                        } else if (map.get(itemAttribute.getAttributeId()).getDataValue() != null && itemAttribute.getLatestValue() == null) {
                            attributeDiffValue = map.get(itemAttribute.getAttributeId()).getDataValue();
                        }
                        switch (itemAttribute.getAttributeType()) {
                            case "3":
                                sceneUsageDto.setYieldWaterUsage(sceneUsageDto.getYieldWaterUsage() != null ? (double) Math.round((sceneUsageDto.getYieldWaterUsage() + attributeDiffValue) * 1000) / 1000 : (double) Math.round((attributeDiffValue) * 1000) / 1000);
                                break;
                            case "4":
                                sceneUsageDto.setIntakeWaterUsage(sceneUsageDto.getIntakeWaterUsage() != null ? (double) Math.round((sceneUsageDto.getIntakeWaterUsage() + attributeDiffValue) * 1000) / 1000 : (double) Math.round((attributeDiffValue) * 1000) / 1000);
                                break;
                        }
                    }
                    if (sceneUsageDto.getYieldWaterUsage() == null)
                        sceneUsageDto.setYieldWaterUsage(sceneUsageDto.getYieldWaterUsage());
                    if (sceneUsageDto.getIntakeWaterUsage() == null)
                        sceneUsageDto.setIntakeWaterUsage(sceneUsageDto.getIntakeWaterUsage());
                }
            }
        }
        return sceneUsageDto;
    }

    public List<ComdisplayInfoDto> selectMapDataForSingleCompany(Integer companyOrgId) {
        LoginUser currentUser = UserUtil.getCurrentUser();
        return  comdisplayMapLocationMapper.selectMapDataForSingleCompany(currentUser.getTenantId(),companyOrgId);
    }

    public List<SecDataCollectDto> selectMapForWholeCompanyByMonth() {
        List<SecDataCollectDto> secDataCollectDtos = new ArrayList<>();
        LoginUser loginUser = UserUtil.getCurrentUser();
        MonitorDataCollectDto monitorDataCollectDto = new MonitorDataCollectDto();
        monitorDataCollectDto.setSceneTypeName("泵站");
        monitorDataCollectDto.setSceneIds(sceneService.findByParentIdsByCom(null));
        monitorDataCollectDto.setTenantId(loginUser.getTenantId());
        monitorDataCollectDto.setProgramItems(loginUser.getProgramItemList());
        monitorDataCollectDto.setUserType(loginUser.getType());
        //1是公司，2是公司及以下，3部门，4部门及以下，5自定义
        monitorDataCollectDto.setPermissonType(loginUser.getPermissonType());
        monitorDataCollectDto.setType(3);
        List<MonitorDataCollectDto> result = onlineMonitorMapper.selectMapSuspension(monitorDataCollectDto);
        Map<Long, SecDataCollectDto> map = new HashMap<>();
        for (MonitorDataCollectDto monitorDataCollectDto1 : result) {
            if (!map.containsKey(monitorDataCollectDto1.getCompanyOrgId())) {
                ComdisplayInfoDto comdisplayInfoDto = selectMapDataForCompany(monitorDataCollectDto1.getCompanyOrgId(), "泵站");
                if (comdisplayInfoDto != null) {
                    SecDataCollectDto secDataCollectDto = new SecDataCollectDto();
                    secDataCollectDto.setYieldWaterUsage(monitorDataCollectDto1.getYieldWaterUsage() != null ? (double) Math.round(monitorDataCollectDto1.getYieldWaterUsage() / (float) 100) / 100 : 0);
                    secDataCollectDto.setCount(1);
                    secDataCollectDto.setComName(orgInfoUtil.getOrgName(monitorDataCollectDto1.getCompanyOrgId().intValue()));
                    map.put(monitorDataCollectDto1.getCompanyOrgId(), secDataCollectDto);
                } else {
                    int count = map.get(monitorDataCollectDto1.getCompanyOrgId()).getCount();
                    map.get(monitorDataCollectDto1.getCompanyOrgId()).setCount(count + 1);
                }
            }
        }
        for (SecDataCollectDto value : map.values()) {
            secDataCollectDtos.add(value);
        }
        //按水量倒序排序 如果是水源按照取水量排序，其他按照供水量
        secDataCollectDtos.sort(new Comparator<SecDataCollectDto>() {
            @Override
            public int compare(SecDataCollectDto o1, SecDataCollectDto o2) {
                Double d1 = (o1.getYieldWaterUsage() == null ? 0d : o1.getYieldWaterUsage());
                Double d2 = (o2.getYieldWaterUsage() == null ? 0d : o2.getYieldWaterUsage());
                if (d1 > d2) {
                    return -1;
                }
                return 0;
            }
        });
        return secDataCollectDtos;
    }
}
