package com.ylx.massage.service;

import com.ylx.massage.domain.TOrder;

/**
 * 订单校验服务接口
 * <p>
 * 提供订单创建和接单时的校验功能，确保技师服务时间的互斥性。
 * 采用订单状态锁机制，防止技师在同一时间段内被分配多个订单。
 * </p>
 *
 * @author ylx
 * @version 1.0
 * @since 2024
 */
public interface OrderValidationService {

    /**
     * 检查技师是否可以接单
     * <p>
     * 基于订单状态锁机制，检查技师是否有进行中的订单。
     * 进行中的订单状态包括：待接单(0)、已接单(1)、已出发(6)、已到达(2)、服务中(3)
     * </p>
     * <b>校验规则：</b>
     * <ul>
     *   <li>如果技师有进行中的订单，不允许接单</li>
     *   <li>支持跨项目校验（按摩、陪玩等项目类型）</li>
     *   <li>升级订单除外（parentNo不为空的订单）</li>
     * </ul>
     *
     * @param technicianId 技师ID
     * @param newOrder 新订单信息
     * @return true-可以接单
     * @throws ServiceException 当技师不能接单时抛出异常，包含详细原因
     */
    boolean canAcceptOrder(String technicianId, TOrder newOrder);

    /**
     * 检查技师是否可以被手动分配订单
     * <p>
     * 用于后台管理员手动分配订单的场景。
     * 规则与接单相同：技师不能有进行中的订单。
     * </p>
     *
     * @param technicianId 技师ID
     * @return true-可以分配
     * @throws ServiceException 当技师不能被分配订单时抛出异常
     */
    boolean canManualAssign(String technicianId);

    /**
     * 获取技师的进行中订单数量
     * <p>
     * 统计技师当前进行中的订单数量。
     * 用于前端展示技师状态和负载情况。
     * </p>
     *
     * @param technicianId 技师ID
     * @return 进行中的订单数量
     */
    long getInProgressOrderCount(String technicianId);

    /**
     * 检查订单是否可以支付
     * <p>
     * 防止在订单状态发生变化后仍然可以支付。
     * </p>
     *
     * @param orderNo 订单号
     * @return true-可以支付
     * @throws ServiceException 当订单不可支付时抛出异常
     */
    boolean canPayOrder(String orderNo);
}
