package com.tmerclub.cloud.api.order.feign;

import com.tmerclub.cloud.api.multishop.bo.OrderChangeShopWalletAmountBO;
import com.tmerclub.cloud.api.order.bo.UserScoreLogOrderBO;
import com.tmerclub.cloud.api.order.dto.CustomerRetainedDTO;
import com.tmerclub.cloud.api.order.dto.FlowOrderItemDTO;
import com.tmerclub.cloud.api.order.dto.FormExcelDTO;
import com.tmerclub.cloud.api.order.dto.QueryOrderDTO;
import com.tmerclub.cloud.api.order.vo.*;
import com.tmerclub.cloud.api.user.bo.UserOrderStatisticBO;
import com.tmerclub.cloud.api.user.bo.UserOrderStatisticListBO;
import com.tmerclub.cloud.api.user.dto.MemberReqDTO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.api.order.dto.SaveOrderToMallDTO;
import com.tmerclub.cloud.common.order.bo.EsOrderBO;
import com.tmerclub.cloud.common.order.bo.OrderIdWithRefundIdBO;
import com.tmerclub.cloud.common.order.bo.OrderStatusBO;
import com.tmerclub.cloud.common.order.dto.OrderDTO;
import com.tmerclub.cloud.common.order.dto.OrderSearchDTO;
import com.tmerclub.cloud.common.order.dto.OrderVirtualInfoDTO;
import com.tmerclub.cloud.common.order.vo.*;
import com.tmerclub.cloud.common.response.ServerResponseEntity;

import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * @author tmerclub
 * @date 2020/11/23
 */
public interface OrderFeignClient {


    /**
     * 如果订单没有被取消的话，获取订单金额，否之会获取失败
     *
     * @param orderIds 订单id列表
     * @param userId
     * @return 订单金额
     */
    ServerResponseEntity<OrderAmountVO> getOrdersAmountAndIfNoCancel(List<Long> orderIds, Long userId);

    /**
     * 支付尾款判断，如果订单没有被取消的话且未支付尾款，获取订单金额，否之会获取失败
     *
     * @param orderIds 订单id列表
     * @return 订单金额
     */
    ServerResponseEntity<OrderAmountVO> getOrdersAmountAndCheckOrderStatus(List<Long> orderIds);

    /**
     * 获取订单状态，如果订单状态不存在，则说明订单没有创建
     *
     * @param orderIds 订单id列表
     * @return 订单状态
     */
    ServerResponseEntity<List<OrderStatusBO>> getOrdersStatus(List<Long> orderIds);

    /**
     * 获取订单中的金额信息，不包含退款
     *
     * @param orderIds 订单id列表
     * @return 订单中的金额信息
     */
    ServerResponseEntity<List<OrderSimpleAmountInfoBO>> getOrdersSimpleAmountInfo(List<Long> orderIds);


    /**
     * 获取订单需要保存到es中的数据
     *
     * @param orderId 订单id
     * @return
     */
    ServerResponseEntity<EsOrderBO> getEsOrder(Long orderId);


    /**
     * 提交订单
     *
     * @param mergerOrder 确认订单的订单信息
     * @return 订单号
     */
    void submit(ShopCartOrderMergerVO mergerOrder);

    /**
     * 会员管理部分获取用户相关的订单统计数据
     *
     * @param queryOrderDTO
     * @return 相关用户的订单中的信息
     */
    ServerResponseEntity<List<UserOrderStatisticVO>> countOrderByUserIds(QueryOrderDTO queryOrderDTO);

    /**
     * 获取各种状态的订单数量
     *
     * @param userId 用户id
     * @return
     */
    ServerResponseEntity<OrderCountVO> countOrderByUserId(Long userId);

    /**
     * 付款用户列表
     *
     * @param orderSearchDTO 条件参数
     * @return 用户id列表
     */
    ServerResponseEntity<List<Long>> getOrderUserIdsBySearchDTO(OrderSearchDTO orderSearchDTO);

