package com.xxfc.platform.vehicle.rest;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.rest.UserRestInterface;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreClientToken;
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.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.xxfc.platform.vehicle.biz.VehicleBiz;
import com.xxfc.platform.vehicle.biz.VehiclePlatCataBiz;
import com.xxfc.platform.vehicle.common.BaseController;
import com.xxfc.platform.vehicle.common.RestResponse;
import com.xxfc.platform.vehicle.constant.BookType;
import com.xxfc.platform.vehicle.constant.VehicleBookRecordStatus;
import com.xxfc.platform.vehicle.constant.VehicleMemberType;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.entity.VehicleBookRecord;
import com.xxfc.platform.vehicle.pojo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.HashSet;

import static com.github.wxiaoqi.security.common.constant.CommonConstants.*;
import static com.xxfc.platform.vehicle.constant.VehicleConstant.USER_APP;
import static com.xxfc.platform.vehicle.constant.VehicleConstant.USER_APP_NAME;

@RestController
@RequestMapping("/vehicleInfo")
@Slf4j
@IgnoreClientToken
@Api(value="租车相关车辆管理controller",tags={"租车相关车辆管理接口"})
public class RentVehicleController extends BaseController<VehicleBiz> implements UserRestInterface {

    @Autowired
    private VehiclePlatCataBiz vehiclePlatCataBiz;

    @Autowired
    UserFeign userFeign;

    @Autowired
    VehicleBiz vehicleBiz;

    public UserFeign getUserFeign() {
        return userFeign;
    }

    /**
     * 租车拒绝预定车辆申请
     *
     * @param bookRecordId
     * @return
     */
    @RequestMapping(value = "/rent/book/reject/{bookRecordId}", method = RequestMethod.PUT)
    @ApiOperation(value = "租车拒绝预定车辆")
    @IgnoreUserToken
    public RestResponse<Integer> rentRejectVehicleBooking(@PathVariable Long bookRecordId) throws Exception {
        //默认USER_APP 预约
        Integer operatorId = USER_APP;
        String userName = USER_APP_NAME;
        return baseBiz.reviewVehicleBooking(operatorId, bookRecordId, VehicleBookRecordStatus.REJECTED.getCode(), userName, "租车订单取消", Boolean.TRUE);
    }

    /**
     * 取消车辆预订
     *
     * @param bookRecordId
     * @return
     */
    @RequestMapping(value = "/rent/unbook/{bookRecordId}", method = RequestMethod.DELETE)
    @ApiOperation(value = "取消预定车辆")
    @IgnoreUserToken
    public RestResponse<Integer> rentUnbookVehicle(@PathVariable Long bookRecordId) throws Exception {
        //默认USER_APP 预约
        Integer operatorId = USER_APP;
        String userName = USER_APP_NAME;
        return baseBiz.unbookVehicle4Employee(operatorId, bookRecordId, userName,null, Boolean.TRUE);
    }

    /**
     * 批准预定车辆预定
     *
     * @param bookRecordId
     * @return
     */
    @RequestMapping(value = "/rent/book/prove/{bookRecordId}", method = RequestMethod.PUT)
    @ApiOperation(value = "预定车辆审核通过")
    @IgnoreUserToken
    public RestResponse<Integer> rentProveVehicleBooking(@PathVariable Long bookRecordId) throws Exception {
        //默认USER_APP 预约
        Integer operatorId = USER_APP;
        String userName = USER_APP_NAME;
        return baseBiz.reviewVehicleBooking(operatorId, bookRecordId, VehicleBookRecordStatus.APPROVE.getCode(), userName, "", Boolean.TRUE);
    }

    /**
     * 可用车辆查询
     *
     * @param dto
     * @return
     */
    @ApiOperation("可用车辆查询")
    @RequestMapping(value = "/rent/usable-vehicle", method = RequestMethod.GET)
    @IgnoreUserToken
    public ObjectRestResponse<PageDataVO<UsableVehicleModelVO>> rentUsableVehicle(UsableVeicleDTO dto) throws Exception {
        //根据时间 获得 可用车辆
        //结合车型
        if (StringUtils.isNotBlank(dto.getCatasStr())) {
            dto.setCatas(vehiclePlatCataBiz.groupCatasByParent(dto.getCatasStr()));
        }
        //设置显示是否有车
        dto.setYearNo4Where(Boolean.TRUE);
        return ObjectRestResponse.succ(vehicleBiz.searchUsableModel(dto));
    }

