package com.dji.sample.manage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dji.sample.component.redis.RedisConst;
import com.dji.sample.component.redis.RedisOpsUtils;
import com.dji.sample.manage.dao.IDeviceDetailMapper;
import com.dji.sample.manage.model.dto.DeviceDTO;
import com.dji.sample.manage.model.dto.DeviceDetailCacheDTO;
import com.dji.sample.manage.model.dto.DeviceDetailCountDTO;
import com.dji.sample.manage.model.entity.DeviceDetailEntity;
import com.dji.sample.manage.service.IDeviceDetailService;
import com.dji.sdk.cloudapi.device.DeviceDomainEnum;
import com.dji.sdk.cloudapi.device.OsdDockDrone;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

import static com.dji.sample.component.redis.RedisConst.*;

/**
 * @author guan
 */
@Service
public class DeviceDetailServiceImpl extends ServiceImpl<IDeviceDetailMapper, DeviceDetailEntity> implements IDeviceDetailService {

    @Override
    public void saveDeviceOsd(String deviceSn, OsdDockDrone osdDockDrone) {

        // 保存
        Double totalFlightDistance = osdDockDrone.getTotalFlightDistance();
        Integer totalFlightSorties = osdDockDrone.getTotalFlightSorties();
        Float totalFlightTime = osdDockDrone.getTotalFlightTime();

        if (totalFlightDistance != null) {
            // 飞行总里程
            DeviceDetailCacheDTO totalFlightDistanceDTO = new DeviceDetailCacheDTO();
            totalFlightDistanceDTO.setDeviceSn(deviceSn);
            totalFlightDistanceDTO.setIsSave(false);
            totalFlightDistanceDTO.setType("total_flight_distance");
            totalFlightDistanceDTO.setValue(String.valueOf(totalFlightDistance));
            RedisOpsUtils.set(DEVICE_TOTAL_FLIGHT_DISTANCE_PREFIX + deviceSn, totalFlightDistanceDTO);
        }
        if (totalFlightSorties != null) {
            // 飞行总架次
            DeviceDetailCacheDTO totalFlightSortiesDTO = new DeviceDetailCacheDTO();
            totalFlightSortiesDTO.setDeviceSn(deviceSn);
            totalFlightSortiesDTO.setIsSave(false);
            totalFlightSortiesDTO.setType("total_flight_sorties");
            totalFlightSortiesDTO.setValue(String.valueOf(totalFlightSorties));
            RedisOpsUtils.set(DEVICE_TOTAL_FLIGHT_SORTIES_PREFIX + deviceSn, totalFlightSortiesDTO);
        }
        if (totalFlightTime != null) {
            // 飞行总航时
            DeviceDetailCacheDTO totalFlightTimeDTO = new DeviceDetailCacheDTO();
            totalFlightTimeDTO.setDeviceSn(deviceSn);
            totalFlightTimeDTO.setIsSave(false);
            totalFlightTimeDTO.setType("total_flight_time");
            totalFlightTimeDTO.setValue(String.valueOf(totalFlightTime));
            RedisOpsUtils.set(DEVICE_TOTAL_FLIGHT_TIME_PREFIX + deviceSn, totalFlightTimeDTO);
        }

    }

