package com.qs.mp.web.controller.api.admin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qs.mp.admin.domain.TicketPackage;
import com.qs.mp.admin.domain.param.*;
import com.qs.mp.admin.domain.vo.TicketPackageVO;
import com.qs.mp.admin.service.ITicketPackageService;
import com.qs.mp.channel.domain.Channel;
import com.qs.mp.channel.domain.ChannelOrder;
import com.qs.mp.channel.domain.ChannelOrderDetail;
import com.qs.mp.channel.domain.ChannelOrderItem;
import com.qs.mp.channel.domain.excel.ChannelOrderExcel;
import com.qs.mp.channel.domain.vo.ChannelOrderInfoVO;
import com.qs.mp.channel.domain.vo.ChannelOrderItemVO;
import com.qs.mp.channel.domain.vo.ChannelOrderVO;
import com.qs.mp.channel.domain.vo.ChannelVO;
import com.qs.mp.channel.service.IChannelOrderDetailService;
import com.qs.mp.channel.service.IChannelOrderItemService;
import com.qs.mp.channel.service.IChannelOrderService;
import com.qs.mp.channel.service.IChannelService;
import com.qs.mp.common.annotation.Log;
import com.qs.mp.common.core.domain.AjaxResult;
import com.qs.mp.common.core.page.TableDataInfo;
import com.qs.mp.common.domain.DeliveryCompany;
import com.qs.mp.common.enums.*;
import com.qs.mp.common.service.IDeliveryCompanyService;
import com.qs.mp.common.utils.DateUtils;
import com.qs.mp.user.domain.UserDeliverOrder;
import com.qs.mp.user.domain.UserDeliverOrderItem;
import com.qs.mp.user.domain.excel.DeliverOrderExcel;
import com.qs.mp.user.domain.vo.UserDeliverOrderItemVO;
import com.qs.mp.user.domain.vo.UserDeliverOrderVO;
import com.qs.mp.utils.ExcelUtil;
import com.qs.mp.web.controller.common.BaseApiController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/api/v1/mp/admin/channel/order")
@Api(tags = "渠道订单管理接口")
@AllArgsConstructor
public class ChannelOrderMgrController extends BaseApiController {

  @Autowired
  private IChannelOrderService channelOrderService;

  @Autowired
  private IChannelOrderItemService channelOrderItemService;

  @Autowired
  private IChannelOrderDetailService channelOrderDetailService;

  @Autowired
  private IChannelService channelService;

  @Autowired
  private IDeliveryCompanyService deliveryCompanyService;

  @Autowired
  private ITicketPackageService ticketPackageService;

  @Autowired
  private MapperFacade mapperFacade;

  /**
   * 订单列表
   */
  @PostMapping("/list")
  @ApiOperation(value = "订单列表" , notes = "获取所有订单信息")
  @PreAuthorize("@ss.hasPermi('order:channel:list')")
  @ApiResponses(
		  @ApiResponse(code = 200, message = "success", response = ChannelOrderVO.class)
  )
  public TableDataInfo list(@RequestBody ChannelOrderQueryParam queryParam) {
    startPage();
    QueryWrapper<ChannelOrder> queryWrapper = new QueryWrapper<ChannelOrder>();
    queryWrapper.eq(null != queryParam && null != queryParam.getChannelId(), "t1.channel_id" ,queryParam.getChannelId());
    queryWrapper.eq(null != queryParam && StringUtils.isNotBlank(queryParam.getOrderId()), "t1.order_id" ,queryParam.getOrderId());
	queryWrapper.eq(null != queryParam && null != queryParam.getStatus(), "t1.`status`" ,queryParam.getStatus());
	queryWrapper.eq(null != queryParam && null != queryParam.getType(), "t1.`type`" ,queryParam.getType());
	queryWrapper.ge(null != queryParam && null != queryParam.getStartTime(),  "t1.created_time", queryParam.getStartTime());
	queryWrapper.le(null != queryParam && null != queryParam.getEndTime(), "t1.created_time", queryParam.getEndTime());
	queryWrapper.like(null != queryParam && StringUtils.isNotBlank(queryParam.getTitle()), "t1.title", queryParam.getTitle());
    queryWrapper.orderByDesc("t1.order_id");
    List<ChannelOrderVO> channelOrderVOList = channelOrderService.selectChannelOrderVoList(queryWrapper);
    for (ChannelOrderVO channelOrderVO : channelOrderVOList) {
    	List<ChannelOrderItem> itemList = channelOrderItemService.list(new LambdaQueryWrapper<ChannelOrderItem>()
   	          .eq(ChannelOrderItem::getOrderId, channelOrderVO.getOrderId()));

   	    List<ChannelOrderItemVO> itemVOList = mapperFacade.mapAsList(itemList, ChannelOrderItemVO.class);
        channelOrderVO.setItems(itemVOList);
    }
    return getDataTable(channelOrderVOList);
  }


