package com.spot.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.spot.dto.mq.OrderMessage;
import com.spot.entity.ExOrder;
import com.spot.req.AdminOrderQueryReq;
import com.spot.req.CreateOrderReq;
import com.spot.req.OrderListReq;
import java.util.List;

/**
 * 订单服务接口
 *
 * @author jean
 * @date 2026-05-06
 */
public interface OrderService extends IService<ExOrder> {

    /**
     * 创建订单（事务内：生成订单、冻结余额、生成流水）
     *
     * @param req    创建订单请求
     * @param userId 用户ID
     * @return OrderMessage，用于事务外发送 MQ
     */
    OrderMessage createOrder(CreateOrderReq req, Long userId);

    /**
     * 撤单（事务内：更新订单状态为撤单中）
     *
     * @param orderId 订单ID
     * @param userId  用户ID
     * @return OrderMessage，用于事务外发送 MQ
     */
    OrderMessage cancelOrder(Long orderId, Long userId);

    /**
     * 一键撤销用户所有当前委托（INIT/NEW/PART_FILLED）
     * 事务内仅更新为 PENDING_CANCEL，事务外再发送 MQ
     *
     * @param userId 用户ID
     * @return 待发送 MQ 的订单消息列表
     */
    List<OrderMessage> cancelAllCurrentOrders(Long userId);

    /**
     * 发送 MQ 消息（事务外调用，发送失败不影响主流程）
     *
     * @param orderMessage 订单消息
     */
    void sendMqMessage(OrderMessage orderMessage);

    /**
     * 查询当前委托（状态为：初始化、新建、部分成交）
     *
     * @param req 查询请求
     * @param uid 用户ID
     * @return 分页结果
     */
    Page<ExOrder> currentOrders(OrderListReq req, Long uid);

    /**
     * 查询历史委托（状态为：已成交、已撤单、撤单中）
     *
     * @param req 查询请求
     * @param uid 用户ID
     * @return 分页结果
     */
    Page<ExOrder> historyOrders(OrderListReq req, Long uid);

    /**
     * 查询成交记录（成交量大于0的订单）
     *
     * @param req 查询请求
     * @param uid 用户ID
     * @return 分页结果
     */
    Page<ExOrder> tradeRecords(OrderListReq req, Long uid);

    /**
     * 处理超时初始化订单撤单
     * 将订单状态更新为 PENDING_CANCEL，并发送撤单消息到 Kafka
     *
     * @param order 超时订单
     * @return true-处理成功，false-订单状态已变更跳过
     */
    boolean cancelTimeoutInitOrder(ExOrder order);

    /**
     * 发送撤单 MQ 消息（供定时任务调用，事务外执行）
     *
     * @param orderMessage 撤单消息
     */
    void sendCancelMqMessage(OrderMessage orderMessage);

    /**
     * 管理后台撤销指定交易对所有活跃订单（INIT/NEW/PART_FILLED）
     *
     * @param symbol 交易对符号
     * @return 已提交撤单数量
     */
    int cancelAllOrdersBySymbol(String symbol);

    /**
     * 管理后台分页查询所有订单
     */
    Page<ExOrder> adminPageQuery(AdminOrderQueryReq req);
}
