package com.clx.performance.service.impl.vehiclewarn;

import com.clx.performance.dao.vehiclewarn.VehicleWarnInfoDao;
import com.clx.performance.dao.vehiclewarn.VehicleWarnRangeDao;
import com.clx.performance.dto.gd.GdRouteDTO;
import com.clx.performance.enums.vehiclewarn.VehicleWarnRangEnum;
import com.clx.performance.model.OrderChild;
import com.clx.performance.model.vehiclewarn.VehicleWarnChild;
import com.clx.performance.model.vehiclewarn.VehicleWarnConfig;
import com.clx.performance.model.vehiclewarn.VehicleWarnInfo;
import com.clx.performance.model.vehiclewarn.VehicleWarnRang;
import com.clx.performance.service.trace.TruckTraceService;
import com.clx.performance.service.vehiclewarn.VehicleWarnCommonService;
import com.clx.performance.service.vehiclewarn.VehicleWarnMqService;
import com.clx.performance.utils.gd.GdService;
import com.msl.common.exception.ServiceSystemException;
import com.msl.common.utils.gps.GpsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class VehicleWarnCommonServiceImpl implements VehicleWarnCommonService {
    private static final Integer MIN_FER_HOUR = 60;
    private static final Integer SEC_FER_MIN = 60;

    @Autowired
    private TruckTraceService truckTraceService;
    @Autowired
    private GdService gdService;
    @Autowired
    private VehicleWarnRangeDao vehicleWarnRangeDao;
    @Autowired
    private VehicleWarnInfoDao vehicleWarnInfoDao;
    @Autowired
    private VehicleWarnMqService vehicleWarnMqService;


    @Override
    public void vehicleWarnInfoUpdate(OrderChild orderChild, VehicleWarnInfo vehicleWarnInfo,
                                      VehicleWarnConfig vehicleWarnConfig){

        // 更新
        if (vehicleWarnInfo != null){

            // 计算下次生效时间
            LocalDateTime nextTime = vehicleWarnInfo.getWarnTime()
                    .plusMinutes(vehicleWarnConfig.getInterval().multiply(new BigDecimal(MIN_FER_HOUR)).intValue());
            if (nextTime.isAfter(LocalDateTime.now())) {return;}

            vehicleWarnInfo.setWarnTime(LocalDateTime.now());
            vehicleWarnInfoDao.updateWarnTime(vehicleWarnInfo);

            // 发送mq （预警通知）
            vehicleWarnMqService.truckWarnNotice(vehicleWarnInfo.getId());
            return;
        }

        // 新增
        vehicleWarnInfo = new VehicleWarnInfo();
        vehicleWarnInfo.setWarnConfigId(vehicleWarnConfig.getId());
        vehicleWarnInfo.setWarnType(vehicleWarnConfig.getWarnType());
        vehicleWarnInfo.setWarnName(vehicleWarnConfig.getWarnName());
        vehicleWarnInfo.setWarnLevel(vehicleWarnConfig.getWarnLevel());

        vehicleWarnInfo.setOrderGoodsNo(orderChild.getOrderGoodsNo());
        vehicleWarnInfo.setChildNo(orderChild.getChildNo());
        vehicleWarnInfo.setChildStatus(orderChild.getStatus());
        vehicleWarnInfo.setSendAddressId(orderChild.getSendAddressId());
        vehicleWarnInfo.setSendAddress(orderChild.getSendAddress());
        vehicleWarnInfo.setReceiveAddressId(orderChild.getReceiveAddressId());
        vehicleWarnInfo.setReceiveAddress(orderChild.getReceiveAddress());

        vehicleWarnInfo.setTruckId(orderChild.getTruckId());
        vehicleWarnInfo.setTruckNo(orderChild.getTruckNo());
        vehicleWarnInfo.setDriverUserNo(orderChild.getDriverUserNo());
        vehicleWarnInfo.setDriverName(orderChild.getDriverName());
        vehicleWarnInfo.setDriverMobile(orderChild.getDriverMobile());

        vehicleWarnInfo.setTakeTime(orderChild.getPayTime());
        vehicleWarnInfo.setWarnTime(LocalDateTime.now());

        vehicleWarnInfoDao.saveEntity(vehicleWarnInfo);
        // 发送mq （预警通知）
        vehicleWarnMqService.truckWarnNotice(vehicleWarnInfo.getId());
    }

    /**
     * 暂停检测
     */
    @Override
    public boolean suspendCheck(VehicleWarnChild vehicleWarnChild, Integer warnConfigId){
        // 报警暂停
        List<VehicleWarnRang> vehicleWarnRangList = vehicleWarnRangeDao.ListByWarnConfigId(warnConfigId);
        if (!vehicleWarnRangList.isEmpty()){
            for (VehicleWarnRang item : vehicleWarnRangList) {
                if (Objects.equals(item.getWarnRang(), VehicleWarnRangEnum.WarnRange.ALL.getCode())){
                    return item.getWarnEndTime().isAfter(LocalDateTime.now());
                }
                if (Objects.equals(item.getWarnRang(), VehicleWarnRangEnum.WarnRange.ORDER_GOODS.getCode())){
                    if (Objects.equals(vehicleWarnChild.getOrderGoodsNo(), item.getOrderGoodsNo())) {
                        return item.getWarnEndTime().isAfter(LocalDateTime.now());
                    }
                }
                if (Objects.equals(item.getWarnRang(), VehicleWarnRangEnum.WarnRange.CHILD.getCode())){
                    if (Objects.equals(vehicleWarnChild.getChildNo(), item.getChildNo())) {
                        return item.getWarnEndTime().isAfter(LocalDateTime.now());
                    }
                }
            }
        }

        return false;
    }

    /**
     * 获取当前位置
     */
    @Override
    public BigDecimal[] getCurrentPosition(String truckNo, Long userNo){
        BigDecimal[] currentPosition = truckTraceService.getCurrentPosition(truckNo, userNo);
        log.info("获取车辆位置, truckNo:{}, userNo:{}, currentPosition:{}", truckNo, userNo, currentPosition);
        return currentPosition;
    }

    /**
     * 获取需要时间（min）
     */
    @Override
    public int getNeedTime(BigDecimal originLongitude, BigDecimal originLatitude,
                           BigDecimal destinationLongitude, BigDecimal destinationLatitude){
        try {
            List<GdRouteDTO> gdRouteDTOS = gdService.getRoute(originLongitude, originLatitude,
                    destinationLongitude, destinationLatitude);

            if (!gdRouteDTOS.isEmpty()){
                return gdRouteDTOS.get(0).getDuration() /SEC_FER_MIN;
            }

        } catch (ServiceSystemException e) {
            log.info("获取高德线路失败, msg:{}", e.getMessage());
        }

        return 0;
    }

    /**
     * 获取需要时间（min）
     */
    @Override
    public int getNeedTime(BigDecimal[] currentPosition,
                           BigDecimal destinationLongitude, BigDecimal destinationLatitude) {
        if (currentPosition == null) {return 0;}
        return getNeedTime(currentPosition[0], currentPosition[1], destinationLongitude, destinationLatitude);
    }

    /**
     * 获取需要距离（m）
     */
    @Override
    public int getNeedDistance(BigDecimal[] currentPosition,
                               BigDecimal destinationLongitude, BigDecimal destinationLatitude){
        int needDistance = 0;

        if (currentPosition == null) {return 0;}
        try {
            List<GdRouteDTO> gdRouteDTOS = gdService.getRoute(currentPosition[0], currentPosition[1],
                    destinationLongitude, destinationLatitude);

            if (!gdRouteDTOS.isEmpty()){
                needDistance = gdRouteDTOS.get(0).getDistance();
            }

        } catch (ServiceSystemException e) {
            log.info("获取高德线路失败, msg:{}", e.getMessage());
        }

        return needDistance;
    }

    @Override
    public Integer getDistance(BigDecimal[] currentPosition,
                               BigDecimal destinationLongitude, BigDecimal destinationLatitude) {
        if (currentPosition == null) {return null;}
        return GpsUtil.distanceM(currentPosition[0], currentPosition[1], destinationLongitude, destinationLatitude);
    }
}