  @PostMapping("/order/cancel")
  @PreAuthorize("@ss.hasPermi('order:channel:ship')")
  @ApiOperation("经销商订单取消")
  public AjaxResult cancelOrder(@Validated @RequestBody ChannelOrderCancelParam param) {
	  return AjaxResult.success(channelOrderService.cancelOrderByAdmin(param));
  }

  /**
   * 订单详情
   */
  @PostMapping("/detail")
  @ApiOperation(value = "订单详情" , notes = "在订单列表页面查看详情")
  @PreAuthorize("@ss.hasPermi('order:channel:query')")
  public AjaxResult query(@RequestBody ChannelOrder order) {
    if(null == order || StringUtils.isBlank(order.getOrderId())) {
    	return error(ErrorCodeEnum.ERROR_CODE_1001);
    }
    ChannelOrder channelOrder = channelOrderService.getById(order.getOrderId());
    if(null == channelOrder || StringUtils.isBlank(channelOrder.getOrderId())) {
    	return error(ErrorCodeEnum.ERROR_CODE_1001);
    }
    ChannelOrderInfoVO channelOrderInfoVO = mapperFacade.map(channelOrder, ChannelOrderInfoVO.class);

    if(null != channelOrderInfoVO && null != channelOrderInfoVO.getChannelId()) {
    	ChannelVO channel = channelService.getChannelVoById(channelOrderInfoVO.getChannelId());
    	channelOrderInfoVO.setChannel(channel);
    }
    if(null != channelOrderInfoVO && null != channelOrderInfoVO.getDeliveryId()) {
    	DeliveryCompany deliveryCompany = deliveryCompanyService.getById(channelOrderInfoVO.getDeliveryId());
    	channelOrderInfoVO.setDeliveryCompany(deliveryCompany);
    }
    List<ChannelOrderItem> itemList = channelOrderItemService.list(new LambdaQueryWrapper<ChannelOrderItem>()
	          .eq(ChannelOrderItem::getOrderId, channelOrderInfoVO.getOrderId()));

	List<ChannelOrderItemVO> itemVOList = mapperFacade.mapAsList(itemList, ChannelOrderItemVO.class);
	if(null != itemVOList && itemVOList.size() > 0) {
		for(ChannelOrderItemVO itemVO : itemVOList) {
			if(null != itemVO && StringUtils.isNotBlank(itemVO.getBoxId())
					&& StringUtils.isNotBlank(itemVO.getOrderId())) {
				LambdaQueryWrapper<ChannelOrderDetail> detailQueryWrapper = new LambdaQueryWrapper<ChannelOrderDetail>();
				detailQueryWrapper.eq(ChannelOrderDetail::getOrderId, itemVO.getOrderId());
				detailQueryWrapper.eq(ChannelOrderDetail::getBoxId, itemVO.getBoxId());
				List<ChannelOrderDetail> detailList = channelOrderDetailService.list(detailQueryWrapper);
				itemVO.setDetailList(detailList);
			}
		}
	}
	channelOrderInfoVO.setItems(itemVOList);
    return AjaxResult.success(channelOrderInfoVO);
  }