    /**
     * 后台查询可用车辆(车型)
     *
     * @param dto
     * @return
     */
    @ApiOperation("后台可用车辆查询")
    @RequestMapping(value = "/rent/back-stage/usable-vehicle", method = RequestMethod.GET)
    @IgnoreUserToken
    public ObjectRestResponse<PageDataVO<UsableVehicleModelVO>> rentBgUsableVehicle(UsableVeicleDTO dto) throws Exception {
        //根据时间 获得 可用车辆
        //结合车型
        if (StringUtils.isNotBlank(dto.getCatasStr())) {
            dto.setCatas(vehiclePlatCataBiz.groupCatasByParent(dto.getCatasStr()));
        }
        //设置显示是否有车
        dto.setYearNo4Where(Boolean.TRUE);
        //dto.setUseType(null);
        return ObjectRestResponse.succ(vehicleBiz.searchUsableModelBackStage(dto));
    }

    /**
     * 热门车型
     *
     * @param dto
     * @return
     */
    @ApiOperation("热门车型")
    @RequestMapping(value = "/rent/hot-vehicle", method = RequestMethod.GET)
    @IgnoreUserToken
    public ObjectRestResponse<PageDataVO<UsableVehicleModelVO>> hotVehicle(HotVeicleDTO dto) throws Exception {
        return ObjectRestResponse.succ(vehicleBiz.hotModel(dto));
    }

    /**
     * 租车触发的申请预定车辆
     *
     * @param dto
     * @return
     */
    @ApiOperation("租车触发的申请预定车辆")
    @RequestMapping(value = "/rent/book/vehicle", method = RequestMethod.POST)
    @IgnoreClientToken
    @IgnoreUserToken
    public ObjectRestResponse<VehicleBookRecord> rentApplyVehicle(@RequestBody RentVehicleBookDTO dto) throws Exception {
        //默认USER_APP 预约
        Integer operatorId = USER_APP;
        String userName = dto.getUserName();
        String bookVehicleId;
        if(StrUtil.isNotBlank(dto.getNumberPlate())) {
            Vehicle vehicle = vehicleBiz.selectOne(new Vehicle(){{
                setNumberPlate(dto.getNumberPlate());
                setIsDel(SYS_FALSE);
            }});
            bookVehicleId = vehicle.getId();
        }else {
            dto.setLimit(1);
            dto.setPage(1);
            dto.setParkBranchCompanyId(dto.getLiftCompany());
            dto.setStartCompanyId(dto.getLiftCompany());
            dto.setEndCompanyId(dto.getEndCompanyId());
            //查询可车辆信息
            PageDataVO<Vehicle> pageDataVO = vehicleBiz.searchUsableVehicle(dto);
            if (pageDataVO.getData().size() <= 0 && (dto.getMemberUse() == null || dto.getMemberUse().equals(VehicleMemberType.NO.getCode()))) {

                throw new BaseException(ResultCode.NOTEXIST_CODE, new HashSet<String>(){{
                    add("可用车辆不存在");
                }});
            } else  if (pageDataVO.getData().size() <= 0 && (dto.getMemberUse() == null ||!dto.getMemberUse().equals(VehicleMemberType.NO.getCode()))) {
                throw new BaseException(ResultCode.NOTEXIST_CODE, new HashSet<String>(){{
                    add("仅剩托管车辆，无法使用免费天数，请关闭会员特权");
                }});
            }
            bookVehicleId = pageDataVO.getData().get(0).getId();
        }
        //判断是否为今天，如果是则设置为30秒后开始 防止预约开始时间比当前时间 要 前
        if(DateUtil.today().equals(dto.getBookStartDate())) {
            LocalDateTime ldt = LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneOffset.ofHours(8)).plusSeconds(30L);
            dto.setBookStartDate(DateTimeFormatter.ofPattern(DATE_TIME_LINE).format(ldt));
        }else {
            dto.setBookStartDate(dto.getBookStartDateTime());
        }
        dto.setBookEndDate(dto.getBookEndDateTime());
        BookVehicleVO bookVehicleVo = BeanUtil.toBean(dto, BookVehicleVO.class);
        bookVehicleVo.setBookType(BookType.USER_RENT.getCode());
        bookVehicleVo.setVehicleId(bookVehicleId);
        if(null != dto.getStatus()) {
            bookVehicleVo.setStatus(dto.getStatus());
        }else {
            bookVehicleVo.setStatus(VehicleBookRecordStatus.APPLY.getCode());
        }
        VehicleBookRecord vehicleBookRecord = baseBiz.applyVehicle(operatorId, bookVehicleVo, userName);
        return ObjectRestResponse.succ(vehicleBookRecord);
    }
}
