package com.starry.admin.modules.order.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.starry.admin.modules.order.module.dto.*;
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
import com.starry.admin.modules.order.module.vo.*;
import com.starry.admin.modules.weichat.entity.order.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.stereotype.Service;

/**
 * 订单Service接口
 *
 * @author admin
 * @since 2024-03-20
 */
@Service
public interface IPlayOrderInfoService extends IService<PlayOrderInfoEntity> {

    /**
     * 查询当前租户店员总数
     *
     * @param tenantId 租户ID
     * @return 店员总数
     */
    List<PlayOrderInfoEntity> getTotalOrderInfo(String tenantId);

    /**
     * 新增充值单
     *
     * @param orderNo     订单编号
     * @param orderMoney  订单金额
     * @param finalAmount 订单最终金额（支付金额）
     * @param purchaserBy 下单人ID
     */
    void createRechargeOrder(String orderNo, BigDecimal orderMoney, BigDecimal finalAmount, String purchaserBy);

    /**
     * 新增订单信息 - 重构版本使用Builder模式
     *
     * @param request 订单创建请求对象
     * @author admin
     * @since 2024/6/3 10:53
     **/
    /**
     * 据店员等级和订单金额，获取店员预计收入
     *
     * @param clerkId     店员ID
     * @param croupIds    优惠券ID列表
     * @param placeType   下单类型（-1:其他类型;0:指定单;1:随机单;2:打赏单）
     * @param firstOrder  是否是首单【0：不是，1：是】
     * @param orderAmount 订单金额
     * @return com.starry.admin.modules.order.module.vo.ClerkEstimatedRevenueVo
     * @author admin
     * @since 2024/7/18 16:39
     **/
    ClerkEstimatedRevenueVo getClerkEstimatedRevenue(String clerkId, List<String> croupIds, String placeType,
                                                     String firstOrder, BigDecimal orderAmount);

    /**
     * 根据店员等级和订单金额，获取店员预计收入
     *
     * @param clerkId     店员ID
     * @param placeType   下单类型（-1:其他类型;0:指定单;1:随机单;2:打赏单）
     * @param firstOrder  是否是首单【0：不是，1：是】
     * @param orderAmount 订单金额
     * @return math.BigDecimal 店员预计收入
     * @author admin
     * @since 2024/6/3 11:12
     **/
    BigDecimal getEstimatedRevenue(String clerkId, String placeType, String firstOrder, BigDecimal orderAmount);

    /**
     * 根据店员等级，获取店员提成比例
     *
     * @param clerkId    店员ID
     * @param placeType  下单类型（-1:其他类型;0:指定单;1:随机单;2:打赏单）
     * @param firstOrder 是否是首单【0：不是，1：是】
     * @return math.BigDecimal 店员预计收入
     * @author admin
     * @since 2024/6/3 11:12
     **/
    Integer getEstimatedRevenueRatio(String clerkId, String placeType, String firstOrder);

    /**
     * 根据订单结算状态查询订单
     *
     * @param clerkId              店员ID
     * @param orderSettlementState 订单结算状态(0:未结算;1:已结算)
     * @return List<PlayOrderInfoEntity>
     */
    List<PlayOrderInfoEntity> queryBySettlementOrder(String clerkId, String orderSettlementState);

    /**
     * 查询指定店员在指定时间前完成，并且未结算工资的订单
     *
     * @param clerkId 店员ID
     * @param endTime 结束时间
     * @return List<PlayOrderInfoEntity>
     */
    List<PlayOrderInfoEntity> listByEndTime(String clerkId, LocalDateTime endTime);

    /**
     * 查询指定店员在一定时间内的订单
     *
     * @param clerkId     店员ID
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @param orderStatus 店员状态列表
     * @return List<PlayOrderInfoEntity>
     */
    List<PlayOrderInfoEntity> listByTime(String clerkId, String startTime, String endTime, List<String> orderStatus);

    /**
     * 分页查询打赏订单
     *
     * @param vo 打赏订单查询对象
     * @return 打赏订单
     */
    IPage<PlayOrderRewardReturnVo> selectRewardOrderInfoByPage(PlayOrderRewardQueryVo vo);

    /**
     * 根据订单ID查询订单信息
     *
     * @param orderId 订单ID
     * @return 订单信息
     */
    PlayOrderDetailsReturnVo selectById(String orderId);

    /**
     * 查询订单
     *
     * @param id 订单主键
     * @return 订单
     */
    PlayOrderInfoEntity selectOrderInfoById(String id);

    /**
     * 查询订单列表
     *
     * @param orderInfoEntity 订单
     * @return 订单集合
     */
    IPage<PlayOrderInfoReturnVo> selectOrderInfoPage(PlayOrderInfoQueryVo orderInfoEntity);

    /**
     * 店员查询本人订单详情
     *
     * @param clerkId 店员ID
     * @param id      订单ID
     * @return 订单详情
     */