    /**
     * 获取在一定时间内消费一定次数的会员信息
     *
     * @param isPayed      是否已支付
     * @param deleteStatus 用户订单删除状态，0：没有删除， 1：回收站， 2：永久删除
     * @param startDate    开始时间
     * @param endDate      结束时间
     * @param status       状态
     * @param minNum       最小数量
     * @param maxNum       最大数量
     * @return 会员id
     */
    ServerResponseEntity<List<Long>> listUserIdByPurchaseNum(Integer isPayed,
                                                             Integer deleteStatus,
                                                             Date startDate,
                                                             Date endDate,
                                                             Integer status,
                                                             Long minNum,
                                                             Long maxNum);

    /**
     * 获取在一定时间内消费一定金额的会员信息
     *
     * @param isPayed      是否已支付
     * @param deleteStatus 用户订单删除状态，0：没有删除， 1：回收站， 2：永久删除
     * @param startDate    开始时间
     * @param endDate      结束时间
     * @param status       状态
     * @param minAmount    最小支付金额
     * @param maxAmount    最大支付金额
     * @return 会员id
     */
    ServerResponseEntity<List<Long>> listUserIdByAverageActualTotal(Integer isPayed,
                                                                    Integer deleteStatus,
                                                                    Date startDate,
                                                                    Date endDate,
                                                                    Integer status,
                                                                    Long minAmount,
                                                                    Long maxAmount);

    /**
     * 根据参数获取数据分析中的订单信息
     *
     * @param spuIds    产品id列表
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 商品效果分析数据
     */
    ServerResponseEntity<List<OrderProdEffectRespVO>> getProdEffectByDateAndProdIds(List<Long> spuIds,
                                                                                    Long startTime,
                                                                                    Long endTime);


    /**
     * 获取用户的成交留存率
     *
     * @param customerRetainedDTO 条件查询参数
     * @return 成交留存信息列表
     */
    ServerResponseEntity<List<CustomerRetainVO>> getTradeRetained(CustomerRetainedDTO customerRetainedDTO);

    /**
     * 根据订单id列表， 获取订单流量信息列表
     *
     * @param orderIds 订单id列表
     * @return 订单流量信息列表
     */
    ServerResponseEntity<List<FlowOrderVO>> listFlowOrderByOrderIds(Collection<Long> orderIds);

    /**
     * 会员支付信息
     *
     * @param param 筛选参数
     * @return 会员支付信息
     */
    ServerResponseEntity<UserOrderStatisticBO> getPaidMemberByParam(MemberReqDTO param);

    /**
     * 获取新老会员成交数据
     *
     * @param param 筛选参数
     * @return 新老会员成交数据
     */
    ServerResponseEntity<UserOrderStatisticListBO> getMemberPayData(MemberReqDTO param);

    /**
     * 刷新交易留存缓存
     *
     * @param customerRetainedDTO 条件查询
     * @return
     */
    ServerResponseEntity<Void> removeCacheTradeRetained(CustomerRetainedDTO customerRetainedDTO);

    /**
     * 批量更新订单明细的获得积分
     *
     * @param orderItemVOList 订单明细
     */
    void updateOrderItemBatchById(List<OrderItemVO> orderItemVOList);

    /**
     * 获取es订单数据列表
     *
     * @param orderId 订单id
     * @return 订单信息
     */
    EsOrderBO getEsOrderInfo(Long orderId);

    /**
     * 获取订单详情
     *
     * @param orderId 订单id
     * @return 订单详情
     */
    ServerResponseEntity<SendNotifyBO> getOrderDetailInfo(Long orderId);

    /**
     * 获取正常状态的订单数量
     *
     * @param orderIds 订单ids
     * @return 订单详情
     */
    ServerResponseEntity<Integer> countNormalOrderByOrderIds(List<Long> orderIds);


    /**
     * 根据用户id列表获取积累消费金额和积累消费笔数
     *
     * @param userIds 用户id列表
     * @return
     */
    ServerResponseEntity<List<SumAmountVO>> listSumDataByUserIds(List<Long> userIds);

    /**
     * 获取用户购买过的商品数量
     *
     * @param spuId  商品id
     * @param userId 分销员userId
     * @return
     */
    ServerResponseEntity<Long> hasBuySuccessProd(Long spuId, Long userId);

    /**
     * 统计用户购物数据
     *
     * @param userId 用户id
     * @return 用户购物数据
     */
    ServerResponseEntity<UserShoppingDataVO> calculateUserInShopData(Long userId);

