package cn.newfeifan.mall.module.trade.service.order;

import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.framework.common.pojo.echarts.EChartsResult;
import cn.newfeifan.mall.module.pay.controller.admin.order.vo.PayOrderPageItemRespVO;
import cn.newfeifan.mall.module.trade.controller.admin.order.vo.TradeOrderPageItemRespVO;
import cn.newfeifan.mall.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
import cn.newfeifan.mall.module.trade.controller.admin.order.vo.TradeOrderSummaryRespVO;
import cn.newfeifan.mall.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
import cn.newfeifan.mall.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.newfeifan.mall.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.newfeifan.mall.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;

import java.time.LocalDate;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import static java.util.Collections.singleton;

/**
 * 交易订单【读】 Service 接口
 *
 * @author 非繁源码
 */
public interface TradeOrderQueryService {

    // =================== Order ===================

    /**
     * 获得指定编号的交易订单
     *
     * @param id 交易订单编号
     * @return 交易订单
     */
    TradeOrderDO getOrder(Long id);

    /**
     * 获得指定用户，指定的交易订单
     *
     * @param userId 用户编号
     * @param id     交易订单编号
     * @return 交易订单
     */
    TradeOrderDO getOrder(Long userId, Long id);

    /**
     * 获得指定用户，指定活动，指定状态的交易订单
     *
     * @param userId     用户编号
     * @param combinationActivityId 活动编号
     * @param status     订单状态
     * @return 交易订单
     */
    TradeOrderDO getOrderByUserIdAndStatusAndCombination(Long userId, Long combinationActivityId, Integer status);

    /**
     * 获得订单列表
     *
     * @param ids 订单编号数组
     * @return 订单列表
     */
    List<TradeOrderDO> getOrderList(Collection<Long> ids);

    /**
     * 【管理员】获得交易订单分页
     *
     * @param reqVO 分页请求
     * @return 交易订单
     */
    PageResult<TradeOrderDO> getOrderPage(TradeOrderPageReqVO reqVO);

    /**
     * 获得订单统计
     *
     * @param reqVO 请求参数
     * @return 订单统计
     */
    TradeOrderSummaryRespVO getOrderSummary(TradeOrderPageReqVO reqVO);

    /**
     * 【会员】获得交易订单分页
     *
     * @param userId 用户编号
     * @param reqVO  分页请求
     * @return 交易订单
     */
    PageResult<TradeOrderDO> getOrderPage(Long userId, AppTradeOrderPageReqVO reqVO);

    /**
     * 【会员】获得交易订单数量
     *
     * @param userId       用户编号
     * @param status       订单状态。如果为空，则不进行筛选
     * @param commonStatus 评价状态。如果为空，则不进行筛选
     * @return 订单数量
     */
    Long getOrderCount(Long userId, Integer status, Boolean commonStatus);

    /**
     * 【前台】获得订单的物流轨迹
     *
     * @param id     订单编号
     * @param userId 用户编号
     * @return 物流轨迹数组
     */
    List<ExpressTrackRespDTO> getExpressTrackList(Long id, Long userId);

    /**
     * 【后台】获得订单的物流轨迹
     *
     * @param id 订单编号
     * @return 物流轨迹数组
     */
    List<ExpressTrackRespDTO> getExpressTrackList(Long id);

    /**
     * 获得指定用户，指定的交易订单项
     *
     * @param userId 用户编号
     * @param itemId 交易订单项编号
     * @return 交易订单项
     */
    TradeOrderItemDO getOrderItem(Long userId, Long itemId);

    /**
     * 获得交易订单项
     *
     * @param id 交易订单项编号 itemId
     * @return 交易订单项
     */
    TradeOrderItemDO getOrderItem(Long id);

    /**
     * 根据交易订单编号，查询交易订单项
     *
     * @param orderId 交易订单编号
     * @return 交易订单项数组
     */
    default List<TradeOrderItemDO> getOrderItemListByOrderId(Long orderId) {
        return getOrderItemListByOrderId(singleton(orderId));
    }

    /**
     * 根据交易订单编号数组，查询交易订单项
     *
     * @param orderIds 交易订单编号数组
     * @return 交易订单项数组
     */
    List<TradeOrderItemDO> getOrderItemListByOrderId(Collection<Long> orderIds);

    /**
     * 根据条件获取订单数量
     * @param reqVO 条件
     * @param status 订单状态
     * @return 数量
     */
    Long getOrderCount(Integer status, TradeOrderPageReqVO reqVO);

    /**
     * 补充订单编号以及商品图片
     * @param list
     * @return
     */
    List<PayOrderPageItemRespVO> getOrderNoAndPicUrl(List<PayOrderPageItemRespVO> list);


    /**
     * 获取商户订单总数
     * @param key
     * @return
     */
    Integer getShopSalesVolume(Long key);


    /**
     * 获取商户下的订单
     * @param id 订单id
     * @return 该商户下的订单
     */
    List<TradeOrderDO> getOrderByMerId(Long id);

    TradeOrderDO getOrderById(Long orderId);

    /**
     * 获取待发货订单
     * @return 集合
     */
    Map<String, Long> getBacklogOrder();

    /**
     * 获取待售后订单
     * @return 售后订单
     */
    Map<String, Long> getBacklogAfterSale();

    /**
     * 用来判断当前的这个订单中的商品是不是虚拟商品
     * @param orderItems 订单项
     * @return 0 是虚拟商品
     */
    Integer getSpuType(List<TradeOrderItemDO> orderItems);

    Integer getSpuTypeByList(List<TradeOrderPageItemRespVO.Item> items);

    /**
     * 获取状态为退款的订单
     * @param refundStatus 订单状态
     * @param reqVO 条件
     * @return 数量
     */
    Long getOrderCountByRefundStatus(Integer refundStatus, TradeOrderPageReqVO reqVO);

    /**
     * 获取订单数量和金额
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return EChartsResult
     */
    EChartsResult getOrderCountWithMoney(LocalDate startTime, LocalDate endTime);
}
