package shop.alien.dining.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import shop.alien.entity.store.StoreOrder;
import shop.alien.entity.store.dto.CreateOrderDTO;
import shop.alien.entity.store.vo.OrderChangeLogBatchVO;
import shop.alien.entity.store.vo.OrderInfoVO;
import shop.alien.entity.store.vo.StoreOrderPageVO;

import java.util.List;

/**
 * 订单服务接口
 *
 * @author system
 * @since 2025-01-XX
 */
public interface StoreOrderService extends IService<StoreOrder> {

    /**
     * 创建订单
     *
     * @param dto 创建订单DTO
     * @return 订单信息
     */
    StoreOrder createOrder(CreateOrderDTO dto);

    /**
     * 支付订单
     *
     * @param orderId 订单ID
     * @param payType 支付方式
     * @return 订单信息
     */
    StoreOrder payOrder(Integer orderId, Integer payType);

    /**
     * 取消订单
     *
     * @param orderId 订单ID
     * @return 是否成功
     */
    boolean cancelOrder(Integer orderId);

    /**
     * 根据订单号查询订单
     *
     * @param orderNo 订单号
     * @return 订单信息
     */
    StoreOrder getOrderByOrderNo(String orderNo);

    /**
     * 根据ID查询订单
     *
     * @param orderId 订单ID
     * @return 订单信息
     */
    StoreOrder getOrderById(Integer orderId);

    /**
     * 分页查询订单列表
     *
     * @param page     分页参数
     * @param storeId  门店ID
     * @param tableId  桌号ID
     * @param orderStatus 订单状态
     * @param keyword  搜索关键词（订单编号或菜品名称，限15字）
     * @return 订单分页列表
     */
    IPage<StoreOrder> getOrderPage(Page<StoreOrder> page, Integer storeId, Integer tableId, Integer orderStatus, String keyword);

    /**
     * 分页查询订单列表（包含菜品信息）
     *
     * @param page     分页参数
     * @param storeId  门店ID
     * @param tableId  桌号ID
     * @param orderStatus 订单状态
     * @param keyword  搜索关键词（订单编号或菜品名称，限15字）
     * @return 订单分页列表（包含菜品信息）
     */
    IPage<StoreOrderPageVO> getOrderPageWithCuisines(Page<StoreOrder> page, Integer storeId, Integer tableId, Integer orderStatus, String keyword);

    /**
     * 完成订单（支付完成后调用）
     *
     * @param orderId 订单ID
     * @return 是否成功
     */
    boolean completeOrder(Integer orderId);

    /**
     * 商家手动完成订单（不校验支付状态）
     *
     * @param orderId 订单ID
     * @return 是否成功
     */
    boolean completeOrderByMerchant(Integer orderId);

    /**
     * 更新订单优惠券
     *
     * @param orderId 订单ID
     * @param couponId 优惠券ID(可为空，表示不使用优惠券)
     * @return 订单信息
     */
    StoreOrder updateOrderCoupon(Integer orderId, Integer couponId);

    /**
     * 管理员重置餐桌（删除购物车数据、未支付/已取消的订单数据，并重置餐桌表）
     * 注意：已支付/已完成的订单会被保留，避免数据丢失
     *
     * @param tableId 餐桌ID
     * @return 是否成功
     */
    boolean resetTable(Integer tableId);

    /**
     * 查询订单信息（包含订单基本信息、菜品清单、价格明细）
     *
     * @param orderId 订单ID
     * @return 订单信息
     */
    OrderInfoVO getOrderInfo(Integer orderId);

    /**
     * 查询订单的所有变更记录（按批次分组）
     *
     * @param orderId 订单ID
     * @return 变更记录批次列表
     */
    List<OrderChangeLogBatchVO> getOrderChangeLogs(Integer orderId);

    /**
     * 查询订单详情（包含订单基本信息和按批次分组的变更记录）
     *
     * @param orderId 订单ID
     * @return 订单详情（包含变更记录）
     */
    shop.alien.entity.store.vo.OrderDetailWithChangeLogVO getOrderDetailWithChangeLog(Integer orderId);

    /**
     * 支付完成后重置餐桌（保留订单数据，只重置餐桌绑定关系）
     *
     * @param tableId 餐桌ID
     */
    void resetTableAfterPayment(Integer tableId);

    /**
     * 查询我的订单（通过标识查询未支付订单或历史订单）
     *
     * @param page 分页参数
     * @param type 订单类型（0或"unpaid":未支付订单, 1或"history":历史订单）
     * @return 订单分页列表
     */
    IPage<StoreOrder> getMyOrders(Page<StoreOrder> page, String type);

    /**
     * 查询我的订单（包含菜品信息）
     *
     * @param page 分页参数
     * @param type 订单类型（0或"unpaid":未支付订单, 1或"history":历史订单）
     * @return 订单分页列表（包含菜品信息）
     */
    IPage<StoreOrderPageVO> getMyOrdersWithCuisines(Page<StoreOrder> page, String type);

    /**
     * 换桌时迁移所有关联数据（订单、订单变更记录、优惠券使用记录等）
     *
     * @param fromTableId 原桌号ID
     * @param toTableId   目标桌号ID
     * @param userId      操作用户ID
     */
    void migrateTableData(Integer fromTableId, Integer toTableId, Integer userId);

    /**
     * 换桌（包含所有业务逻辑：迁移购物车、订单、优惠券等，记录日志，推送消息）
     *
     * @param fromTableId  原桌号ID
     * @param toTableId    目标桌号ID
     * @param changeReason 换桌原因
     * @param userId       操作用户ID
     * @return 迁移后的购物车信息
     */
    shop.alien.entity.store.dto.CartDTO changeTable(Integer fromTableId, Integer toTableId, String changeReason, Integer userId);
}
