package com.xxfc.platform.order.rest;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.github.wxiaoqi.security.admin.feign.rest.UserRestInterface;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreUserToken;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.rest.BaseController;
import com.github.wxiaoqi.security.common.util.AssertUtils;
import com.github.wxiaoqi.security.common.util.Query;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.github.wxiaoqi.security.common.vo.PageParam;
import com.xxfc.platform.order.biz.OrderRentVehicleBiz;
import com.xxfc.platform.order.biz.SpecialRentBiz;
import com.xxfc.platform.order.entity.BaseOrder;
import com.xxfc.platform.order.entity.SpecialRent;
import com.xxfc.platform.order.mqhandler.RabbitProduct;
import com.xxfc.platform.order.pojo.order.RentVehicleBO;
import com.xxfc.platform.order.pojo.order.add.AddRentVehicleDTO;
import com.xxfc.platform.order.service.OrderRentVehicleService;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import com.xxfc.platform.vehicle.pojo.vo.VehicleVO;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.klock.annotation.Klock;
import org.springframework.web.bind.annotation.*;

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

@RestController
@RequestMapping("/chw/specialRent")
public class SpecialRentController extends BaseController<SpecialRentBiz, SpecialRent> implements UserRestInterface {

    @Autowired
    RabbitProduct rabbitProduct;

    @Autowired
    OrderRentVehicleBiz orderRentVehicleBiz;

    @Autowired
    OrderRentVehicleService orderRentVehicleService;

    @Autowired
    VehicleFeign vehicleFeign;

    @Autowired
    UserFeign userFeign;

    @Override
    public UserFeign getUserFeign() {
        return userFeign;
    }

    @RequestMapping(value = "/appBusiness/addRent", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "添加发布特惠租车")
    public ObjectRestResponse appBusinessAddRent(@RequestBody SpecialRent specialRent) {
        UserDTO userDTO = getBusinessUserByAppUser();

        baseBiz.addRent(specialRent, userDTO);

        return ObjectRestResponse.succ();
    }

    @RequestMapping(value = "/appBusiness/cnlRent", method = RequestMethod.DELETE)
    @ResponseBody
    @ApiOperation(value = "取消发布特惠租车")
    public ObjectRestResponse appBusinessCnlRent(@RequestBody SpecialRent specialRent) {
        UserDTO userDTO = getBusinessUserByAppUser();

        //查询
        SpecialRent specialRentDB = baseBiz.selectById(specialRent.getId());
        AssertUtils.isBlank(specialRentDB);
        if(SpecialRent.STATUS_CRT != specialRentDB.getStatus()) {
            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
        }

        //拒绝原来的预约
        orderRentVehicleService.errorRejectVehicle(new RentVehicleBO(){{
            setBookRecordId(specialRentDB.getBookRecordId());
        }});

        //设置车辆上架
        if(!specialRentDB.getStartCompanyId().equals(specialRentDB.getEndCompanyId())) {
            ObjectRestResponse restResponse = vehicleFeign.updVehicleFeign(new Vehicle(){{
                setId(specialRentDB.getVehicleId());
                setState(STATE_UP);
            }});
        }

        baseBiz.updateSelectiveById(new SpecialRent(){{
            setId(specialRentDB.getId());
            setStatus(SpecialRent.STATUS_CNL);
            setUpdUser(userDTO.getId().toString());
        }});

        return ObjectRestResponse.succ();
    }


    @RequestMapping(value = "/app/unauth/app/pageList", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "分页查询可参加特惠租车")
    @IgnoreUserToken
    public ObjectRestResponse<PageDataVO<SpecialRentVO>> pageList(QueryDTO dto) {
        //查询列表数据
        Query query = new Query(dto);
        PageDataVO<SpecialRentVO> pages = PageDataVO.pageInfo(query, () -> baseBiz.selectByWeekend(w -> {
            w.andIn(SpecialRent::getStatus, CollUtil.newArrayList(STATUS_CRT, STATUS_AUTOCNL_ORDER, STATUS_AUTOCNL_TOPAY, STATUS_AUTOCNL_PAYED));
            if(null != dto.getStartCityCode()) {
                w.andEqualTo(SpecialRent::getStartCityCode, dto.getStartCityCode());
            }
            if(null != dto.getEndCityCode()) {
                w.andEqualTo(SpecialRent::getEndCityCode, dto.getEndCityCode());
            }
            return w;
        }, " crt_time desc "), SpecialRentVO.class);

        return ObjectRestResponse.succ(pages);
    }