  /**
   * 订单发货
   */
  @Log(title = "经销商订单发货", businessType = BusinessType.UPDATE)
  @PostMapping("/ship")
  @ApiOperation(value = "订单发货" , notes = "在订单发货页面提交")
  @ApiResponses(
		  @ApiResponse(code = 200, message = "操作成功", response = AjaxResult.class)
  )
  @PreAuthorize("@ss.hasPermi('order:channel:ship')")
  public AjaxResult ship(@RequestBody ChannelOrderShipParam shipParam) {
		if(null == shipParam || StringUtils.isBlank(shipParam.getOrderId())) {
			return error(ErrorCodeEnum.ERROR_CODE_1001);
		}

		ChannelOrder order  = channelOrderService.getById(shipParam.getOrderId());
		if(null == order || StringUtils.isBlank(order.getOrderId())
				|| null == order.getChannelId()) {
			return error(ErrorCodeEnum.ERROR_CODE_1001);
		}
		Integer deliveryType = shipParam.getDeliveryType();
	  if (DeliverTypeEnum.DELIVER.getValue().equals(deliveryType)) {
		  if (Objects.isNull(shipParam.getDeliveryId())) {
			  return AjaxResult.error("快递公司不能为空");
		  }
		  if (StringUtils.isBlank(shipParam.getDeliveryFlowId())) {
			  return AjaxResult.error("快递单号不能为空");
		  }
	  }

		if(null != shipParam && null != shipParam.getPkgIds()
				&& shipParam.getPkgIds().size() > 0) {
			ChannelOrder channelOrder = new ChannelOrder();
			channelOrder.setType(order.getType());

			if (DeliverTypeEnum.NO_DELIVER.getValue().equals(deliveryType)) {
				// 无需物流，设置发货时间为当前时间
				channelOrder.setOrderId(shipParam.getOrderId());
				channelOrder.setChannelId(order.getChannelId());
				channelOrder.setDeliveryTime(new Date());

			} else if (DeliverTypeEnum.DELIVER.getValue().equals(deliveryType)) {
				// 快递发货，设置物流信息
				channelOrder.setOrderId(shipParam.getOrderId());
				channelOrder.setChannelId(order.getChannelId());
				channelOrder.setDeliveryId(shipParam.getDeliveryId());
				channelOrder.setDeliveryFlowId(shipParam.getDeliveryFlowId());
				channelOrder.setDeliveryTime(new Date());
			}
			boolean rtn = channelOrderService.channelOrderShip(channelOrder, shipParam.getPkgIds());
			return rtn ? AjaxResult.success() : AjaxResult.error("发货失败");
		}
		return AjaxResult.error("发货失败");
  }

	/**
	 * 订单发货单号修改
	 */
	@Log(title = "经销商订单发货单号修改", businessType = BusinessType.UPDATE)
	@PostMapping("/ship/update")
	@ApiOperation(value = "订单发货单号修改" , notes = "在订单发货页面提交")
	@ApiResponses(
			@ApiResponse(code = 200, message = "操作成功", response = AjaxResult.class)
	)
	@PreAuthorize("@ss.hasPermi('order:channel:ship')")
	public AjaxResult updateShipInfo(@RequestBody ChannelOrderShipParam shipParam) {
		if(null == shipParam || StringUtils.isBlank(shipParam.getOrderId())) {
			return error(ErrorCodeEnum.ERROR_CODE_1001);
		}

		ChannelOrder order  = channelOrderService.getById(shipParam.getOrderId());
		if(null == order || StringUtils.isBlank(order.getOrderId())
				|| null == order.getChannelId()) {
			return error(ErrorCodeEnum.ERROR_CODE_1001);
		}

		Integer deliveryType = shipParam.getDeliveryType();
		if (DeliverTypeEnum.DELIVER.getValue().equals(deliveryType)) {
			if (Objects.isNull(shipParam.getDeliveryId())) {
				return AjaxResult.error("快递公司不能为空");
			}
			if (StringUtils.isBlank(shipParam.getDeliveryFlowId())) {
				return AjaxResult.error("快递单号不能为空");
			}
		}


		boolean rtn = false;
		if (DeliverTypeEnum.NO_DELIVER.getValue().equals(deliveryType)) {
			// 无需物流，设置单号为空，物流公司为空
			rtn = channelOrderService.update(new LambdaUpdateWrapper<ChannelOrder>()
					.set(ChannelOrder::getDeliveryId, null)
					.set(ChannelOrder::getDeliveryFlowId, null)
					.set(ChannelOrder::getStatus, DeliverOrderStatusEnum.FINISHED)
					.eq(ChannelOrder::getOrderId, shipParam.getOrderId()));

		} else if (DeliverTypeEnum.DELIVER.getValue().equals(deliveryType)) {
			// 快递发货，原逻辑
			rtn = channelOrderService.update(new LambdaUpdateWrapper<ChannelOrder>()
					.set(ChannelOrder::getDeliveryId, shipParam.getDeliveryId())
					.set(ChannelOrder::getDeliveryFlowId, shipParam.getDeliveryFlowId())
					.eq(ChannelOrder::getOrderId, shipParam.getOrderId()));
		}


		return rtn ? AjaxResult.success() : AjaxResult.error("修改失败");

	}

