package cn.iocoder.yudao.module.order.service.orderException;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.service.IService;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderException.OrderExceptionDO;
import cn.iocoder.yudao.module.order.enums.OrderExceptionEnum;
import cn.iocoder.yudao.module.order.vo.order.StatisticsOrderVO;
import cn.iocoder.yudao.module.order.vo.orderException.*;
import cn.iocoder.yudao.module.order.vo.orderException.additional.ChannelPackagingOverWeightAdditionalBo;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;

/**
 * 订单异常 Service 接口
 *
 * @author 系统管理员
 */
public interface OrderExceptionService extends IService<OrderExceptionDO> {

    /**
     * 创建订单异常
     *
     * @param createReqVO 创建信息
     * @return 编号
     */
    Long createOrderException(@Valid OrderExceptionCreateReqVO createReqVO);

    /**
     * 更新订单异常
     *
     * @param updateReqVO 更新信息
     */
    void updateOrderException(@Valid OrderExceptionUpdateReqVO updateReqVO);

    /**
     * 删除订单异常
     *
     * @param id 编号
     */
    void deleteOrderException(Long id);

    /**
     * 取消订单而删除订单异常
     *
     * @param id 编号
     */
    void cancelOrderException(Long id);

    /**
     * 获得订单异常
     *
     * @param id 编号
     * @return 订单异常
     */
    OrderExceptionDO getOrderException(Long id);

    /**
     * 获得订单异常列表
     *
     * @param ids 编号
     * @return 订单异常列表
     */
    List<OrderExceptionDO> getOrderExceptionList(Collection<Long> ids);

    /**
     * 获得订单异常列表
     *
     * @return 订单异常列表
     */
    List<OrderExceptionExcelVO> getOrderExceptionExcelList(OrderExceptionQueryVO query);

    /*    *//**
     * 获得订单异常分页
     *
     * @param page  分页查询
     * @param query 查询
     * @return 订单异常分页
     *//*
    PageResult<OrderExceptionDO> getOrderExceptionPage(OrderExceptionQueryVO query, PageVO page);*/

    /**
     * 获得订单异常分页
     *
     * @param page  分页查询
     * @param reqVo 查询
     * @return 订单异常分页
     */
    PageResult<OrderBackVO> selectOrderExceptionPage(OrderExceptionQueryVO reqVo, PageVO page);


    /**
     * 获取该订单下的所有异常列表
     *
     * @param orderId 订单ID
     * @return 订单异常列表
     */
    List<OrderExceptionBackVO> getOrderExceptionListByOrderId(Long orderId);

    /**
     * 根据订单id、订单项id、异常key获取待处理异常
     *
     * @param orderId      订单id
     * @param orderItemId  订单项id
     * @param exceptionKey 异常key
     * @return 待处理的异常
     */
    List<OrderExceptionDO> getPendingOrderExceptionByOrderIdAndOrderItemIdAndExceptionKey(Long orderId, Long orderItemId, String exceptionKey);

    List<OrderExceptionDO> getPendingOrderExceptionByOrderIdAndOrderItemIdAndProdIdAndExceptionKey(Long orderId, Long orderItemId, Long prodId, String exceptionKey);

    List<OrderExceptionDO> getPendingOrderExceptionByOrderIdAndOrderItemIdAndProdIdAndExceptionKeyAndState(Long orderId, Long orderItemId, Long prodId, String exceptionKey, Integer state);

    /**
     * 根据订单id、订单项id、异常key获取待处理异常
     *
     * @param orderId       订单id
     * @param orderItemId   订单项id
     * @param exceptionKeys 多个异常key
     * @return 待处理的异常
     */
    List<OrderExceptionDO> getPendingOrderExceptionByOrderIdAndOrderItemIdAndExceptionKeys(Long orderId, Long orderItemId, Collection<String> exceptionKeys);

    List<OrderExceptionDO> getPendingOrderExceptionByOrderIdAndOrderItemIdAndProdIdAndExceptionKeys(Long orderId, Long orderItemId, Long prodId, Collection<String> exceptionKeys);

    List<OrderExceptionDO> getPendingOrderExceptionByOrderIdAndOrderItemIdAndProdIdAndExceptionKeysAndState(Long orderId, Long orderItemId, Long prodId, Collection<String> exceptionKeys, Integer state);


    Long getUnprocessGoodsAddExceptionCounts(Long orderId, Long prodId);


    /**
     * 根据订单id、客户id、获取待处理的未分配客户经理异常
     *
     * @param orderId    订单id
     * @param customerId 客户ID
     * @return 待处理的异常
     */
    List<OrderExceptionDO> getOrderExceptionByOrderIdAndCustomerId(Long orderId, Long customerId);


