package com.xinxincaravan.caravan.vehicle.biz;

import com.github.wxiaoqi.security.common.exception.BaseException;
import com.xinxincaravan.caravan.vehicle.constant.ResCode.ResCode;
import com.xinxincaravan.caravan.vehicle.constant.VehicleActiveType;
import com.xinxincaravan.caravan.vehicle.constant.VehicleDepartureState;
import com.xinxincaravan.caravan.vehicle.constant.VehicleStatus;
import com.xinxincaravan.caravan.vehicle.entity.*;
import com.xinxincaravan.caravan.vehicle.mapper.*;
import com.xinxincaravan.caravan.vehicle.vo.VehicleArrivalVo;
import com.xinxincaravan.caravan.vehicle.vo.VehicleDepartureVo;
import com.xinxincaravan.caravan.vehicle.vo.VehicleUpkeepEndVo;
import com.xinxincaravan.caravan.vehicle.vo.VehicleUpkeepVo;
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 org.springframework.transaction.interceptor.TransactionAttribute;

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
    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());
            }

            // 出车记录
            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());
            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());
            }

            // 出车记录
            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());
            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());
        }
    }

    /**
     * 车辆保养
     * @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);


    }
}
