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.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;

    /**
     * 出车
     *
     * @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());
        }

        // 写入车辆公里数,预计目的地
        vehicle.setMileageLastUpdate(departureVo.getMileage());
        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);

    }

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

        // 写入车辆公里数,还车分公司id
        vehicle.setMileageLastUpdate(arrivalVo.getMileage());
        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);

    }

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

        int result = vehicleMapper.updateStatusByIdAndStatus(vehicleUpkeepVo.getVehicleId(), VehicleStatus.UPKEEP.getCode(),
                VehicleStatus.NORMAL.getCode());
        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());
        }

        int result = vehicleMapper.updateStatusByIdAndStatus(vehicleId, VehicleStatus.NORMAL.getCode(), VehicleStatus.UPKEEP.getCode());
        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);


    }
}