    PlayClerkOrderDetailsReturnVo clerkSelectOrderDetails(String clerkId, String id);

    /**
     * 店员分页查询订单本人列表
     *
     * @param vo 订单列表查询对象
     * @return 订单集合
     */
    IPage<PlayClerkOrderListReturnVo> clerkSelectOrderInfoByPage(PlayClerkOrderInfoQueryVo vo);

    /**
     * 店员查询自己一段时间内的订单
     *
     * @param clerkId   店员ID
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 订单列表
     */
    List<PlayOrderInfoEntity> clerkSelectOrderInfoList(String clerkId, String startTime, String endTime);

    /**
     * 顾客查询订单详情
     *
     * @param customId 顾客ID
     * @param orderId  订单ID
     * @return 订单详情
     */
    PlayCustomOrderDetailsReturnVo customSelectOrderDetails(String customId, String orderId);

    /**
     * 顾客分页查询订单列表
     *
     * @param vo 订单列表查询对象
     * @return 订单集合
     */
    IPage<PlayCustomOrderListReturnVo> customSelectOrderInfoByPage(PlayCustomOrderInfoQueryVo vo);

    /**
     * 顾客查询本人订单列表
     *
     * @param customId 顾客ID
     * @return 订单集合
     */
    List<PlayOrderInfoEntity> customSelectOrderInfoByList(String customId);

    void revokeCompletedOrder(OrderRevocationContext context);

    /**
     * 修改订单状态为接单 只有管理员或者店员本人才能操作
     *
     * @param operatorByType 操作人类型（0:顾客;1:店员;2:管理员）
     * @param operatorBy     操作人ID
     * @param acceptBy       接单人ID
     * @param orderId        订单Id
     **/
    void updateStateTo1(String operatorByType, String operatorBy, String acceptBy, String orderId);

    /**
     * 修改订单状态为开始订单或者完成订单 只有管理员或者店员本人才能操作
     *
     * @param operatorByType 操作人类型（0:顾客;1:店员;2:管理员）
     * @param operatorBy     操作人ID
     * @param orderState     订单状态
     * @param orderId        订单Id
     **/
    void updateStateTo23(String operatorByType, String operatorBy, String orderState, String orderId);

    /**
     * 管理端完成订单（运营/组长）
     *
     * @param operatorByType 操作人类型
     * @param operatorBy     操作人标识
     * @param orderId        订单ID
     * @param remark         操作备注
     */
    void completeOrderByManagement(String operatorByType, String operatorBy, String orderId, String remark);

    /**
     * 修改订单状态为取消订单 管理员、店员、顾客均可操作
     *
     * @param operatorByType 操作人类型（0:顾客;1:店员;2:管理员）
     * @param operatorBy     操作人ID
     * @param orderId        订单Id
     * @param refundReason   订单取消原因
     * @param images         证据图片列表
     **/
    void updateStateTo4(String operatorByType, String operatorBy, String orderId, String refundReason,
                        List<String> images);

    /**
     * 已接单/服务中的订单强制取消
     *
     * @param operatorByType 操作人类型（1:店员;2:管理员）
     * @param operatorBy     操作人ID
     * @param orderId        订单ID
     * @param refundAmount   退款金额（为空则退回实际支付金额）
     * @param refundReason   取消原因
     * @param images         退款凭证图片
     */
    void forceCancelOngoingOrder(String operatorByType, String operatorBy, String orderId, BigDecimal refundAmount,
                                 String refundReason, List<String> images);

    /**
     * 修改订单
     *
     * @param orderInfoEntity 订单
     * @return 结果
     */
    boolean update(PlayOrderInfoEntity orderInfoEntity);

    /**
     * 批量删除订单
     *
     * @param ids 需要删除的订单主键集合
     * @return 结果
     */
    int deleteOrderInfoByIds(String[] ids);

    /**
     * 根据订单编号查询订单信息
     *
     * @param orderNo 订单编号
     * @return 订单信息
     */
    PlayOrderInfoEntity queryByOrderNo(String orderNo);

    /**
     * 删除订单信息
     *
     * @param id 订单主键
     * @return 结果
     */
    int deleteOrderInfoById(String id);

    /**
     * 获得订单编号 订单编号组成规则为 YYYYMMHH+4位随机数字+当日的订单顺序
     *
     * @return 订单编号
     */
    String getOrderNo();

    /**
     * 查询未接单的订单
     *
     * @param vo      查询对象
     * @param clerkId 店员ID
     * @return 订单列表
     */
    IPage<PlayOrderInfoEntity> selectRandomOrderByPage(PlayOrderInfoRandomQueryVo vo, String clerkId);

    /**
     * 分页获取打赏动态
     *
     * @param vo 查询对象
     * @return 打赏动态列表
     */
    IPage<PlayRewardInfoReturnVo> selectRewardByPage(PlayRewardOrderQueryVo vo);

    Boolean checkFirstOrderFlag(String customId, String clerkId);

}
