package com.xxfc.platform.order.rest;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.wxiaoqi.security.admin.entity.AppUserLogin;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.AppUserDTO;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.github.wxiaoqi.security.admin.feign.rest.UserRestInterface;
import com.github.wxiaoqi.security.admin.vo.AppUserVo;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreClientToken;
import com.github.wxiaoqi.security.common.context.BaseContextHandler;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.rest.CommonBaseController;
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.google.common.collect.Lists;
import com.xxfc.platform.activity.entity.Coupon;
import com.xxfc.platform.activity.feign.ActivityFeign;
import com.xxfc.platform.order.biz.*;
import com.xxfc.platform.order.contant.enumerate.ItemTypeEnum;
import com.xxfc.platform.order.entity.OrderItem;
import com.xxfc.platform.order.entity.OrderRentVehicleDetail;
import com.xxfc.platform.order.pojo.OrderAccompanyDTO;
import com.xxfc.platform.order.pojo.order.*;
import com.xxfc.platform.order.pojo.price.RentVehiclePriceVO;
import com.xxfc.platform.order.service.OrderRentVehicleService;
import com.xxfc.platform.tour.entity.TourUser;
import com.xxfc.platform.tour.feign.TourFeign;
import com.xxfc.platform.vehicle.common.RestResponse;
import com.xxfc.platform.vehicle.constant.VehicleBookRecordStatus;
import com.xxfc.platform.vehicle.entity.BranchCompany;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.entity.VehicleUserLicense;
import com.xxfc.platform.vehicle.feign.VehicleFeign;
import com.xxfc.platform.vehicle.pojo.BookVehicleVO;
import com.xxfc.platform.vehicle.pojo.CompanyDetail;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jodd.util.StringUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.mockito.internal.util.collections.Sets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

import static com.github.wxiaoqi.security.common.constant.CommonConstants.DATE_TIME_LINE_FORMATTER;
import static com.github.wxiaoqi.security.common.constant.CommonConstants.YMR_SLASH_FORMATTER;

@Controller
@RequestMapping("baseOrder")
@Api(value = "订单后台相关", tags = {"订单后台相关"})
@Slf4j
public class BackStageOrderController extends CommonBaseController implements UserRestInterface {

    public static final Integer STATUS_SUCCESS = 1;
    @Autowired
    BaseOrderBiz baseOrderBiz;

    @Autowired
    OrderRentVehicleBiz orderRentVehicleBiz;

    @Autowired
    OrderUserLicenseBiz orderUserLicenseBiz;

    @Autowired
    OrderRentVehicleService orderRentVehicleService;

    @Autowired
    OrderItemBiz orderItemBiz;

    @Autowired
    UserFeign userFeign;

    @Autowired
    ActivityFeign activityFeign;

    @Autowired
    TourFeign tourFeign;

    @Resource
    VehicleFeign vehicleFeign;

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

