package com.xxfc.platform.order.rest.background;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
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.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.OrderUtil;
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.BaseOrderBiz;
import com.xxfc.platform.order.biz.OrderRentVehicleBiz;
import com.xxfc.platform.order.biz.ShuntApplyBiz;
import com.xxfc.platform.order.biz.inner.OrderCalculateBiz;
import com.xxfc.platform.order.entity.BaseOrder;
import com.xxfc.platform.order.entity.ShuntApply;
import com.xxfc.platform.order.mqhandler.RabbitProduct;
import com.xxfc.platform.order.pojo.order.OrderPageVO;
import com.xxfc.platform.order.pojo.order.RentVehicleBO;
import com.xxfc.platform.order.rest.ShuntApplyController;
import com.xxfc.platform.order.service.OrderRentVehicleService;
import com.xxfc.platform.vehicle.constant.VehicleBookRecordStatus;
import com.xxfc.platform.vehicle.entity.VehicleModel;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import com.xxfc.platform.vehicle.pojo.BookVehicleVO;
import com.xxfc.platform.vehicle.pojo.RentVehicleBookDTO;
import com.xxfc.platform.vehicle.pojo.vo.UsableVeicleVO;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.jsoup.helper.DataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_FALSE;
import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_TRUE;
import static com.xxfc.platform.order.entity.ShuntApply.STATUS_CONFIRM;
import static com.xxfc.platform.order.entity.ShuntApply.STATUS_CRT;

@RestController
@RequestMapping("/background/shuntApply")
public class BgShuntApplyController extends BaseController<ShuntApplyBiz, ShuntApply> implements UserRestInterface {


    @Autowired
    VehicleFeign vehicleFeign;

    @Autowired
    UserFeign userFeign;

    @Autowired
    OrderRentVehicleBiz orderRentVehicleBiz;

    @Autowired
    OrderCalculateBiz orderCalculateBiz;

    @Autowired
    OrderRentVehicleService orderRentVehicleService;

    @Autowired
    RabbitProduct rabbitProduct;

    @Autowired
    BaseOrderBiz baseOrderBiz;

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

    @RequestMapping(value = "/steward/list", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "根据城市查询待确认申请列表")
    public ObjectRestResponse<PageDataVO<StewardShuntApply>> stewardList(ListDTO dto) {
        //获取该城市的申请最大和最小时间
        //获取该店铺
        PageDataVO<StewardShuntApply> list = PageDataVO.pageInfo(dto.initQuery(), () -> baseBiz.selectByWeekend(w -> {
            if(null != dto.getCityCode()) {
                w.andEqualTo(ShuntApply::getStartCityCode, dto.getCityCode());
            }
            w.andEqualTo(ShuntApply::getStatus, STATUS_CRT);
            return w;
        }, " crt_time desc "), StewardShuntApply.class);

        list.getData().forEach(data -> {
            data.setVehicleModel(vehicleFeign.get(data.getModelId()).getData());
        });

//        List<StewardShuntApply> returnList = CollUtil.newArrayList();
//
//        Integer companyId = getAdminUserInfo().getCompanyId();
//
//        if(CollUtil.isNotEmpty(list)) {
//            //group by 车型
//            //List<Integer> modelList = list.parallelStream().map(ShuntApply::getModelId).distinct().collect(Collectors.toList());
//                    //.collect(Collectors.groupingBy(ShuntApply::getModelId));
//            Map<Integer, List<ShuntApply>> modelMap = list.parallelStream().collect(Collectors.groupingBy(ShuntApply::getModelId));
//
//            Long startTime = list.parallelStream().map(ShuntApply::getStartTime).min(Long::compareTo).get();
//            Long endTime = list.parallelStream().map(ShuntApply::getEndTime).max(Long::compareTo).get();
//
//            for (Integer modelId : modelMap.keySet()) {
//                RentVehicleBookDTO rbd = new RentVehicleBookDTO();
//                rbd.setModelId(modelId);
//                rbd.setParkBranchCompanyId(companyId);
//                rbd.setStartCompanyId(companyId);
//                rbd.setEndCompanyId(companyId);
//                rbd.setBookStartDate(DateUtil.date(startTime).toDateStr());
//                rbd.setBookEndDate(DateUtil.date(endTime).toDateStr());
//                rbd.setBookStartDateTime(DateUtil.date(startTime).toTimeStr());
//                rbd.setBookEndDateTime(DateUtil.date(endTime).toTimeStr());
//                //查询本公司时间段内可用车辆
//                ObjectRestResponse<PageDataVO<UsableVeicleVO>> usableVehiclePage = vehicleFeign.applyUsableVehicle(rbd);
//
//                if(CollUtil.isNotEmpty(usableVehiclePage.getData().getData())) {
//                    modelMap.get(modelId).forEach( shuntApply -> {
//                        List<UsableVeicleVO> vehicles = CollUtil.newArrayList();
//
//                        usableVehiclePage.getData().getData().forEach(usableVeicleVO -> {
//                            //判断是否预定时间内可租
//                            usableVeicleVO.setAllowRent(SYS_TRUE);
//                            //如果"必须在这时间后预定" 存在 并且 比预定开始时间 要晚，那么不允许预定
//                            if(null != usableVeicleVO.getToLiftMustAfterDate() && DateUtil.date(shuntApply.getStartTime()).isBeforeOrEquals(usableVeicleVO.getToLiftMustAfterDate())) {
//                                usableVeicleVO.setAllowRent(SYS_FALSE);
//                            }
//
//                            //如果"必须在这时间前预定" 存在 并且 比预定结束时间 要早，那么不允许预定
//                            if(null != usableVeicleVO.getToReturnMustBeforeDate() && DateUtil.date(shuntApply.getEndTime()).isAfterOrEquals(usableVeicleVO.getToReturnMustBeforeDate())) {
//                                usableVeicleVO.setAllowRent(SYS_FALSE);
//                            }
//                            if(SYS_TRUE.equals(usableVeicleVO.getAllowRent())) {
//                                vehicles.add(BeanUtil.toBean(usableVeicleVO, UsableVeicleVO.class));
//                            }
//                        });
//
//                        if(CollUtil.isNotEmpty(vehicles)) {
//                            StewardShuntApply stewardShuntApply = BeanUtil.toBean(shuntApply, StewardShuntApply.class);
//                            stewardShuntApply.setVehicles(vehicles);
//                            stewardShuntApply.setVehicleModel(vehicleFeign.get(modelId).getData());
//                            returnList.add(stewardShuntApply);
//                        }
//
//                    });
//                }
//
//            }
//
//
//        }
        return ObjectRestResponse.succ(list);
    }