    /**
     * 根据客户id获取待处理的未分配客户经理异常
     *
     * @param customerId 客户ID
     * @return 待处理的异常
     */
    List<OrderExceptionDO> getOrderExceptionByCustomerId(Long customerId);

    /**
     * 根据订单id、订单项id、异常key获取异常
     *
     * @param orderId      订单id
     * @param orderItemId  订单项id
     * @param exceptionKey 异常key
     * @return 异常列表
     */
    List<OrderExceptionDO> getOrderExceptionByOrderIdAndOrderItemIdAndExceptionKey(Long orderId, Long orderItemId, String exceptionKey);


    /**
     * 根据订单项id获取异常
     *
     * @param orderItemId 订单项id
     * @return 异常列表
     */
    List<OrderExceptionDO> getOrderExceptionByOrderItemId(Long orderItemId);

    /**
     * 异常处理
     */
    void handlerExceptionByExceptionId(OrderExceptionResultHandlerVo vo);


    /**
     * 预付审核回调
     *
     * @param businessId 表单业务ID
     * @param result     1 处理中  2 通过 3 不通过 4 已取消
     */
    void updateApplyCallback(String businessId, Integer result);

    /**
     * 继续不可出渠道异常审核回调
     *
     * @param businessId 表单业务ID
     * @param result     1 处理中  2 通过 3 不通过 4 已取消
     */
    void continueChannelCallback(String businessId, Integer result);

    /**
     * 商品重量超限异常回调
     *
     * @param businessId 表单业务ID
     * @param result     1 处理中  2 通过 3 不通过 4 已取消
     */
    void weightExceptionCallback(String businessId, Integer result);

    /**
     * 根据异常ID取消正在进行的流程
     */
    void cancelBpmByExceptionId(Long exceptionId, String remark);

    /**
     * 接收客户之后没有客户经理异常回调
     *
     * @param customerId
     */
    void assignedCustomerCallback(Long customerId, Long customerService);

    /**
     * 商品确认之后回调
     *
     * @param productId
     */
    void assignedProductCallback(Long productId);

    /**
     * 清关费未报价异常回调
     *
     * @param productId
     */
    void customsFeeCallback(Long productId);

    /*PageResult<OrderBackPageVO> orderExceptionPage(OrderQueryVO query, PageVO page);*/

    /**
     * 异常订单列表统计
     *
     * @param query
     * @return
     */
    StatisticsOrderVO statisticsOrder(OrderExceptionQueryVO query);

    /**
     * 得到根据跟进服务得到所有对应客户经理
     *
     * @param salesmanId
     * @return
     */
    List<String> getCustomerServiceListById(Long salesmanId);


    /**
     * 自动处理异常
     *
     * @param orderId
     * @param orderItemId
     * @param orderExceptionEnum          异常类型
     * @param remark                      备注
     * @param orderExceptionHandlerResult 自动处理异常选项  见OrderExceptionResult下的枚举类
     */
    void autoProcessException(Long orderId, Long orderItemId, OrderExceptionEnum orderExceptionEnum, String remark, String orderExceptionHandlerResult);

    void autoProcessException(Long orderId, Long orderItemId, OrderExceptionEnum orderExceptionEnum, String remark, String orderExceptionHandlerResult, boolean isSystemAutoProcess);

    /**
     * 订单选择渠道之后-删除渠道异常
     *
     * @param orderId
     */
    void orderChannelExceptionCallback(Long orderId);

    /**
     * 当入仓时变更特性需要删除不可出渠道异常
     *
     * @param orderId
     */
    void handlerRemoveNotShippingChannelExceptionByOrderId(Long orderId);


    /**
     * 当入仓时变更特性需要删除不可出渠道异常
     *
     * @param id 异常id
     */
    void handlerRemoveNotShippingChannelExceptionById(Long id);


    void handlerRemoveFeeExceptionById(Long id);


    /**
     * 自动处理商品超重异常
     *
     * @param prodId             商品id
     * @param airWeightLimitNew  新重量
     * @param excludeExceptionId 需要排除的异常id, 可为null
     */
    void autoProcessGoodsWeightException(Long prodId, BigDecimal airWeightLimitNew, Long excludeExceptionId);


    void autoProcessGoodsLineWeightException(Long lineId, Long channelId, Long prodId, BigDecimal airWeightLimitNew, Long excludeExceptionId);

    /**
     * 自动处理渠道包装重量超限异常
     *
     * @param additionalBoOld    异常自带json
     * @param excludeExceptionId 需要排队的异常id，可为null
     */
    void autoProcessLineChannelPackageWeightException(ChannelPackagingOverWeightAdditionalBo additionalBoOld, Long excludeExceptionId);
}
