package com.xxfc.platform.order.biz;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ace.cache.annotation.Cache;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.AssertUtils;
import com.github.wxiaoqi.security.common.util.OrderUtil;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.xxfc.platform.order.entity.BaseOrder;
import com.xxfc.platform.order.mqhandler.RabbitProduct;
import com.xxfc.platform.order.pojo.order.RentVehicleBO;
import com.xxfc.platform.order.service.OrderRentVehicleService;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.entity.VehicleCategory;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import com.xxfc.platform.vehicle.pojo.BookVehicleVO;
import com.xxfc.platform.vehicle.pojo.CompanyDetail;
import com.xxfc.platform.vehicle.pojo.vo.VehicleVO;
import lombok.extern.slf4j.Slf4j;
import org.mockito.internal.util.collections.Sets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.klock.annotation.Klock;
import org.springframework.stereotype.Service;

import com.xxfc.platform.order.entity.SpecialRent;
import com.xxfc.platform.order.mapper.SpecialRentMapper;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import org.springframework.web.bind.annotation.RequestBody;

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

import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_FALSE;
import static com.xxfc.platform.order.entity.SpecialRent.STATUS_CRT;
import static com.xxfc.platform.order.redis.KlockConstant.SPECIAL_RENT_ENTITY;
import static com.xxfc.platform.vehicle.entity.Vehicle.STATE_DOWN;

/**
 * 特惠租车
 *
 * @author libin
 * @email 18178966185@163.com
 * @date 2020-10-31 11:02:42
 */
@Service
@Slf4j
public class SpecialRentBiz extends BaseBiz<SpecialRentMapper, SpecialRent> {


    @Autowired
    OrderRentVehicleService orderRentVehicleService;

    @Autowired
    RabbitProduct rabbitProduct;

    @Autowired
    UserFeign userFeign;

    @Autowired
    VehicleFeign vehicleFeign;

    /**
     * 判断车辆是否有进行中的特惠租车
     * @param vehicleId
     * @return
     */
    public Boolean checkHasSpecialRent(String vehicleId) {
        List<SpecialRent> list = selectByWeekend(w -> {
            w.andIn(SpecialRent::getStatus, CollUtil.newArrayList(SpecialRent.STATUS_CRT, SpecialRent.STATUS_ORDER))
             .andEqualTo(SpecialRent::getVehicleId, vehicleId);
            return w;
        });

        if(list.size() > 0 ) {
            for(SpecialRent specialRent : list) {
                if(specialRent.getStartCompanyId().equals(specialRent.getEndCompanyId())) {
                    return Boolean.TRUE;
                }
            }
        }
        return Boolean.FALSE;
    }

    /**
     * 添加发布特惠租车
     * @param specialRent
     * @param userDTO
     */
    public void addRent(@RequestBody SpecialRent specialRent, UserDTO userDTO) {
        AssertUtils.isBlank(userDTO);
        AssertUtils.isBlank(specialRent.getUnitPrice());
        if(StrUtil.isBlank(specialRent.getVehicleId())) {
            throw new BaseException(ResultCode.PARAM_ILLEGAL_CODE);
        }

        //Vehicle vehicle = vehicleFeign.get(specialRent.getVehicleId()).getData();
        VehicleVO vehicle = vehicleFeign.getVehicleDetail(specialRent.getVehicleId()).getData();
        vehicle.setVehicleExtensions(vehicleFeign.vehicleEextensionTree(specialRent.getVehicleId()).getData());

        if(null == vehicle) {
            throw new BaseException(ResultCode.PARAM_ILLEGAL_CODE);
        }

        //判断车辆是否下架、是否已经存在一个特惠租车
        if(STATE_DOWN == vehicle.getStatus() ) {
            throw new BaseException("车辆已下架", ResultCode.PARAM_ILLEGAL_CODE);
        }

        if(checkHasSpecialRent(vehicle.getId()) ) {
            throw new BaseException("车辆已被占用", ResultCode.PARAM_ILLEGAL_CODE);
        }

        //设置当前经营门店为停靠门店、品牌id、型号id
        specialRent.setStartCompanyId(vehicle.getManageCompanyId());
        specialRent.setBrandId(vehicle.getBrandId());
        specialRent.setCategoryId(vehicle.getCategoryId());
        specialRent.setGoodsType(vehicle.getGoodsType());
        specialRent.setPriceType(vehicle.getPriceType());

        //缓存商品信息
        specialRent.setGoodsJson(JSONUtil.parse(vehicle).toString());

        DateTime startDateTime = DateUtil.date(specialRent.getStartTime());
//        DateTime endDateTime = DateUtil.date(sFpecialRent.getEndTime());
//        DateTime tomorrowBegin = DateUtil.beginOfDay(DateUtil.tomorrow());
        DateTime afterDateTime = DateUtil.offsetHour(DateUtil.date(), 1);

        if(!startDateTime.isAfterOrEquals(afterDateTime)) {
            throw new BaseException("请提前一小时特惠租车发布", ResultCode.FAILED_CODE);
        }

        if(null != specialRent.getStartCompanyId()) {
            CompanyDetail companyDetail = vehicleFeign.getCompanyDetail(specialRent.getStartCompanyId()).getData();
            specialRent.setStartCompanyName(companyDetail.getName());
            specialRent.setStartCityCode(companyDetail.getAddrCity());
            specialRent.setStartCityName(companyDetail.getCityName());
        }
        if(null != specialRent.getEndCompanyId()) {
            CompanyDetail companyDetail = vehicleFeign.getCompanyDetail(specialRent.getEndCompanyId()).getData();
            specialRent.setEndCompanyName(companyDetail.getName());
            specialRent.setEndCityCode(companyDetail.getAddrCity());
            specialRent.setEndCityName(companyDetail.getCityName());
        }
        if(null != specialRent.getCategoryId()) {
            VehicleCategory vehicleCategory = vehicleFeign.getVehicleCategory(specialRent.getCategoryId()).getData();
            specialRent.setBrandName(vehicleCategory.getBrandName());
            specialRent.setCategoryName(vehicleCategory.getName());
        }

        specialRent.setPublishUserId(userDTO.getId());
        specialRent.setCrtUser(userDTO.getId().toString());
        specialRent.setUpdUser(userDTO.getId().toString());
        specialRent.setStatus(STATUS_CRT);

        Long delayTime = handleRent(specialRent, vehicle);
        insertSelective(specialRent);
//        rabbitProduct.sendApplyRequireDelayMessage(baseBiz.selectById(shuntApply.getId()), delayTime);
        rabbitProduct.sendSpecialDelayMessage(selectById(specialRent.getId()), delayTime);
    }