    @RequestMapping(value = "/app/unauth/app/detail", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询特惠租车详情")
    @IgnoreUserToken
    public ObjectRestResponse<SpecialRent> detail(BaseDetailDTO dto) {
        //查询数据
        AssertUtils.isBlankBean(dto);
        return ObjectRestResponse.succ(baseBiz.selectById(dto.getId()));
    }

    @RequestMapping(value = "/appBusiness/myList", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "分页查询我发布的特惠租车")
    public ObjectRestResponse<SpecialRentVO> myList(QueryDTO dto) {
        //查询列表数据
        if (StrUtil.isBlank(getCurrentUserId())) {
            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
        }
        UserDTO userDTO = getBusinessUserByAppUser();
        Query query = new Query(dto);
        PageDataVO<SpecialRentVO> pages = PageDataVO.pageInfo(query, () -> baseBiz.selectByWeekend(w -> {
            w.andEqualTo(SpecialRent::getIsDel, SYS_FALSE);
            w.andEqualTo(SpecialRent::getPublishUserId, userDTO.getId());
            return w;
        }, " crt_time desc "), SpecialRentVO.class);

        return ObjectRestResponse.succ(pages);
    }

    @RequestMapping(value = "/app/specialOrder", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "特惠租车下单")
    @Klock(name = SPECIAL_RENT_ENTITY, keys = {"#dto.specialId"})
    public ObjectRestResponse specialOrder(@RequestBody SpecialOrderDTO dto) {

        //查询列表数据
        if (StrUtil.isBlank(getCurrentUserId())) {
            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
        }

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

        SpecialRent specialRent = baseBiz.selectById(dto.getSpecialId());
        if(null == specialRent) {
            throw new BaseException(ResultCode.PARAM_ILLEGAL_CODE);
        }

        if(
                !(DateUtil.date(dto.getStartTime()).isAfterOrEquals(DateUtil.date(specialRent.getStartTime()))
                && DateUtil.date(dto.getEndTime()).isBeforeOrEquals(DateUtil.date(specialRent.getEndTime())))
        ) {
            throw new BaseException(ResultCode.PARAM_ILLEGAL_CODE);
        }
        if(SpecialRent.STATUS_ORDER == specialRent.getStatus()) {
            throw new BaseException("该特惠租车已下单", ResultCode.PARAM_ILLEGAL_CODE);
        }

//        //拒绝原来的预约
//        orderRentVehicleService.errorRejectVehicle(new RentVehicleBO(){{
//            setBookRecordId(specialRent.getBookRecordId());
//        }});

        //正式下单
        dto.setVehicleId(specialRent.getVehicleId());
        dto.setStartCompanyId(specialRent.getStartCompanyId());
        dto.setEndCompanyId(specialRent.getEndCompanyId());
        dto.setAppUserDTO(getAppUser());
        RentVehicleBO bo = orderRentVehicleBiz.initRentVehicleBO(dto);
        bo.setOrderSign(BaseOrder.ORDER_SIGN_SPECIAL);
        bo.setSpecialUnitPrice(specialRent.getUnitPrice());
        bo.setBookRecordId(specialRent.getBookRecordId());
        orderRentVehicleService.specialCreateOrder(bo, specialRent.getOrderNo());
        baseBiz.updateSelectiveById(new SpecialRent(){{
            setId(specialRent.getId());
            setStatus(SpecialRent.STATUS_ORDER);
            setOrderStatus(SpecialRent.ORDER_STATUS_TOPAY);
        }});
        return ObjectRestResponse.succ(bo.getOrder());
    }


    @RequestMapping(value = "/app/unauth/checkHasSpecialRentFegin", method = RequestMethod.GET)
    @ResponseBody
    @IgnoreUserToken
    @ApiOperation(value = "判断车辆是否有进行中的特惠租车")
    public ObjectRestResponse checkHasSpecialRent(@RequestParam("vehicleId")String vehicleId) {
        return ObjectRestResponse.succ(baseBiz.checkHasSpecialRent(vehicleId));
    }


    @RequestMapping(value = "/app/unauth/checkHasSpecialRentFeginV2", method = RequestMethod.POST)
    @ResponseBody
    @IgnoreUserToken
    @ApiOperation(value = "判断车辆是否有进行中的特惠租车")
    public ObjectRestResponse checkHasSpecialRentFeginV2(@RequestBody String vehicleId) {
        return ObjectRestResponse.succ(baseBiz.checkHasSpecialRent(vehicleId));
    }

    @Data
    public static class SpecialRentVO extends SpecialRent{
        VehicleVO vehicle;
        @Override
        public void setGoodsJson(String goodsJson) {
            super.setGoodsJson(goodsJson);
            if(StrUtil.isNotBlank(goodsJson)) {
                setVehicle(JSONUtil.toBean(goodsJson, VehicleVO.class));
                super.setGoodsJson(null);
            }
        }
    }

    @Data
    public static class QueryDTO extends PageParam {
        Integer userId;
        /**
         * 开始城市编码
         */
        @ApiModelProperty(value = "开始城市编码")
        private Integer startCityCode;

        /**
         * 结束城市编码
         */
        @ApiModelProperty(value = "结束城市编码")
        private Integer endCityCode;
    }
    @Data
    public static class SpecialOrderDTO extends AddRentVehicleDTO {
        Integer specialId;
    }
}