package com.gxwebsoft.glt.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.glt.entity.GltTicketOrder;
import com.gxwebsoft.glt.param.GltTicketOrderParam;

import java.util.List;
import java.time.LocalDateTime;

/**
 * 送水订单Service
 *
 * @author 科技小王子
 * @since 2026-02-05 18:50:20
 */
public interface GltTicketOrderService extends IService<GltTicketOrder> {

    int DELIVERY_STATUS_WAITING = 10;
    int DELIVERY_STATUS_DELIVERING = 20;
    int DELIVERY_STATUS_WAIT_CONFIRM = 30;
    int DELIVERY_STATUS_FINISHED = 40;

    int RECEIVE_CONFIRM_TYPE_MANUAL = 10;
    int RECEIVE_CONFIRM_TYPE_PHOTO = 20;
    int RECEIVE_CONFIRM_TYPE_TIMEOUT = 30;

    /**
     * 分页关联查询
     *
     * @param param 查询参数
     * @return PageResult<GltTicketOrder>
     */
    PageResult<GltTicketOrder> pageRel(GltTicketOrderParam param);

    /**
     * 关联查询全部
     *
     * @param param 查询参数
     * @return List<GltTicketOrder>
     */
    List<GltTicketOrder> listRel(GltTicketOrderParam param);

    /**
     * 根据id查询
     *
     * @param id 
     * @return GltTicketOrder
     */
    GltTicketOrder getByIdRel(Integer id);

    /**
     * 下单（事务）：校验水票 -> 扣减水票 -> 写核销记录 -> 创建送水订单。
     *
     * @param gltTicketOrder 订单请求体
     * @param userId         当前登录用户ID
     * @param tenantId       当前租户ID
     * @return 创建后的订单（含id）
     */
    GltTicketOrder createWithWriteOff(GltTicketOrder gltTicketOrder, Integer userId, Integer tenantId);

    /**
     * 配送员接单（原子）：仅当 riderId 为空(或0)且 deliveryStatus=10 时写入 riderId。
     */
    void accept(Integer id, Integer riderId, Integer tenantId);

    /**
     * 指派/接单成功后，同步关联商城订单发货状态为“已发货”(deliveryStatus=20)。
     *
     * <p>用于后台指派配送员（不走接单接口）等场景的状态兜底同步。</p>
     */
    void markShopOrderShippedAfterRiderAssigned(Integer ticketOrderId, Integer tenantId, Integer riderId);

    /**
     * 送水订单完成后，同步关联商城订单为“已完成”(orderStatus=1)。
     *
     * <p>用于后台直接改 deliveryStatus=40 等不经过 confirmReceive/autoConfirmTimeout 的兜底同步。</p>
     */
    void markShopOrderCompletedAfterTicketFinished(Integer ticketOrderId, Integer tenantId);

    /**
     * 配送员开始配送：10 -> 20，并写 sendStartTime。
     */
    void start(Integer id, Integer riderId, Integer tenantId);

    /**
     * 配送员确认送达：20 -> 30，并写 sendEndTime / sendEndImg。
     */
    void delivered(Integer id, Integer riderId, Integer tenantId, String sendEndImg);

    /**
     * 用户确认收货：30 -> 40，并写 receiveConfirmTime / receiveConfirmType=10。
     */
    void confirmReceive(Integer id, Integer userId, Integer tenantId);

    /**
     * 超时自动确认收货：
     * - 扫描已送达待确认(30)且送达时间(sendEndTime)超过指定小时数的订单
     * - 自动置为已完成(40)，并写 receiveConfirmTime / receiveConfirmType=30
     *
     * @param tenantId   租户ID
     * @param now        当前时间
     * @param timeoutHours 超时小时数（如24）
     * @param batchSize  每次处理条数上限
     * @return 本次自动确认条数
     */
    int autoConfirmTimeout(Integer tenantId, LocalDateTime now, int timeoutHours, int batchSize);

}
