package com.xxfc.platform.vehicle.biz;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.xxfc.platform.vehicle.constant.ResCode.ResCode;
import com.xxfc.platform.vehicle.constant.VehicleActiveType;
import com.xxfc.platform.vehicle.constant.VehicleBookRecordStatus;
import com.xxfc.platform.vehicle.constant.VehicleDepartureState;
import com.xxfc.platform.vehicle.constant.VehicleStatus;
import com.xxfc.platform.vehicle.entity.*;
import com.xxfc.platform.vehicle.mapper.*;
import com.xxfc.platform.vehicle.pojo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.Date;
import java.util.List;

@Service
public class VehicleActiveService {

    @Autowired
    VehicleMapper vehicleMapper;

    @Autowired
    VehicleDepartureLogMapper vehicleDepartureLogMapper;

    @Autowired
    VehicleActiveLogMapper vehicleActiveLogMapper;

    @Autowired
    VehicleUpkeepLogMapper vehicleUpkeepLogMapper;

    @Autowired
    VehicleBookRecordBiz vehicleBookRecordBiz;

    @Autowired
    VehicleUpkeepItemMapper vehicleUpkeepItemMapper;
    @Value("${vehicle.mileage}")
    private Integer Mileage;

    /**
     * 出车
     *
     * @param departureVo
     */
    @Transactional
    public void departure(VehicleDepartureVo departureVo) {
        Vehicle vehicle = vehicleMapper.selectByPrimaryKey(departureVo.getVehicleId());
        if (vehicle == null) {
            throw new BaseException(ResCode.VEHICLE_DEPARTURE_VEHICLE_UNEXIST.getDesc(),
                    ResCode.VEHICLE_DEPARTURE_VEHICLE_UNEXIST.getCode());
        }
        if (!vehicle.getStatus().equals(VehicleStatus.NORMAL.getCode())) {
            throw new BaseException(ResCode.VEHICLE_DEPARTURE_VEHICLE_DISABLE.getDesc(),
                    ResCode.VEHICLE_DEPARTURE_VEHICLE_DISABLE.getCode());
        }
        Integer MileageLift=vehicle.getMileageLastUpdate();
        Integer MileageLift1=departureVo.getMileage();
        if(MileageLift1==null){
            throw new BaseException(ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getDesc(),
                    ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getCode());
        }
        if(MileageLift==null||MileageLift1>=MileageLift){
            // 写入车辆公里数,预计目的地
            vehicle.setMileageLastUpdate(MileageLift1);
            vehicle.setExpectDestinationBranchCompanyId(departureVo.getExpectArrivalBranchCompanyId());
            vehicleMapper.updateByPrimaryKeySelective(vehicle);

            // 修改车辆状态，确认是空闲状态
            int result = vehicleMapper.updateStatusByIdAndStatus(departureVo.getVehicleId(), VehicleStatus.DEPARTURE.getCode(),
                    VehicleStatus.NORMAL.getCode());

            if (result == 0) {
                throw new BaseException(ResCode.VEHICLE_DEPARTURE_VEHICLE_DISABLE.getDesc(),
                        ResCode.VEHICLE_DEPARTURE_VEHICLE_DISABLE.getCode());
            }
            //修改预约记录状态
            if(departureVo.getBookRecordId() != null) {
                updateBookRecordStatus(departureVo.getBookRecordId());
            }
            VehicleDepartureLogVo vehicleDepartureLogVo = vehicleDepartureLogMapper.selectByBookRecordId(departureVo.getBookRecordId());
           if(vehicleDepartureLogVo != null) {
               BeanUtil.copyProperties(departureVo, vehicleDepartureLogVo, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
               VehicleDepartureLog departureLog = vehicleDepartureLogVo.getVehicleDeparture(vehicleDepartureLogVo);
               departureLog.setDepartureTime(new Date());
               departureLog.setUpdateTime(new Date());
               departureLog.setState(VehicleDepartureState.DEPARTURE.getCode());
               departureLog.setDepartureRemark(departureVo.getRemark());
               vehicleDepartureLogMapper.updateByPrimaryKeySelective(departureLog);
           } else {
               // 出车记录
               VehicleDepartureLog departureLog = new VehicleDepartureLog();
               BeanUtils.copyProperties(departureVo, departureLog);
               departureLog.setDepartureTime(new Date());
               departureLog.setCreateTime(new Date());
               departureLog.setMileageStart(departureVo.getMileage());
               departureLog.setState(VehicleDepartureState.DEPARTURE.getCode());
               departureLog.setBookRecordId(departureVo.getBookRecordId());
               departureLog.setDepartureRemark(departureVo.getRemark());
               vehicleDepartureLogMapper.insert(departureLog);
           }


            // 车辆活动日志
            VehicleActiveLog activeLog = new VehicleActiveLog();
            activeLog.setVehicleId(departureVo.getVehicleId());
            activeLog.setActiveType(VehicleActiveType.Departure.getCode());
            activeLog.setStartTime(new Date());
            activeLog.setCreateTime(new Date());
            vehicleActiveLogMapper.insert(activeLog);
        }else {
            throw new BaseException(ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getDesc(),
                    ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getCode());
        }
    }

    @Transactional
    public void arrival(VehicleArrivalVo arrivalVo) {
        Vehicle vehicle = vehicleMapper.selectByPrimaryKey(arrivalVo.getVehicleId());
        if (vehicle == null) {
            throw new BaseException(ResCode.VEHICLE_DEPARTURE_VEHICLE_UNEXIST.getDesc(),
                    ResCode.VEHICLE_DEPARTURE_VEHICLE_UNEXIST.getCode());
        }
        if (!vehicle.getStatus().equals(VehicleStatus.DEPARTURE.getCode())) {
            throw new BaseException(ResCode.VEHICLE_DEPARTURE_VEHICLE_UNDEPARTURE.getDesc(),
                    ResCode.VEHICLE_DEPARTURE_VEHICLE_UNDEPARTURE.getCode());
        }
        Integer Mileagerest = vehicle.getMileageLastUpdate();
        Integer Mileagerest1 = arrivalVo.getMileage();
        if (Mileagerest1 == null) {
            throw new BaseException(ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getDesc(),
                    ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getCode());
        }
        if (Mileagerest != null && Mileagerest1 >= Mileagerest) {

            // 写入车辆公里数,还车分公司id
            vehicle.setMileageLastUpdate(Mileagerest1);
            vehicle.setParkBranchCompanyId(arrivalVo.getArrivalBranchCompanyId());
            vehicle.setExpectDestinationBranchCompanyId(0);
            vehicleMapper.updateByPrimaryKeySelective(vehicle);

            // 修改状态，确认是出车状态
            int result = vehicleMapper.updateStatusByIdAndStatus(arrivalVo.getVehicleId(), VehicleStatus.NORMAL.getCode(),
                    VehicleStatus.DEPARTURE.getCode());
            if (result == 0) {
                throw new BaseException(ResCode.VEHICLE_DEPARTURE_VEHICLE_UNDEPARTURE.getDesc(),
                        ResCode.VEHICLE_DEPARTURE_VEHICLE_UNDEPARTURE.getCode());
            }

            if(arrivalVo.getBookRecordId() != null) {
                updateBookRecordStatus(arrivalVo.getBookRecordId());
            }


            // 出车记录
            VehicleDepartureLog departureLog = vehicleDepartureLogMapper.selectLastByVehicleId(arrivalVo.getVehicleId());
            if (departureLog == null) {
                throw new BaseException(ResCode.VEHICLE_DEPARTURE_VEHICLE_UNDEPARTURE.getDesc(),
                        ResCode.VEHICLE_DEPARTURE_VEHICLE_UNDEPARTURE.getCode());
            }
                departureLog.setMileageEnd(arrivalVo.getMileage());
                departureLog.setRecycleMan(arrivalVo.getRecycleMan());
                departureLog.setRecycleManTel(arrivalVo.getRecycleManTel());
                departureLog.setArrivalBranchCompanyId(arrivalVo.getArrivalBranchCompanyId());
                departureLog.setUpdateTime(new Date());
                departureLog.setArrivalTime(new Date());
                departureLog.setState(VehicleDepartureState.END.getCode());
                departureLog.setIllegalPic(arrivalVo.getIllegalPic());
                departureLog.setIllegalAmount(arrivalVo.getIllegalAmount());
                departureLog.setArrivalPic(arrivalVo.getArrivalPic());
                departureLog.setArrivalRemark(arrivalVo.getRemark());
                vehicleDepartureLogMapper.updateByPrimaryKeySelective(departureLog);
            // 车辆活动日志
            VehicleActiveLog activeLog = vehicleActiveLogMapper.selectLastByVehicleId(arrivalVo.getVehicleId());
            if (activeLog == null) {
                throw new BaseException(ResCode.VEHICLE_DEPARTURE_VEHICLE_UNDEPARTURE.getDesc(),
                        ResCode.VEHICLE_DEPARTURE_VEHICLE_UNDEPARTURE.getCode());
            }
            activeLog.setEndTime(new Date());
            activeLog.setUpdateTime(new Date());
            vehicleActiveLogMapper.updateByPrimaryKeySelective(activeLog);

        } else {
            throw new BaseException(ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getDesc(),
                    ResCode.VEHICLE_BOOKED_RECORD_MILEAGE_CHANGED.getCode());
        }
    }

    public void updateBookRecordStatus(Integer bookRecordId) {
        VehicleBookRecord vehicleBookRecord = vehicleBookRecordBiz.selectById(bookRecordId);
        if(vehicleBookRecord != null) {
            vehicleBookRecord.setStatus(VehicleBookRecordStatus.LIFTED.getCode());
            vehicleBookRecordBiz.updateSelectiveByIdRe(vehicleBookRecord);
        } else {
            throw new BaseException(ResCode.VEHICLE_BOOK_RECORD_IS_NOT_EXIST.getDesc(),
                    ResCode.VEHICLE_BOOK_RECORD_IS_NOT_EXIST.getCode());
        }
    }


    /**
     * 车辆保养
     * @param vehicleUpkeepVo
     */
    @Transactional
    public void upkeep(VehicleUpkeepVo vehicleUpkeepVo) {

        Vehicle vehicle = vehicleMapper.selectByPrimaryKey(vehicleUpkeepVo.getVehicleId());
        if (vehicle == null) {
            throw new BaseException(ResCode.VEHICLE_UPKEEP_VEHICLE_UNEXIST.getDesc(),
                    ResCode.VEHICLE_UPKEEP_VEHICLE_UNEXIST.getCode());
        }
        if (!vehicle.getStatus().equals(VehicleStatus.NORMAL.getCode())) {
            // 车辆非正常状态
            throw new BaseException(ResCode.VEHICLE_UPKEEP_VEHICLE_DISABLE.getDesc(),
                    ResCode.VEHICLE_UPKEEP_VEHICLE_DISABLE.getCode());
        }
        Integer lastMileage=vehicleUpkeepVo.getMileage();
        int result = vehicleMapper.upMileageByIdAndStatus(vehicleUpkeepVo.getVehicleId(), VehicleStatus.UPKEEP.getCode(),
                VehicleStatus.NORMAL.getCode(),lastMileage);
        if (result == 0) {
            // 车辆状态异常
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new BaseException(ResCode.VEHICLE_UPKEEP_VEHICLE_DISABLE.getDesc(),
                    ResCode.VEHICLE_UPKEEP_VEHICLE_DISABLE.getCode());
        }

        // 维修记录
        VehicleUpkeepLog vehicleUpkeepLog = new VehicleUpkeepLog();
        BeanUtils.copyProperties(vehicleUpkeepVo, vehicleUpkeepLog);
        vehicleUpkeepLog.setCreateTime(new Date());
        vehicleUpkeepLogMapper.insertSelective(vehicleUpkeepLog);

        // 维修项目
        List<Integer> upkeepItems = vehicleUpkeepVo.getUpkeepItems();
        for (Integer itemId : upkeepItems) {
            if (vehicleUpkeepItemMapper.selectByPrimaryKey(itemId) == null) {
                // 保养项目不存在
                throw new BaseException(ResCode.VEHICLE_UPKEEP_ITEM_UNEXIST.getDesc(),
                        ResCode.VEHICLE_UPKEEP_ITEM_UNEXIST.getCode());
            }
        }
        vehicleUpkeepLogMapper.addItems(vehicleUpkeepLog.getId(), upkeepItems);

        // 活动记录
        VehicleActiveLog vehicleActiveLog = new VehicleActiveLog();
        vehicleActiveLog.setVehicleId(vehicleUpkeepVo.getVehicleId());
        vehicleActiveLog.setActiveType(VehicleActiveType.UPKEEP.getCode());
        vehicleActiveLog.setCreateTime(new Date());
        vehicleActiveLog.setStartTime(new Date());
        vehicleActiveLogMapper.insertSelective(vehicleActiveLog);
    }

    /**
     * 保养结束
     * @param vehicleUpkeepEndVo
     */
    @Transactional
    public void upkeepEnd(VehicleUpkeepEndVo vehicleUpkeepEndVo) {
        String vehicleId = vehicleUpkeepEndVo.getVehicleId();
        Vehicle vehicle = vehicleMapper.selectByPrimaryKey(vehicleId);
        if (vehicle == null) {
            throw new BaseException(ResCode.VEHICLE_UPKEEP_VEHICLE_UNEXIST.getDesc(),
                    ResCode.VEHICLE_UPKEEP_VEHICLE_UNEXIST.getCode());
        }
        if (!vehicle.getStatus().equals(VehicleStatus.UPKEEP.getCode())) {
            // 车辆非保养状态
            throw new BaseException(ResCode.VEHICLE_UPKEEP_VEHICLE_UNUPKEEP.getDesc(),
                    ResCode.VEHICLE_UPKEEP_VEHICLE_UNUPKEEP.getCode());
        }
        Integer mileageLastUpdate=vehicle.getMileageLastUpdate()==null?0:vehicle.getMileageLastUpdate();
        Integer maintenance_mileage=Mileage+mileageLastUpdate;
        int result = vehicleMapper.updateMileageStatusByIdAndStatus(vehicleId, VehicleStatus.NORMAL.getCode(), VehicleStatus.UPKEEP.getCode(),maintenance_mileage);
        if (result == 0) {
            throw new BaseException(ResCode.VEHICLE_UPKEEP_VEHICLE_UNUPKEEP.getDesc(),
                    ResCode.VEHICLE_UPKEEP_VEHICLE_UNUPKEEP.getCode());
        }

        VehicleUpkeepLog vehicleUpkeepLog = vehicleUpkeepLogMapper.selectLastByVehicleId(vehicleId);
        if (vehicleUpkeepLog == null) {
            throw new BaseException(ResCode.VEHICLE_UPKEEP_VEHICLE_UNUPKEEP.getDesc(),
                    ResCode.VEHICLE_UPKEEP_VEHICLE_UNUPKEEP.getCode());
        }

        VehicleActiveLog vehicleActiveLog = vehicleActiveLogMapper.selectLastByVehicleId(vehicleId);
        if (vehicleActiveLog == null || !vehicleActiveLog.getActiveType().equals(VehicleActiveType.UPKEEP.getCode())) {
            throw new BaseException(ResCode.VEHICLE_UPKEEP_VEHICLE_UNUPKEEP.getDesc(),
                    ResCode.VEHICLE_UPKEEP_VEHICLE_UNUPKEEP.getCode());
        }
        vehicleActiveLog.setEndTime(new Date());
        vehicleActiveLog.setUpdateTime(new Date());
        vehicleActiveLogMapper.updateByPrimaryKeySelective(vehicleActiveLog);


    }
}