    @RequestMapping(value = "/getOrderList", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "获取后台订单列表")
    @IgnoreClientToken
    @CrossOrigin
    public ObjectRestResponse<PageDataVO<OrderListVo>> selectByUser(BaseOrderController.QueryOrderList dto) {
		UserDTO userDTO = getAdminUserInfo();
		if (userDTO == null) {
			return ObjectRestResponse.succ(new PageDataVO<>());
		}

        //车辆排班表查询订单详情
        if (dto.getOneNo()!=null) {
            dto.setPage(1);
            dto.setLimit(1);
            dto.setType(1);
        }

        if (StringUtils.isNotBlank(dto.getPhone()) || StringUtils.isNotBlank(dto.getRealName())) {
            List<AppUserLogin> appUserLoins = userFeign.getOne(dto.getPhone(), dto.getRealName());
            if (CollectionUtil.isNotEmpty(appUserLoins)) {
                List<Integer> collect = appUserLoins.parallelStream().map(AppUserLogin::getId).collect(Collectors.toList());
                dto.setUserIds(collect);
            } else {
                return ObjectRestResponse.succ(new PageDataVO<>());
            }
        }
        //获取权限公司列表
        List<BranchCompany> branchCompanies = vehicleFeign.companyAll(userDTO.getDataAll(), userDTO.getDataCompany(), userDTO.getDataZone());
        List<Integer> companyId = branchCompanies.stream().map(BranchCompany::getId).collect(Collectors.toList());
        dto.setCompanyIds(companyId);
        //大区搜索
        if (dto.getZoneId() != null) {
            if (userDTO.getDataAll() != 1 && !dto.getZoneId().equals(userDTO.getZoneId())) {
                return ObjectRestResponse.succ(new PageDataVO<>());
            } else {
                ArrayList<Integer> zoneIds = new ArrayList<>();
                zoneIds.add(dto.getZoneId());
                dto.setZoneIds(zoneIds);
            }
        }
        //所属公司筛选
        if (dto.getStartCompanyId() != null) {
            if (userDTO.getDataAll() != 1 && !dto.getStartCompanyId().equals(userDTO.getId())) {
                return ObjectRestResponse.succ(new PageDataVO<>());
            } else {
                ArrayList<Integer> companyIds = new ArrayList<>();
                companyIds.add(dto.getStartCompanyId());
                dto.setCompanyIds(companyIds);
            }
        }

        //根据车牌号或车辆编号获取订单信息
        if (StringUtils.isNotEmpty(dto.getPlateNumber()) || StringUtils.isNotEmpty(dto.getVehicleCode())) {
            List<String> vehicleIds = vehicleFeign.findbyPlateNumberAndVehicleCod(dto.getPlateNumber(), dto.getVehicleCode());
            dto.setVehicleIds(vehicleIds);
        }
        //
		if (dto.getStartTime() != null) {
			if (dto.getEndTime() == null) {
				dto.setEndTime(new Date().getTime());
			}
		}
		Query query = new Query(dto);
        PageDataVO pageDataVO = PageDataVO.pageInfo(query, () -> baseOrderBiz.listOrder(query.getSuper()));

        List<OrderListVo> list = pageDataVO.getData();
        List<Integer> userIds = list.stream().map(OrderListVo::getUserId).distinct().collect(Collectors.toList());
        if (userIds != null && userIds.size() > 0) {
            ObjectRestResponse<List<AppUserVo>> objectRestResponse = userFeign.getUsersByUserIds(userIds);
            log.info("获取用户信息：objectRestResponse = {}", objectRestResponse.getData());
            Map<Integer, AppUserVo> appvoMap = new HashMap<Integer, AppUserVo>();
            if (objectRestResponse.getData() != null) {
                for (AppUserVo appUserVo : objectRestResponse.getData()) {
                    if (appUserVo != null) {
                        appvoMap.put(appUserVo.getUserid(), appUserVo);
                    }
                }
            }


            for (OrderListVo orderPageVO : list) {
                AppUserVo appUserVo = appvoMap.get(orderPageVO.getUserId());
                if (appUserVo != null) {
                    orderPageVO.setTelephone(appUserVo.getUsername());
                    orderPageVO.setUsername(appUserVo.getNickname());
                    orderPageVO.setRealName(appUserVo.getRealname());
                    orderPageVO.setJobTitle(appUserVo.getJobTitle());
                    orderPageVO.setMemberName(appUserVo.getMemberName());
                }

                if (dto.getType()!= null&&dto.getType() == 1) {
                    String costDetail = orderPageVO.getOrderRentVehicleDetail().getCostDetail();
                    ObjectMapper objectMapper = new ObjectMapper();
                    try {
                        Map<String, Object> map = objectMapper.readValue(costDetail, Map.class);
                        String paramJson = (String) map.get("paramJson");
                        if (StringUtil.isNotBlank(paramJson)) {
                            RentVehiclePriceVO rentVehiclePriceVO = objectMapper.readValue(paramJson, RentVehiclePriceVO.class);
                            orderPageVO.setRentVehiclePriceVO(rentVehiclePriceVO);
                        }
                        List<Map<String, String>> children = (List<Map<String, String>>) map.get("children");
                        orderPageVO.setDetailsOfExpenses(children);

                    } catch (IOException e) {
                        log.error(e.getMessage(), e);
                    }

                    if (StringUtils.isNotBlank(orderPageVO.getCouponTickerNos())) {
                        String[] couponIds = orderPageVO.getCouponTickerNos().split(",");
                        List<Coupon> couponList = activityFeign.couponsByTickerNoList(Lists.newArrayList(couponIds));
                        orderPageVO.setCouponList(couponList);
                    }


                }

                if (orderPageVO.getOrderRentVehicleDetail() != null && orderPageVO.getOrderRentVehicleDetail().getVehicleId() != null) {
                    String vehicleId = orderPageVO.getOrderRentVehicleDetail().getVehicleId();
                    log.info("该订单车辆id：{}", vehicleId);
                    RestResponse<Vehicle> restResponse = vehicleFeign.findById(orderPageVO.getOrderRentVehicleDetail().getVehicleId());
                    log.info("获取车辆信息返回消息：{}", restResponse.getData());
                    if (restResponse.getData() != null) {
                        orderPageVO.setVehicleNumberPlat(restResponse.getData().getNumberPlate());
                        orderPageVO.setVehicleCode(restResponse.getData().getCode());
                    }

                    if (StringUtils.isNotBlank(orderPageVO.getOrderRentVehicleDetail().getMyDriverIds())) {
                        log.info("自己司机,驾驶人id:{}", orderPageVO.getOrderRentVehicleDetail().getMyDriverIds());
                        try {
                            List<VehicleUserLicense> orderUserLicenses = vehicleFeign.getVehicleLicenseList(orderPageVO.getOrderRentVehicleDetail().getMyDriverIds()).getData();
                            log.info("驾驶人信息:{}", orderUserLicenses);
                            if (orderUserLicenses != null && orderUserLicenses.size() > 0) {
                                OrderVehicleCrosstownDto orderVehicleCrosstownDto = new OrderVehicleCrosstownDto();
                                orderVehicleCrosstownDto.setLicenseIdCard(orderUserLicenses.get(0).getIdCard());
                                orderVehicleCrosstownDto.setLicenseImg(orderUserLicenses.get(0).getImg());
                                orderVehicleCrosstownDto.setLicenseName(orderUserLicenses.get(0).getName());
                                orderVehicleCrosstownDto.setLicensePhone(orderUserLicenses.get(0).getPhone());
                                orderPageVO.setOrderVehicleCrosstownDto(orderVehicleCrosstownDto);
                            }
                        } catch (Exception e) {
                            log.info("获取驾驶人信息失败！");
                            log.error(e.getMessage(), e);
                        }
                    }

                }
                if (orderPageVO.getOrderRentVehicleDetail() != null && orderPageVO.getOrderRentVehicleDetail().getStartCompanyId() != null && orderPageVO.getOrderRentVehicleDetail().getEndCompanyId() != null) {
                    ObjectRestResponse<CompanyDetail> startResponse = vehicleFeign.getCompanyDetail(orderPageVO.getOrderRentVehicleDetail().getStartCompanyId());
                    if (startResponse.getData() != null) {
                        orderPageVO.setStartCompanyName(startResponse.getData().getName());
                    }

                    ObjectRestResponse<CompanyDetail> restResponse = vehicleFeign.getCompanyDetail(orderPageVO.getOrderRentVehicleDetail().getEndCompanyId());
                    if (restResponse.getData() != null) {
                        orderPageVO.setEndCompanyName(restResponse.getData().getName());
                    }
                }
                //旅游
                if (orderPageVO.getOrderTourDetail() != null && orderPageVO.getOrderTourDetail().getStartCompanyId() != null) {
                    ObjectRestResponse<CompanyDetail> startResponse = vehicleFeign.getCompanyDetail(orderPageVO.getOrderTourDetail().getStartCompanyId());
                    if (startResponse.getData() != null) {
                        orderPageVO.setStartCompanyName(startResponse.getData().getName());
                    }
                    if (StringUtils.isNotBlank(orderPageVO.getOrderTourDetail().getTourUserIds())) {
                        List<TourUser> tourUsers = tourFeign.getTourUsers(orderPageVO.getOrderTourDetail().getTourUserIds()).getData();
                        orderPageVO.getOrderTourDetail().setUserVoList(tourUsers == null || tourUsers.size() <= 0 ? new ArrayList<>() : tourUsers);
                    }
                }


            }
        }
        return new ObjectRestResponse<>().data(pageDataVO);
    }