    @RequestMapping(value = "/steward/confirmApply", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "后台确认申请")
    public ObjectRestResponse stewardConfirmApply(@RequestBody ConfirmApplyDTO dto) {

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

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

        ShuntApply shuntApply = baseBiz.selectById(dto.getApplyId());
        if(null == shuntApply && shuntApply.getStatus() != STATUS_CRT) {
            throw new BaseException(ResultCode.PARAM_ILLEGAL_CODE);
        }

        RentVehicleBO detail = new RentVehicleBO();
        detail.setStartTime(shuntApply.getStartTime());
        detail.setEndTime(shuntApply.getEndTime());
        detail.setVehicleId(dto.getVehicleId());
        detail.setModelId(shuntApply.getModelId());
        detail.setStartAddr(shuntApply.getStartCompanyName());
        detail.setStartCompanyId(shuntApply.getStartCompanyId());
        detail.setEndCompanyId(shuntApply.getEndCompanyId());
        detail.setOrder(new BaseOrder(){{setNo(OrderUtil.GetOrderNumber("", OrderUtil.APP_MID));}});
        detail.setRentFreeDay(SYS_FALSE);
        detail.setBookVehicleVO(new BookVehicleVO(){{
            setBookStartDate(DateUtil.date(shuntApply.getStartTime()).toDateStr());
            setBookEndDate(DateUtil.date(shuntApply.getEndTime()).toDateStr());
            setBookStartDateTime(DateUtil.date(shuntApply.getStartTime()).toString());
            setBookEndDateTime(DateUtil.date(shuntApply.getEndTime()).toString());
        }});

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

        shuntApply.setVehicleId(dto.getVehicleId());
        shuntApply.setStatus(STATUS_CONFIRM);
        shuntApply.setOrderNo(detail.getOrder().getNo());
        shuntApply.setOverTime(DateUtil.offsetHour(DateUtil.date(), 1).getTime());
        shuntApply.setConfirmUserId(getAdminUserInfo().getId());
        shuntApply.setConfirmCompanyId(getAdminUserInfo().getCompanyId());
        shuntApply.setBookRecordId(detail.getBookRecordId());
        baseBiz.updateSelectiveByIdRe(shuntApply);

        rabbitProduct.sendApplyDelayMessage(baseBiz.selectById(shuntApply.getId()), 1000L * 3601L);

        return ObjectRestResponse.succ();
    }