    /**
     * 计算订单项当中含有的分销金额
     *
     * @param orderItems 订单项列表
     * @return 分销金额
     */
    ServerResponseEntity<Long> sumTotalDistributionAmountByOrderItem(List<OrderItemVO> orderItems);

    /**
     * 获取指定的订单项
     *
     * @param orderIds 订单号集合
     * @return 订单项列表
     */
    ServerResponseEntity<List<OrderItemVO>> listOrderItemByOrderIds(List<Long> orderIds);

    /**
     * 获取商品洞察的商品id
     *
     * @param begin
     * @param size
     * @param shopId
     * @param startTime
     * @param endTime
     * @return
     */
    ServerResponseEntity<List<Long>> getInsightSpuIdsByDate(Integer begin,
                                                            Integer size,
                                                            Long shopId,
                                                            Long startTime,
                                                            Long endTime);

    /**
     * 获取积分订单详情
     *
     * @param orderIds 订单id
     * @return 订单详情
     */
    ServerResponseEntity<List<UserScoreLogOrderBO>> getUserScoreLogDetail(List<Long> orderIds);

    /**
     * 订单结算
     *
     * @param orderIds 订单id列表
     * @return
     */
    ServerResponseEntity<Void> settledOrder(List<OrderChangeShopWalletAmountBO> orderIds);

    /**
     * 订单确认收货
     *
     * @param orderIds 订单id列表
     * @return
     */
    ServerResponseEntity<Void> confirmOrder(List<Long> orderIds);

    /**
     * 获取活动订单的支付信息
     *
     * @param orderId 订单id
     * @return
     */
    ServerResponseEntity<OrderActivityVO> getActivityOrderInfo(Long orderId);

    /**
     * 获取用户活动订单的商品购买数量
     *
     * @param activityId   活动id
     * @param activityType 活动类型
     * @param spuId        商品id
     * @param userId       用户id
     * @return
     */
    ServerResponseEntity<Integer> getUserBuyNumByActivityId(Long activityId, Integer activityType, Long spuId, Long userId);

    /**
     * 获取活动销售的商品数量
     *
     * @param orderIds     订单id列表
     * @param activityType
     * @return
     */
    List<OrderActivityVO> getActivitySalesQuantity(List<Long> orderIds, Integer activityType);

    /**
     * 根据订单id获取对应用户
     *
     * @param orderIds
     * @return
     */
    ServerResponseEntity<List<EsOrderVO>> getUserByOrderIdList(List<Long> orderIds);

    /**
     * 统计活动订单的销量
     *
     * @param activityId
     * @param activityType
     * @return
     */
    ServerResponseEntity<Integer> countActivityOrderSale(Long activityId, Integer activityType);


    /**
     * 统计活动sku的销量
     *
     * @param skuId
     * @param activityId
     * @param activityType
     * @return
     */
    ServerResponseEntity<Integer> countActivitySkuSale(Long skuId, Long activityId, Integer activityType);

    /**
     * 查询指定的订单及订单项列表（从mysql中查询订单列表）
     * 由于目前进行了分库分表，所以使用该方法时要注意分表的问题，尽量保证查询的订单都是属于同一个用户的，避免多表查询
     * 如果是多个用户的订单查询，且不涉及下单、结算和退款流程时，不要使用该方法，请使用es进行查询
     *
     * @param orderIds
     * @return
     */
    ServerResponseEntity<List<OrderVO>> listOrderAndOrderItemByOrderIds(List<Long> orderIds);

    /**
     * 查询财务对账信息，使用mongodb，当有店铺名称查询需要时
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param shopName  店铺名称
     * @param shopId
     * @return 财务对账信息
     */
    ServerResponseEntity<AccountOrderDetailVO> getAccountOrderDetail(Date startTime,
                                                                     Date endTime,
                                                                     String shopName,
                                                                     Long shopId);


    /**
     * 查询财务对账信息，使用mongodb，当有店铺名称查询需要时
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param shopName  店铺名称
     * @param pageNum
     * @param pageSize
     * @return 财务对账信息
     */
    ServerResponseEntity<PageShopAccountOrderVO> listShopAccountDetail(Date startTime,
                                                                       Date endTime,
                                                                       String shopName,
                                                                       Integer pageSize,
                                                                       Integer pageNum);