    @RequestMapping(value = "/getVehicleList", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "交还车租车订单列表")
    @IgnoreClientToken
    public ObjectRestResponse<List<OrderPageVO>> getVehicleList(BaseOrderController.QueryOrderList dto) {
        log.info("交还车租车订单列表请求参数：dto = {}", dto);
        if (dto.getStartTime() != null) {
            if (dto.getEndTime() == null) {
                dto.setEndTime(new Date().getTime());
            }
        }
        List<Integer> userIds = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getKeywords())) {
            List<Integer> list = userFeign.getUserIdByUsername(dto.getKeywords());
            if (list != null) {
                userIds.addAll(list);
            }
            if (userIds.size() <= 0) {
                return ObjectRestResponse.succ(new PageDataVO<>());
            }
        }

        UserDTO userDTO = getAdminUserInfo();
        if (userDTO == null) {
            return ObjectRestResponse.succ(new PageDataVO<>());
        }
        List<BranchCompany> branchCompanies = vehicleFeign.companyAll(userDTO.getDataAll(), userDTO.getDataCompany(), userDTO.getDataZone());
        List<Integer> companyIds = branchCompanies.stream().map(BranchCompany::getId).collect(Collectors.toList());
        if (dto.getStartCompanyId() != null) {
            if (companyIds.size() > 0) {
                if (companyIds.contains(dto.getStartCompanyId())) {
                    companyIds.clear();
                    companyIds.add(dto.getStartCompanyId());
                } else {
                    return ObjectRestResponse.succ();
                }
            } else {
                companyIds.add(dto.getStartCompanyId());
            }
        }
        dto.setCompanyIds(companyIds);
        Query query = new Query(dto);
        PageDataVO<OrderPageVO> pageDataVO = PageDataVO.pageInfo(query, () -> baseOrderBiz.getRentVehicle(query.getSuper()));
        for (OrderPageVO orderPageVO : pageDataVO.getData()) {
            if (orderPageVO.getOrderRentVehicleDetail() != null && orderPageVO.getOrderRentVehicleDetail().getVehicleId() != null) {
                ObjectRestResponse<Vehicle> restResponse = vehicleFeign.get(orderPageVO.getOrderRentVehicleDetail().getVehicleId());
                log.info("获取车辆信息返回消息：{}", restResponse.getMessage());
                if (restResponse.getData() != null) {
                    orderPageVO.setVehicalNumberPlat(restResponse.getData().getNumberPlate());
                    orderPageVO.setCode(restResponse.getData().getCode());
                }
            }
            if (orderPageVO.getUserId() != null) {
                AppUserDTO appUserDTO = userFeign.userDetailById(orderPageVO.getUserId()).getData();
                if (appUserDTO != null) {
                    orderPageVO.setUsername(appUserDTO.getUsername());
                    orderPageVO.setRealName(appUserDTO.getRealname());
                }
            }
        }
        return new ObjectRestResponse<>().data(pageDataVO);
    }

    @RequestMapping(value = "/getTourList", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "交还车旅游订单列表")
    @IgnoreClientToken
    public ObjectRestResponse<List<OrderPageVO>> getTourList(BaseOrderController.QueryOrderList dto) {
        if (dto.getStartTime() != null) {
            if (dto.getEndTime() == null) {
                dto.setEndTime(dto.getStartTime());
            }
        }
        Query query = new Query(dto);
        PageDataVO pageDataVO = PageDataVO.pageInfo(query, () -> baseOrderBiz.getTourList(query.getSuper()));
        return new ObjectRestResponse<>().data(pageDataVO);
    }

    @GetMapping(value = "/orderDetail")
    @ApiOperation(value = "交还车获取订单详情，带驾驶人信息")
    @IgnoreClientToken
    @ResponseBody
    public ObjectRestResponse<OrderPageVO> getOrderDetail(String orderNo, Boolean flag) {
        UserDTO userDTO = getAdminUserInfo();
        if (userDTO == null) {
            return ObjectRestResponse.succ(new PageDataVO<>());
        }
        if (StringUtils.isBlank(orderNo)) {
            return ObjectRestResponse.paramIsEmpty();
        }
        if(flag != null && flag == true) {
            return baseOrderBiz.orderDetail(orderNo, userDTO);
        } else {
            return baseOrderBiz.getOrderDetail(orderNo, userDTO);
        }
    }


    @ApiOperation("结合后台人员所属公司查询订单详情")
    @RequestMapping(value = "/company/{no}", method = RequestMethod.GET)
    @IgnoreClientToken
    @ResponseBody
    public ObjectRestResponse<OrderPageVO> companyGet(@PathVariable String no) {
        //查询列表数据
        if (StringUtils.isBlank(BaseContextHandler.getUserID())) {
            throw new BaseException(ResultCode.AJAX_WECHAT_NOTEXIST_CODE);
        }

        Query query = initCompanyQuery(no);
        PageDataVO<OrderPageVO> page = PageDataVO.pageInfo(query, () -> baseOrderBiz.pageByParm(query.getSuper()));
        if (page.getData().isEmpty()) {
            throw new BaseException(ResultCode.NOTEXIST_CODE);
        }
        return new ObjectRestResponse<>().data(page.getData().get(0));
    }

    @ApiOperation("更換車輛")
    @RequestMapping(value = "/bg/change-vehicle", method = RequestMethod.POST)
    @IgnoreClientToken
    @ResponseBody
    public ObjectRestResponse<OrderPageVO> changeVehicle(@RequestBody ChangeVehicleDTO dto) {
        checkAdminUser();
        //根据订单号获取订单
        //查询列表数据
        Query query = baseOrderBiz.initQuery(dto.getNo());
        query.put("crtUser", null);
        query.put("userId", null);
        PageDataVO<OrderPageVO> page = PageDataVO.pageInfo(query, () -> baseOrderBiz.pageByParm(query.getSuper()));
        OrderPageVO orderPageVO = page.getData().get(0);
        if (null == orderPageVO) {
            throw new BaseException(ResultCode.PARAM_ILLEGAL_CODE, Sets.newSet("订单不存在"));
        }
        //预约新的车辆
        RentVehicleBO bo = BeanUtil.toBean(orderPageVO.getOrderRentVehicleDetail(), RentVehicleBO.class);
        bo.setOrder(orderPageVO);
        bo.setBookVehicleVO(new BookVehicleVO() {{
            setBookStartDate(YMR_SLASH_FORMATTER.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(bo.getStartTime()), ZoneOffset.ofHours(8))));
            setBookEndDate(YMR_SLASH_FORMATTER.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(bo.getEndTime()), ZoneOffset.ofHours(8))));
            setBookStartDateTime(DATE_TIME_LINE_FORMATTER.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(bo.getStartTime()), ZoneOffset.ofHours(8))));
            setBookEndDateTime(DATE_TIME_LINE_FORMATTER.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(bo.getEndTime()), ZoneOffset.ofHours(8))));
        }});

        List<OrderAccompanyDTO> oads = JSONUtil.toList(JSONUtil.parseArray(orderItemBiz.selectOne(new OrderItem() {{
            setOrderId(orderPageVO.getId());
            setType(ItemTypeEnum.ACCOMPANY.getCode());
        }}).getDetail()), OrderAccompanyDTO.class);
        bo.setAccompanyItems(oads);
        Long oldBookRecordId = bo.getBookRecordId();
        orderRentVehicleService.acquireVehicle(bo, dto.getNumberPlate(), VehicleBookRecordStatus.APPROVE.getCode());
        //如果成功则取消旧车的预约
        RestResponse<Integer> rentUnbookResponse = vehicleFeign.rentUnbookVehicle(oldBookRecordId);
        //设置新的vehicleId 和 record
        orderRentVehicleBiz.updateSelectiveByIdRe(new OrderRentVehicleDetail() {{
            setId(bo.getId());
            setVehicleId(bo.getVehicleId());
            setBookRecordId(bo.getBookRecordId());
        }});
        return ObjectRestResponse.succ();
    }

    @PostMapping("/updateEndCompany")
    @ResponseBody
    public ObjectRestResponse updateEndCompany(@RequestBody OrderRentVehicleDetail orderRentVehicleDetail) {
        return baseOrderBiz.save(orderRentVehicleDetail);
    }

    @GetMapping(value = "/getAll")
    @ResponseBody
    public ObjectRestResponse getAllOrderList(BaseOrderController.QueryOrderList dto) {
        return backgroundBaseOrderBiz.getAllOrderList(dto);
    }

    @Data
    public static class ChangeVehicleDTO {
        String no;
        String numberPlate;
    }

    private Query initCompanyQuery(String no) {
        BackStageOrderController.QueryOrderDetailDTO qodd = new BackStageOrderController.QueryOrderDetailDTO();
        //查询公司id
        UserDTO userDto = userFeign.userinfoByToken(BaseContextHandler.getToken()).getData();
        qodd.setCrtCompanyId(userDto.getCompanyId());
        qodd.setNo(no);
        qodd.setLimit(1);
        qodd.setPage(1);
        Query query = new Query(qodd);
        return query;
    }

    /**
     * 订单查询类
     */
    @Data
    public class QueryOrderDetailDTO extends QueryOrderDTO {
        private String no;
    }
}