    @Override
    public DeviceDetailCountDTO searchList(List<String> deviceSnList) {

        DeviceDetailCountDTO deviceDetailCountDTO = new DeviceDetailCountDTO();
        deviceDetailCountDTO.setTotalFlightSorties(BigDecimal.ZERO);
        deviceDetailCountDTO.setTotalFlightDistance(BigDecimal.ZERO);
        deviceDetailCountDTO.setTotalFlightTime(BigDecimal.ZERO);

        // 查询数据
        LambdaQueryWrapper<DeviceDetailEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(DeviceDetailEntity::getDeviceSn, deviceSnList);
        List<DeviceDetailEntity> detailEntities = this.list(wrapper);

        if (CollectionUtils.isEmpty(detailEntities)) {
            return deviceDetailCountDTO;
        }

        Map<String, List<DeviceDetailEntity>> deviceDetailMap = detailEntities.stream().collect(Collectors.groupingBy(DeviceDetailEntity::getType));
        List<DeviceDetailEntity> totalFlightDistanceList = deviceDetailMap.getOrDefault("total_flight_distance", new ArrayList<>());
        List<DeviceDetailEntity> totalFlightSortiesList = deviceDetailMap.getOrDefault("total_flight_sorties", new ArrayList<>());
        List<DeviceDetailEntity> totalFlightTimeList = deviceDetailMap.getOrDefault("total_flight_time", new ArrayList<>());

        if (!CollectionUtils.isEmpty(totalFlightDistanceList)) {
            BigDecimal num = BigDecimal.ZERO;
            for (DeviceDetailEntity deviceDetailEntity : totalFlightDistanceList) {
                num = num.add(new BigDecimal(deviceDetailEntity.getCurValue()));
            }
            deviceDetailCountDTO.setTotalFlightDistance(num);
        }
        if (!CollectionUtils.isEmpty(totalFlightSortiesList)) {
            BigDecimal num = BigDecimal.ZERO;
            for (DeviceDetailEntity deviceDetailEntity : totalFlightSortiesList) {
                num = num.add(new BigDecimal(deviceDetailEntity.getCurValue()));
            }
            deviceDetailCountDTO.setTotalFlightSorties(num);
        }
        if (!CollectionUtils.isEmpty(totalFlightTimeList)) {
            BigDecimal num = BigDecimal.ZERO;
            for (DeviceDetailEntity deviceDetailEntity : totalFlightTimeList) {
                num = num.add(new BigDecimal(deviceDetailEntity.getCurValue()));
            }
            deviceDetailCountDTO.setTotalFlightTime(num);
        }
        return deviceDetailCountDTO;
    }

    /**
     * 定时器 10分钟保存一次数据  每 600 秒执行一次
     */
    @Scheduled(fixedRate = 600000)
    public void syncSaveDeviceDetailData() {

        // 查询redis 获取数据
        int start = RedisConst.DEVICE_DETAIL_PREFIX.length();

        Set<String> allKeys = RedisOpsUtils.getAllKeys(RedisConst.DEVICE_DETAIL_PREFIX + "*");

        Iterator<String> iterator = allKeys.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            DeviceDetailCacheDTO value = (DeviceDetailCacheDTO) RedisOpsUtils.get(key);

            if (value.getIsSave()) {
                continue;
            }
            value.setIsSave(true);
            RedisOpsUtils.set(key, value);

            // 查询数据库是否存在数据
            LambdaQueryWrapper<DeviceDetailEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(DeviceDetailEntity::getType, value.getType());
            queryWrapper.eq(DeviceDetailEntity::getDeviceSn, value.getDeviceSn());
            List<DeviceDetailEntity> deviceDetailEntities = this.list(queryWrapper);
            if (CollectionUtils.isEmpty(deviceDetailEntities)) {
                // 新增
                DeviceDetailEntity deviceDetailEntity = new DeviceDetailEntity();
                deviceDetailEntity.setDeviceSn(value.getDeviceSn());
                deviceDetailEntity.setType(value.getType());
                deviceDetailEntity.setInitValue(value.getValue());
                deviceDetailEntity.setCurValue(value.getValue());
                deviceDetailEntity.setCreateTime(System.currentTimeMillis());
                deviceDetailEntity.setUpdateTime(System.currentTimeMillis());

                this.save(deviceDetailEntity);
            } else {
                // 修改
                DeviceDetailEntity dbDetailEntity = deviceDetailEntities.get(0);
                LambdaUpdateWrapper<DeviceDetailEntity> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(DeviceDetailEntity::getId, dbDetailEntity.getId());
                updateWrapper.set(DeviceDetailEntity::getCurValue, value.getValue());
                updateWrapper.set(DeviceDetailEntity::getUpdateTime, System.currentTimeMillis());
                this.update(updateWrapper);
            }
        }

    }


}