	@PostMapping("/item/list")
	@ApiOperation(value = "获取经销商订单盲票组列表", notes = "")
	public AjaxResult list(@RequestBody ChannelOrder order) {
		List<ChannelOrderItemVO> list = new ArrayList<ChannelOrderItemVO>();
		if (null != order && StringUtils.isNotBlank(order.getOrderId())) {
			QueryWrapper<ChannelOrderItem> queryWrapper = new QueryWrapper<ChannelOrderItem>();
			queryWrapper.eq("t1.order_id", order.getOrderId());
			list = channelOrderItemService.listChannelOrderItemVO(queryWrapper);
		}
		return AjaxResult.success(list);
	}

	@PostMapping("/ticket/pkg/list")
	@ApiOperation(value = "经销商订单发货筛选盲票包列表", notes = "")
	public AjaxResult list(@RequestBody ChannelOrderPkgParam orderPkgParam) {
		List<TicketPackageVO> list = new ArrayList<TicketPackageVO>();
		QueryWrapper<TicketPackage> queryWrapper = new QueryWrapper<TicketPackage>();
		queryWrapper.eq("t1.`status`", TicketPkgStatusEnum.FOR_SALE); // 筛选待售
		if (null != orderPkgParam && StringUtils.isNotBlank(orderPkgParam.getPkgNo())) {
			queryWrapper.like("t1.pkg_no", orderPkgParam.getPkgNo());
		}
		if (null != orderPkgParam && StringUtils.isNotBlank(orderPkgParam.getBoxId())) {
			queryWrapper.eq("t1.box_id", orderPkgParam.getBoxId());
			list = ticketPackageService.listTicketPackageVO(queryWrapper);
		} else {
			if (null != orderPkgParam && StringUtils.isNotBlank(orderPkgParam.getOrderId())) {
				// 查询订单明细
				List<ChannelOrderItem> itemList = channelOrderItemService
						.list(new LambdaQueryWrapper<ChannelOrderItem>().eq(ChannelOrderItem::getOrderId,
								orderPkgParam.getOrderId()));
				if (null != itemList && itemList.size() > 0) {
					List<String> boxIds = new ArrayList<String>();
					for (ChannelOrderItem item : itemList) {
						if (null != item && StringUtils.isNotBlank(item.getBoxId())) {
							boxIds.add(item.getBoxId());
						}
					}
					if (null != boxIds && boxIds.size() > 0) {
						queryWrapper.in("t1.box_id", boxIds);
						list = ticketPackageService.listTicketPackageVO(queryWrapper);
					}
				}
			}
		}
		return AjaxResult.success(list);
	}



