package com.skr.mdm.service.impl.track;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.google.common.collect.Lists;
import com.skr.mdm.annotation.CmdHandler;
import com.skr.mdm.constant.CmdTypeConstants;
import com.skr.mdm.dao.AuCompanyDao;
import com.skr.mdm.dao.DeviceEquipmentDao;
import com.skr.mdm.dao.DeviceEquipmentInfoDao;
import com.skr.mdm.dto.EquipmentLocationDTO;
import com.skr.mdm.entity.DeviceEquipmentDO;
import com.skr.mdm.entity.DeviceEquipmentInfoDO;
import com.skr.mdm.enums.EquipmentStatusEnum;
import com.skr.mdm.result.ResponseResult;
import com.skr.mdm.service.CmdHandlerService;
import com.skr.mdm.util.GaodeMapAPIUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author nfq
 * @date 2020/8/3 18:23
 */
@Slf4j
@CmdHandler(cmdType = CmdTypeConstants.UPLOAD_LOCATION)
public class UserLocationInfoServiceImpl implements CmdHandlerService {

    @Autowired
    private AuCompanyDao companyDao;
    @Autowired
    private DeviceEquipmentDao equipmentDao;
    @Autowired
    private DeviceEquipmentInfoDao equipmentInfoDao;

    @Override
    public ResponseResult cmdHandler(Integer equipmentId, String data) {
        try {
            // 用户轨迹信息上传到猎鹰
            JSONArray jsonArray = JSONUtil.parseArray(data);
            List<EquipmentLocationDTO> equipmentLocationDTOList = JSONUtil.toList(jsonArray, EquipmentLocationDTO.class);
            List<Map<String, Object>> mapList = new ArrayList<>(equipmentLocationDTOList.size());
            List<Integer> cidList = new ArrayList<>(equipmentLocationDTOList.size());
            if (CollectionUtils.isNotEmpty(equipmentLocationDTOList)) {
                // 更新设备最新位置
                equipmentLocationDTOList.stream().min((t1, t2) -> t2.getLocateTime().compareTo(t1.getLocateTime()))
                        .ifPresent(locationDTO -> new LambdaUpdateChainWrapper<>(equipmentInfoDao)
                                .set(DeviceEquipmentInfoDO::getLatitude, locationDTO.getLatitude())
                                .set(DeviceEquipmentInfoDO::getLongitude, locationDTO.getLongitude())
                                .set(DeviceEquipmentInfoDO::getPosCorrentionTime, DateUtil.date(locationDTO.getLocateTime()))
                                .eq(DeviceEquipmentInfoDO::getEquipmentId, equipmentId)
                                .update());
//                List<DeviceInstructLocationDO> deviceInstructLocationDOList = new ArrayList<>(equipmentLocationDTOList.size());
                equipmentLocationDTOList.forEach(equipmentLocationDTO -> {
                    String location = equipmentLocationDTO.getLongitude() + "," + equipmentLocationDTO.getLatitude();
                    Map<String, Object> map = new HashMap<>(2);
                    map.put("location", location);
                    map.put("locatetime", equipmentLocationDTO.getLocateTime());
                    map.put("speed", equipmentLocationDTO.getSpeed());
                    map.put("direction", equipmentLocationDTO.getDirection());
                    map.put("height", equipmentLocationDTO.getHeight());
                    map.put("accuracy", equipmentLocationDTO.getAccuracy());
                    mapList.add(map);
                    cidList.add(equipmentLocationDTO.getCid());
//                    DeviceInstructLocationDO deviceInstructLocationDO =  DeviceInstructLocationDO.builder().build();
//                    BeanUtil.copyProperties(equipmentLocationDTO, deviceInstructLocationDO);
//                    deviceInstructLocationDO.setEquipmentId(equipmentId);
//                    deviceInstructLocationDOList.add(deviceInstructLocationDO);
                });
//                deviceInstructLocationDao.insertBatch(deviceInstructLocationDOList);
            }
            Integer sid = companyDao.getSidByEquipmentId(equipmentId, EquipmentStatusEnum.ELIMINATED.getState());
            if (sid == null) {
                return ResponseResult.success(JSONUtil.toJsonStr(cidList));
            }
            DeviceEquipmentDO equipmentDO = equipmentDao.selectById(equipmentId);
            Integer uploadPoint = null;
            if (mapList.size() > 100) {
                // 分批上传
                List<List<Map<String, Object>>> partition = Lists.partition(mapList, 100);
                for (List<Map<String, Object>> maps : partition) {
                    uploadPoint = GaodeMapAPIUtil.uploadPoint(sid, equipmentDO.getTid(), equipmentDO.getTrid(), maps);
                    if (uploadPoint == null) {
                        return ResponseResult.failure();
                    }
                }
            } else {
                uploadPoint = GaodeMapAPIUtil.uploadPoint(sid, equipmentDO.getTid(), equipmentDO.getTrid(), mapList);
            }
            if (uploadPoint == null) {
                return ResponseResult.failure();
            }
            return ResponseResult.success(JSONUtil.toJsonStr(cidList));
        } catch (Exception e) {
            log.error("用户轨迹上传异常：" + equipmentId + data, e);
            return ResponseResult.failure();
        }
    }

}
