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

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.vehiclewarn.VehicleWarnInfoDao;
import com.clx.performance.dao.vehiclewarn.VehicleWarnLogDao;
import com.clx.performance.dao.vehiclewarn.VehicleWarnRangeDao;
import com.clx.performance.enums.ResultEnum;
import com.clx.performance.enums.vehiclewarn.VehicleWarnInfoEnum;
import com.clx.performance.enums.vehiclewarn.VehicleWarnLogEnum;
import com.clx.performance.enums.vehiclewarn.VehicleWarnRangEnum;
import com.clx.performance.model.OrderChild;
import com.clx.performance.model.vehiclewarn.VehicleWarnInfo;
import com.clx.performance.model.vehiclewarn.VehicleWarnLog;
import com.clx.performance.model.vehiclewarn.VehicleWarnRang;
import com.clx.performance.param.pc.vehiclewarn.PageVehicleWarnInfoParam;
import com.clx.performance.param.pc.vehiclewarn.VehicleWarnInfoResolveUpdateParam;
import com.clx.performance.param.pc.vehiclewarn.VehicleWarnInfoSuspendUpdateParam;
import com.clx.performance.service.trace.TruckTraceService;
import com.clx.performance.service.vehiclewarn.VehicleWarnInfoService;
import com.clx.performance.struct.vehiclewarn.VehicleWarnInfoStruct;
import com.clx.performance.utils.LocalDateTimeUtils;
import com.clx.performance.vo.pc.trace.DriverTraceVO;
import com.clx.performance.vo.pc.trace.DriverTruckTraceVO;
import com.clx.performance.vo.pc.vehiclewarn.VehicleTraceVO;
import com.clx.performance.vo.pc.vehiclewarn.VehicleWarnInfoVO;
import com.msl.user.data.UserSessionData;
import com.msl.user.utils.TokenUtil;
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.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class VehicleWarnInfoServiceImpl implements VehicleWarnInfoService {
    private final Integer TRUCK_TRACE_DAY_MAX = 3;

    @Autowired
    private VehicleWarnInfoDao vehicleWarnInfoDao;
    @Autowired
    private VehicleWarnLogDao vehicleWarnLogDao;
    @Autowired
    private VehicleWarnRangeDao vehicleWarnRangeDao;
    @Autowired
    private OrderChildDao orderChildDao;

    @Autowired
    private VehicleWarnInfoStruct vehicleWarnInfoStruct;

    @Autowired
    private TruckTraceService truckTraceService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateSuspend(VehicleWarnInfoSuspendUpdateParam param) {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();
        LocalDateTime endTime = LocalDateTimeUtils.parseTime(param.getWarnEndTime());

        VehicleWarnInfo vehicleWarnInfo = vehicleWarnInfoDao.findById(param.getId()).orElseThrow(ResultEnum.DATA_NOT_FIND);

        vehicleWarnInfo.setSuspendTime(endTime);
        vehicleWarnInfoDao.updateSuspendTime(vehicleWarnInfo, param.getWarnRang());

        VehicleWarnLog vehicleWarnLog = new VehicleWarnLog();
        vehicleWarnLog.setInfoId(vehicleWarnInfo.getId());
        vehicleWarnLog.setType(VehicleWarnLogEnum.Type.SUSPEND.getCode());
        vehicleWarnLog.setContent(VehicleWarnLogEnum.Type.SUSPEND.getMsg());
        vehicleWarnLog.setChildNo(vehicleWarnInfo.getChildNo());
        vehicleWarnLog.setWarnName(vehicleWarnInfo.getWarnName());
        vehicleWarnLog.setWarnRang(param.getWarnRang());
        vehicleWarnLog.setWarnEndTime(endTime);
        vehicleWarnLog.setWarnTime(vehicleWarnInfo.getWarnTime());
        vehicleWarnLog.setCreateBy(loginUserInfo.getUserName());
        vehicleWarnLogDao.saveEntity(vehicleWarnLog);

        VehicleWarnRang vehicleWarnRang = new VehicleWarnRang();
        vehicleWarnRang.setWarnConfigId(vehicleWarnInfo.getWarnConfigId());
        vehicleWarnRang.setWarnName(vehicleWarnInfo.getWarnName());
        vehicleWarnRang.setWarnRang(param.getWarnRang());
        vehicleWarnRang.setOrderGoodsNo(
                Objects.equals(param.getWarnRang(), VehicleWarnRangEnum.WarnRange.ORDER_GOODS.getCode())
                        ? vehicleWarnInfo.getOrderGoodsNo() : null);
        vehicleWarnRang.setChildNo(
                Objects.equals(param.getWarnRang(), VehicleWarnRangEnum.WarnRange.CHILD.getCode())
                        ? vehicleWarnInfo.getChildNo() : null);
        vehicleWarnRang.setWarnEndTime(endTime);
        vehicleWarnRang.setStatus(endTime.isAfter(LocalDateTime.now())?
                VehicleWarnRangEnum.Status.ENABLE.getCode(): VehicleWarnRangEnum.Status.DISABLE.getCode());
        vehicleWarnRang.setCreateBy(loginUserInfo.getUserName());
        vehicleWarnRangeDao.saveEntity(vehicleWarnRang);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateResolve(VehicleWarnInfoResolveUpdateParam param) {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();

        VehicleWarnInfo vehicleWarnInfo = vehicleWarnInfoDao.findById(param.getId()).orElseThrow(ResultEnum.DATA_NOT_FIND);
        vehicleWarnInfo.setStatus(VehicleWarnInfoEnum.Status.RESOLVE.getCode());
        vehicleWarnInfoDao.updateStatus(vehicleWarnInfo);

        VehicleWarnLog vehicleWarnLog = new VehicleWarnLog();
        vehicleWarnLog.setInfoId(vehicleWarnInfo.getId());
        vehicleWarnLog.setType(VehicleWarnLogEnum.Type.RESOLVE.getCode());
        vehicleWarnLog.setContent(VehicleWarnLogEnum.Type.RESOLVE.getMsg());
        vehicleWarnLog.setChildNo(vehicleWarnInfo.getChildNo());
        vehicleWarnLog.setWarnName(vehicleWarnInfo.getWarnName());
        vehicleWarnLog.setWarnTime(vehicleWarnInfo.getWarnTime());
        vehicleWarnLog.setCreateBy(loginUserInfo.getUserName());

        vehicleWarnLogDao.saveEntity(vehicleWarnLog);
    }

    @Override
    public VehicleTraceVO getTrace(Integer id) {
        VehicleWarnInfo vehicleWarnInfo = vehicleWarnInfoDao.findById(id).orElseThrow(ResultEnum.DATA_NOT_FIND);
        OrderChild orderChild = orderChildDao.getByChildNo(vehicleWarnInfo.getChildNo()).orElseThrow(ResultEnum.DATA_NOT_FIND);

        LocalDateTime beginTime = vehicleWarnInfo.getTakeTime();
        LocalDateTime endTime = LocalDateTime.now();
        if (orderChild.getArriveSendTime() != null) {endTime = orderChild.getArriveSendTime();}
        if (orderChild.getLoadTime() != null) {endTime = orderChild.getLoadTime();}
        if (orderChild.getArriveReceiveTime() != null) {endTime = orderChild.getArriveReceiveTime();}
        if (orderChild.getUnloadTime() != null) {endTime = orderChild.getUnloadTime();}
        if (orderChild.getConfirmTime() != null) {endTime = orderChild.getConfirmTime();}
        if (orderChild.getSettleTime() != null) {endTime = orderChild.getSettleTime();}
        if (orderChild.getFinishTime() != null) {endTime = orderChild.getFinishTime();}
        if (endTime.isAfter(beginTime.plusDays(TRUCK_TRACE_DAY_MAX))) {endTime = beginTime.plusDays(TRUCK_TRACE_DAY_MAX);}      //最多查询3天

        List<DriverTruckTraceVO> truckTraceList = truckTraceService.calcTruckStayTime(truckTraceService.listTruckTraceByTime(vehicleWarnInfo.getTruckNo(), LocalDateTimeUtils.formatTime(beginTime), LocalDateTimeUtils.formatTime(endTime)));
        List<DriverTraceVO> driverTraceList = truckTraceService.calcDriverStayTime(truckTraceService.listDriverTraceByTime(vehicleWarnInfo.getDriverUserNo(), LocalDateTimeUtils.formatTime(beginTime), LocalDateTimeUtils.formatTime(endTime)));

        // 接单重车、卸车空车
        for (DriverTruckTraceVO item : truckTraceList) {
            item.setTruckStatus(2);
            if (orderChild.getCancelTime() != null){
                if (LocalDateTimeUtils.parseTime(item.getGpsTime()).isAfter(orderChild.getCancelTime())){item.setTruckStatus(1);}
            }
            if (orderChild.getUnloadTime() != null){
                if (LocalDateTimeUtils.parseTime(item.getGpsTime()).isAfter(orderChild.getUnloadTime())){item.setTruckStatus(1);}
            }
        }

        VehicleTraceVO result = new VehicleTraceVO();
        result.setDriverTraceList(driverTraceList);
        result.setTruckTraceList(truckTraceList);

        return result;
    }

    @Override
    public VehicleWarnInfoVO getInfo(Integer id) {
        return vehicleWarnInfoStruct.convert(vehicleWarnInfoDao.findById(id).orNull());

    }

    @Override
    public IPage<VehicleWarnInfoVO> pageInfo(PageVehicleWarnInfoParam param) {
        Page<VehicleWarnInfoVO> page = vehicleWarnInfoStruct.convertPage(vehicleWarnInfoDao.pageByParam(param));

        List<String> childNoList = page.getRecords().stream().map(item -> item.getChildNo()).collect(Collectors.toList());
        if (!childNoList.isEmpty()) {
            List<OrderChild> list = orderChildDao.listByChildNoList(childNoList);
            Map<String, OrderChild> map = list.stream().collect(Collectors.toMap(item -> item.getChildNo(), item -> item));
            for (VehicleWarnInfoVO record : page.getRecords()) {
                record.setStatus(map.get(record.getChildNo()).getStatus());
            }
        }
        return vehicleWarnInfoStruct.convertPage(vehicleWarnInfoDao.pageByParam(param));

    }
}