	@Log(title = "提货订单导出", businessType = BusinessType.EXPORT)
	@PostMapping("/export")
	@PreAuthorize("@ss.hasPermi('order:channel:export')")
	public AjaxResult export(@RequestBody ChannelOrderQueryParam queryParam) {
		Date startTime = queryParam.getStartTime();
		Date endTime = queryParam.getEndTime();
		if (startTime == null || endTime == null) {
			return AjaxResult.error("导出数据必须设置日期范围");
		}
		if (DateUtils.diff(startTime, endTime) > 30) {
			return AjaxResult.error("导出的数据不能超过31天");
		}

		List<ChannelOrderExcel> excelList = new ArrayList<ChannelOrderExcel>();
		List<ChannelOrderVO> listAll = new ArrayList<ChannelOrderVO>();
		// 首先查询要导出的数据总数
		QueryWrapper<ChannelOrder> queryWrapper = new QueryWrapper<ChannelOrder>();
	    queryWrapper.eq(null != queryParam && null != queryParam.getChannelId(), "t1.channel_id" ,queryParam.getChannelId());
	    queryWrapper.eq(null != queryParam && StringUtils.isNotBlank(queryParam.getOrderId()), "t1.order_id" ,queryParam.getOrderId());
		queryWrapper.eq(null != queryParam && null != queryParam.getStatus(), "t1.`status`" ,queryParam.getStatus());
		queryWrapper.eq(null != queryParam && null != queryParam.getType(), "t1.`type`" ,queryParam.getType());
		queryWrapper.ge(null != queryParam && null != queryParam.getStartTime(),  "t1.created_time", queryParam.getStartTime());
		queryWrapper.le(null != queryParam && null != queryParam.getEndTime(), "t1.created_time", queryParam.getEndTime());
		queryWrapper.like(null != queryParam && StringUtils.isNotBlank(queryParam.getTitle()), "t1.title", queryParam.getTitle());
	    queryWrapper.orderByDesc("t1.order_id");

	    int totalSize = channelOrderService.selectChannelOrderCount(queryWrapper);
		if (totalSize == 0) {
			return AjaxResult.error("没有符合条件的经销商订单");
		}

		int pageSize = 2000;
		if (totalSize > pageSize) {
			int totalPage = totalSize % pageSize == 0 ? totalSize / pageSize : totalSize / pageSize + 1;
			for (int i = 0; i < totalPage; i++) {
				queryWrapper.last("limit " + (i * pageSize) + ", " + pageSize);
			    List<ChannelOrderVO> channelOrderVOList = channelOrderService.selectChannelOrderVoList(queryWrapper);
			    for (ChannelOrderVO channelOrderVO : channelOrderVOList) {
			    	List<ChannelOrderItem> itemList = channelOrderItemService.list(new LambdaQueryWrapper<ChannelOrderItem>()
			     	          .eq(ChannelOrderItem::getOrderId, channelOrderVO.getOrderId()));
				  	List<ChannelOrderItemVO> itemVOList = mapperFacade.mapAsList(itemList, ChannelOrderItemVO.class);
				  	if(null != itemVOList && itemVOList.size() > 0) {
				  		for(ChannelOrderItemVO itemVO : itemVOList) {
				  			if(null != itemVO && StringUtils.isNotBlank(itemVO.getBoxId())
				  					&& StringUtils.isNotBlank(itemVO.getOrderId())) {
				  				LambdaQueryWrapper<ChannelOrderDetail> detailQueryWrapper = new LambdaQueryWrapper<ChannelOrderDetail>();
				  				detailQueryWrapper.eq(ChannelOrderDetail::getOrderId, itemVO.getOrderId());
				  				detailQueryWrapper.eq(ChannelOrderDetail::getBoxId, itemVO.getBoxId());
				  				List<ChannelOrderDetail> detailList = channelOrderDetailService.list(detailQueryWrapper);
				  				itemVO.setDetailList(detailList);
				  			}
				  		}
				  	}
				  	channelOrderVO.setItems(itemVOList);
			    }
				if (null != channelOrderVOList && channelOrderVOList.size() > 0) {
					listAll.addAll(channelOrderVOList);
				}
			}
		} else {
			listAll = channelOrderService.selectChannelOrderVoList(queryWrapper);
		    for (ChannelOrderVO channelOrderVO : listAll) {
		    	List<ChannelOrderItem> itemList = channelOrderItemService.list(new LambdaQueryWrapper<ChannelOrderItem>()
		     	          .eq(ChannelOrderItem::getOrderId, channelOrderVO.getOrderId()));
			  	List<ChannelOrderItemVO> itemVOList = mapperFacade.mapAsList(itemList, ChannelOrderItemVO.class);
			  	if(null != itemVOList && itemVOList.size() > 0) {
			  		for(ChannelOrderItemVO itemVO : itemVOList) {
			  			if(null != itemVO && StringUtils.isNotBlank(itemVO.getBoxId())
			  					&& StringUtils.isNotBlank(itemVO.getOrderId())) {
			  				LambdaQueryWrapper<ChannelOrderDetail> detailQueryWrapper = new LambdaQueryWrapper<ChannelOrderDetail>();
			  				detailQueryWrapper.eq(ChannelOrderDetail::getOrderId, itemVO.getOrderId());
			  				detailQueryWrapper.eq(ChannelOrderDetail::getBoxId, itemVO.getBoxId());
			  				List<ChannelOrderDetail> detailList = channelOrderDetailService.list(detailQueryWrapper);
			  				itemVO.setDetailList(detailList);
			  			}
			  		}
			  	}
			  	channelOrderVO.setItems(itemVOList);
		    }
		}

		if (null != listAll && listAll.size() > 0) {
			// listAll.sort(Comparator.comparing(UserDeliverOrderVO::getOrderId));
			for (ChannelOrderVO channelOrder : listAll) {
				if (null != channelOrder && StringUtils.isNotBlank(channelOrder.getOrderId())
						&& StringUtils.isNotBlank(channelOrder.getReceiver())
						&& StringUtils.isNotBlank(channelOrder.getTel())
						&& StringUtils.isNotBlank(channelOrder.getProvince())
						&& StringUtils.isNotBlank(channelOrder.getCity())
						&& StringUtils.isNotBlank(channelOrder.getArea())
						&& StringUtils.isNotBlank(channelOrder.getAddress()) && null != channelOrder.getItems()
						&& channelOrder.getItems().size() > 0) {
					for (ChannelOrderItemVO channelOrderItem : channelOrder.getItems()) {
						if (null != channelOrderItem) {
							ChannelOrderExcel channelOrderExcel = new ChannelOrderExcel();
							channelOrderExcel.setTitle(channelOrderItem.getTitle());
							channelOrderExcel.setOrderNum(channelOrderItem.getOrderNum());
							if(null != channelOrderItem.getDetailList() && channelOrderItem.getDetailList().size() > 0) {
								StringBuffer buff = new StringBuffer();
								for(ChannelOrderDetail orderDetail: channelOrderItem.getDetailList()) {
									if(null != orderDetail && StringUtils.isNotBlank(orderDetail.getStartSn())
											&& StringUtils.isNotBlank(orderDetail.getEndSn())) {
										buff.append("("+orderDetail.getStartSn()+"-"+orderDetail.getEndSn()+")");
									}
								}
								channelOrderExcel.setSnRrange(buff.toString());
							}
							channelOrderExcel.setCreatedTime(channelOrder.getCreatedTime());
							channelOrderExcel.setItemStatus(channelOrder.getStatus().getValue() > 1 ? "已发货" : "未发货");
							channelOrderExcel.setOrderId(channelOrder.getOrderId());
							channelOrderExcel.setMemo(channelOrder.getMemo());
							channelOrderExcel.setStatus(channelOrder.getStatus().getDesc());
							channelOrderExcel.setChannelName(channelOrder.getChannelName());
							channelOrderExcel.setParentName(channelOrder.getParentName());
							channelOrderExcel.setReceiver(channelOrder.getReceiver());
							channelOrderExcel.setTel(channelOrder.getTel());
							String address = channelOrder.getProvince() + channelOrder.getCity()
									+ channelOrder.getArea() + channelOrder.getAddress();
							channelOrderExcel.setAddress(address);
							excelList.add(channelOrderExcel);
						}
					}
				}
			}
		}
		ExcelUtil<ChannelOrderExcel> util = new ExcelUtil<ChannelOrderExcel>(ChannelOrderExcel.class);
		return util.exportExcel(excelList, "经销商盲票订单导出", false);
	}
}