    @RequestMapping(value = "/steward/applyDetail", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "申请的详情")
    public ObjectRestResponse stewardApplyDetail(Integer applyId) {
        Integer companyId = getAdminUserInfo().getCompanyId();
        ShuntApply shuntApply = baseBiz.selectById(applyId);
        StewardShuntApply shuntApplyVO = BeanUtil.toBean(shuntApply, StewardShuntApply.class);
        shuntApplyVO.setVehicleModel(vehicleFeign.get(shuntApply.getModelId()).getData());
        RentVehicleBookDTO rbd = new RentVehicleBookDTO();
        rbd.setModelId(shuntApply.getModelId());
        rbd.setParkBranchCompanyId(companyId);
        rbd.setStartCompanyId(companyId);
        rbd.setEndCompanyId(companyId);
        rbd.setBookStartDate(DateUtil.date(shuntApply.getStartTime()).toDateStr());
        rbd.setBookEndDate(DateUtil.date(shuntApply.getEndTime()).toDateStr());
        rbd.setBookStartDateTime(DateUtil.date(shuntApply.getStartTime()).toTimeStr());
        rbd.setBookEndDateTime(DateUtil.date(shuntApply.getEndTime()).toTimeStr());
        //查询本公司时间段内可用车辆
        ObjectRestResponse<PageDataVO<UsableVeicleVO>> usableVehiclePage = vehicleFeign.applyUsableVehicle(rbd);

        if(CollUtil.isNotEmpty(usableVehiclePage.getData().getData())) {
            List<UsableVeicleVO> vehicles = CollUtil.newArrayList();

            usableVehiclePage.getData().getData().forEach(usableVeicleVO -> {
                //判断是否预定时间内可租
                usableVeicleVO.setAllowRent(SYS_TRUE);
                //如果"必须在这时间后预定" 存在 并且 比预定开始时间 要晚，那么不允许预定
                if(null != usableVeicleVO.getToLiftMustAfterDate() && DateUtil.date(shuntApply.getStartTime()).isBeforeOrEquals(usableVeicleVO.getToLiftMustAfterDate())) {
                    usableVeicleVO.setAllowRent(SYS_FALSE);
                }

                //如果"必须在这时间前预定" 存在 并且 比预定结束时间 要早，那么不允许预定
                if(null != usableVeicleVO.getToReturnMustBeforeDate() && DateUtil.date(shuntApply.getEndTime()).isAfterOrEquals(usableVeicleVO.getToReturnMustBeforeDate())) {
                    usableVeicleVO.setAllowRent(SYS_FALSE);
                }
                if(SYS_TRUE.equals(usableVeicleVO.getAllowRent())) {
                    vehicles.add(BeanUtil.toBean(usableVeicleVO, UsableVeicleVO.class));
                }
            });

            if(CollUtil.isNotEmpty(vehicles)) {
                shuntApplyVO.setVehicles(vehicles);
            }
        }
        return ObjectRestResponse.succ(shuntApplyVO);
    }


    @RequestMapping(value = "/steward/myApplyList", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "我的申请")
    public ObjectRestResponse myApplyList(PageDTO dto) {
        UserDTO userDTO = getAdminUserInfo();
        PageDataVO<ShuntApplyController.ShuntApplyVO> pages = PageDataVO.pageInfo(dto.initQuery(), () -> baseBiz.selectByWeekend(w -> {
            w.andEqualTo(ShuntApply::getConfirmUserId, userDTO.getId());
            if(StrUtil.isNotBlank(dto.getMultiStatus())) {
                w.andIn(ShuntApply::getStatus, CollUtil.toList(dto.getMultiStatus().split(",")));
            }
            return w;
        }), ShuntApplyController.ShuntApplyVO.class);

        pages.getData().forEach(data -> {
            data.setVehicleModel(vehicleFeign.get(data.getModelId()).getData());

            if(StrUtil.isNotBlank(data.getOrderNo())) {
                Map<String, Object> map = CollUtil.newHashMap();
                map.put("no", data.getOrderNo());
                List<OrderPageVO> list = baseOrderBiz.pageByParm(map);
                if(CollUtil.isNotEmpty(list)) {
                    data.setOrderPageVO(list.get(0));
                }
            }
        });

        return ObjectRestResponse.succ(pages);
    }


    @Data
    public static class ConfirmApplyDTO {
        Integer applyId;
        String vehicleId;
    }

    @Data
    public static class ListDTO extends PageParam {
        Integer cityCode;
    }

    @Data
    public static class PageDTO extends PageParam {
        String multiStatus;
    }

    @Data
    public static class StewardShuntApply extends ShuntApply {
        List<UsableVeicleVO> vehicles;
        VehicleModel vehicleModel;

        public VehicleModel getVehicleModel() {
            return vehicleModel;
        }

        public void setVehicleModel(VehicleModel vehicleModel) {
            this.vehicleModel = vehicleModel;
        }
    }
}