    @Klock(name = SPECIAL_RENT_ENTITY, keys = {"#specialRent.id"})
    public Long handleRent(@RequestBody SpecialRent specialRent, VehicleVO vehicle) {
        RentVehicleBO detail = new RentVehicleBO();
        detail.setStartTime(specialRent.getStartTime());
        detail.setEndTime(specialRent.getEndTime());
        detail.setVehicleId(specialRent.getVehicleId());
        detail.setStartAddr(specialRent.getStartCompanyName());
        detail.setStartCompanyId(specialRent.getStartCompanyId());
        detail.setEndCompanyId(specialRent.getEndCompanyId());
        if(StrUtil.isNotBlank(specialRent.getOrderNo())) {
            if(StrUtil.isBlank(specialRent.getOldOrderNo())) {
                specialRent.setOldOrderNo("");
            }
            specialRent.setOldOrderNo(specialRent.getOldOrderNo()+ ","+ specialRent.getOrderNo());
        }
        detail.setOrder(new BaseOrder(){{setNo(OrderUtil.GetOrderNumber("", OrderUtil.APP_MID));}});
        detail.setRentFreeDay(SYS_FALSE);
        detail.setBookVehicleVO(new BookVehicleVO(){{
            setBookStartDate(DateUtil.date(specialRent.getStartTime()).toDateStr());
            setBookEndDate(DateUtil.date(specialRent.getEndTime()).toDateStr());
            setBookStartDateTime(DateUtil.date(specialRent.getStartTime()).toString());
            setBookEndDateTime(DateUtil.date(specialRent.getEndTime()).toString());
        }});

        //预约车辆
        orderRentVehicleService.acquireVehicle(detail, null , null);

        specialRent.setOrderNo(detail.getOrder().getNo());
//        specialRent.setOverTime(DateUtil.offsetHour(DateUtil.date(), 1).getTime());
        specialRent.setBookRecordId(detail.getBookRecordId());

        //设置车辆下架
        if(!specialRent.getStartCompanyId().equals(specialRent.getEndCompanyId())) {
            ObjectRestResponse restResponse = vehicleFeign.updVehicleFeign(new Vehicle(){{
                setId(vehicle.getId());
                setState(STATE_DOWN);
            }});
            log.info("设置车辆下架: {} restResponse: {}", vehicle.getId(), JSONUtil.toJsonStr(restResponse));
        }

        Date endDateTime = DateUtil.date(specialRent.getEndTime());
        Long delayTime = DateUtil.offsetHour(endDateTime, -1).getTime() - DateUtil.date().getTime();
        specialRent.setOverTime(DateUtil.offsetHour(endDateTime, -1).getTime());
        return delayTime;
    }
}