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

import com.clx.performance.dao.vehiclewarn.VehicleWarnConfigDao;
import com.clx.performance.dao.vehiclewarn.VehicleWarnInfoDao;
import com.clx.performance.dto.vehiclewarn.VehicleWarnCommonInfoDTO;
import com.clx.performance.enums.OrderChildEnum;
import com.clx.performance.enums.vehiclewarn.VehicleWarnConfigEnum;
import com.clx.performance.enums.vehiclewarn.VehicleWarnInfoEnum;
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.service.trace.TruckTraceService;
import com.clx.performance.service.vehiclewarn.VehicleWarnCommonService;
import com.clx.performance.service.vehiclewarn.VehicleWarnParkWarnService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Slf4j
@Service
public class VehicleWarnParkWarnServiceImpl implements VehicleWarnParkWarnService {
    private static final Integer MIN_FER_HOUR = 60;
    private static final Integer DISTANCE_DEFAULT = 2000;
    private static final Integer PARK_TIMEOUT_DEFAULT = 5;
    @Autowired
    private VehicleWarnConfigDao vehicleWarnConfigDao;
    @Autowired
    private VehicleWarnInfoDao vehicleWarnInfoDao;
    @Autowired
    private TruckTraceService truckTraceService;

    @Autowired
    private VehicleWarnCommonService vehicleWarnCommonService;

    /**
     * 停留超时
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void packTimeout(OrderChild orderChild, VehicleWarnChild vehicleWarnChild, VehicleWarnCommonInfoDTO commonInfo){

        // 未装车前往目的地判断
        if (!commonInfo.isGotoReceive()) {return;}
        orderChild.setLoadTime(commonInfo.getGotoReceiveTime());

        // 停留时间
        int parkTime = truckTraceService.getParkTime(vehicleWarnChild.getTruckNo(), vehicleWarnChild.getDriverUserNo(), orderChild.getLoadTime());
        log.info("停留超时,停留时间:{}", parkTime);
        if (parkTime == 0) {return;}

        List<VehicleWarnConfig> vehicleWarnConfigList = vehicleWarnConfigDao.listByWarnType(VehicleWarnConfigEnum.WarnType.PARK_TIMEOUT.getCode());
        if (vehicleWarnConfigList.isEmpty()) {return;}

        for (VehicleWarnConfig item : vehicleWarnConfigList) {
            doParkTimeout(orderChild, vehicleWarnChild, item, parkTime);
        }

    }


    private void doParkTimeout(OrderChild orderChild, VehicleWarnChild vehicleWarnChild, VehicleWarnConfig vehicleWarnConfig, int parkTime){
        VehicleWarnInfo vehicleWarnInfo = vehicleWarnInfoDao.findByChildNoAndWarnConfigId(vehicleWarnChild.getChildNo(), vehicleWarnConfig.getId()).orNull();
        if (vehicleWarnInfo != null && Objects.equals(vehicleWarnInfo.getStatus(), VehicleWarnInfoEnum.Status.RESOLVE.getCode())){
            return;
        }

        // 暂停检测
        boolean suspend = vehicleWarnCommonService.suspendCheck(vehicleWarnChild, vehicleWarnConfig.getId());
        if (suspend) {return;}

        // 超时判断
        int time = vehicleWarnConfig.getTimeoutRatio().multiply(new BigDecimal(MIN_FER_HOUR)).intValue();
        log.info("停留超时,parkTime:{}, time:{}", parkTime,time);
        if (parkTime < time){return;}

        // 更新
        vehicleWarnCommonService.vehicleWarnInfoUpdate(orderChild, vehicleWarnInfo, vehicleWarnConfig);

    }

    /**
     * 敏感区停留超时
     */
    @Override
    public void sensitiveAreaParkTimeout(OrderChild orderChild, VehicleWarnChild vehicleWarnChild, VehicleWarnCommonInfoDTO commonInfo) {

        // 未装车前往目的地判断
        if (!commonInfo.isGotoReceive()) {return;}
        orderChild.setLoadTime(commonInfo.getGotoReceiveTime());

        // 停留时间
        int parkTime = truckTraceService.getParkTime(vehicleWarnChild.getTruckNo(), vehicleWarnChild.getDriverUserNo(), vehicleWarnChild.getTakeTime());
        log.info("敏感区停留超时,停留时间:{}", parkTime);
        if (parkTime < PARK_TIMEOUT_DEFAULT) {return;}

        List<VehicleWarnConfig> vehicleWarnConfigList = vehicleWarnConfigDao.listByWarnType(VehicleWarnConfigEnum.WarnType.SENSITIVE_AREA_PARK_TIMEOUT.getCode());
        if (vehicleWarnConfigList.isEmpty()) {return;}

        for (VehicleWarnConfig item : vehicleWarnConfigList) {
            doSensitiveParkTimeout(orderChild, vehicleWarnChild, item, commonInfo);
        }

    }

    private void doSensitiveParkTimeout(OrderChild orderChild, VehicleWarnChild vehicleWarnChild, VehicleWarnConfig vehicleWarnConfig, VehicleWarnCommonInfoDTO commonInfo){
        VehicleWarnInfo vehicleWarnInfo = vehicleWarnInfoDao.findByChildNoAndWarnConfigId(vehicleWarnChild.getChildNo(), vehicleWarnConfig.getId()).orNull();
        if (vehicleWarnInfo != null && Objects.equals(vehicleWarnInfo.getStatus(), VehicleWarnInfoEnum.Status.RESOLVE.getCode())){
            return;
        }

        // 敏感区距离
        Integer sensitiveDistance = vehicleWarnCommonService.getDistance(commonInfo.getCurrentPosition(), vehicleWarnConfig.getLongitude(), vehicleWarnConfig.getLatitude());
        if (sensitiveDistance==null || sensitiveDistance > vehicleWarnConfig.getRadius()) {return;}

        // 暂停检测
        boolean suspend = vehicleWarnCommonService.suspendCheck(vehicleWarnChild, vehicleWarnConfig.getId());
        if (suspend) {return;}

        // 更新
        vehicleWarnCommonService.vehicleWarnInfoUpdate(orderChild, vehicleWarnInfo, vehicleWarnConfig);
    }

}