    /**
     * 查询财务对账信息，使用mongodb，当有店铺名称查询需要时
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param shopId    店铺id
     * @param shopName
     * @param pageNum
     * @param pageSize
     * @return 财务对账信息
     */
    ServerResponseEntity<PageShopAccountOrderVO> listOrderPayInfo(Date startTime,
                                                                  Date endTime,
                                                                  Long shopId,
                                                                  String shopName,
                                                                  Integer pageSize,
                                                                  Integer pageNum);

    /**
     * 获取时间范围内的销量排序，放入redis
     *
     * @param key
     * @param shopId              店铺id
     * @param time                时间范围内
     * @param expireTime
     * @param esRenovationSpuSort
     * @param primaryCategoryId
     * @return
     */
    ServerResponseEntity<List<Long>> getSoldNumRankByShopIdAndTime(String key, Long shopId,
                                                                   Integer time, Integer expireTime,
                                                                   Integer esRenovationSpuSort,
                                                                   Long primaryCategoryId);

    /**
     * 获取团购活动信息
     *
     * @param groupActivityId
     * @return
     */
    ServerResponseEntity<GroupInfoVO> getGroupInfoById(Long groupActivityId);


    /**
     * 获取报表导出
     *
     * @param formExcelParamVO
     * @return
     */
    List<FormExcelDTO> listFormExcelByParam(FormExcelParamVO formExcelParamVO);

    /**
     * 付款用户列表
     *
     * @param orderSearchDTO 条件参数
     * @return 用户id列表
     */
    ServerResponseEntity<List<EsOrderVO>> getStationOrderBySeachDTO(OrderSearchDTO orderSearchDTO);

    /**
     * 提货
     *
     * @param orderIds
     * @param stationId
     * @return
     */
    ServerResponseEntity<Boolean> orderStationByOrderId(List<Long> orderIds, Long stationId) throws LuckException;

    /**
     * 获取自提点订单列表
     *
     * @param orderDTO
     * @return
     */
    ServerResponseEntity<List<OrderVO>> listStationOrder(OrderDTO orderDTO);

    /**
     * 核销操作
     *
     * @param orderVirtualInfoDTO
     * @param orderId
     * @param statinoId
     * @return
     */
    ServerResponseEntity<Boolean> orderWriteOffByOrderId(OrderVirtualInfoDTO orderVirtualInfoDTO, Long orderId, Long statinoId);

    /**
     * 删除通联支付的缓存
     */
    void deleteAllinpayCache();

    /**
     * 订单结算
     *
     * @param orderList 订单列表
     * @return
     */
    ServerResponseEntity<Void> settledOrderByAllinpay(List<OrderChangeShopWalletAmountBO> orderList);

    /**
     * 获取待采购订单和支付定金未支付尾款的订单Ids
     *
     * @param paySysType 支付类型
     * @return
     */
    ServerResponseEntity<List<OrderIdWithRefundIdBO>> listWaitPurchaseAndUnPayBalanceOrderIds(Integer paySysType);

    /**
     * 建议订单搜索数据
     *
     * @param orderSearchDTO
     * @return
     */
    ServerResponseEntity<OrderSearchDTO> checkOrderSearchInfo(OrderSearchDTO orderSearchDTO);

    /**
     * 批量获取指定的订单列表（数据必须在同一个表中）
     * 注意： 使用该接口时，请确认订单都是属于同一个用户或者订单在同一表中， 如果涉及多个表的数据，请使用es查询
     *
     * @param orderIds
     * @return
     */

    List<OrderVO> listOrderByOrderIds(List<Long> orderIds);

    /**
     * 获取订单商品流量统计数据
     *
     * @param flowOrderItemDTO 查询参数
     * @return 订单商品流量统计数据
     */
    List<FlowOrderItemVO> listFlowOrderItems(FlowOrderItemDTO flowOrderItemDTO);

    /**
     * 向商城订单写入球杆回收订单
     */
    Long saveOrderToMall(SaveOrderToMallDTO saveOrderToMallDTO);

    void updateOrderMall(Long shopId,Long mallOrderId, Integer orderStatus);
}
