package cn.nianxx.thhotel.workflows.reservation.repository;

import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationAiBatchDraft;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationAiBatchSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationAiQueryOrderSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationAiQueryTaskSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationAiTransitionSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationAiTransitionDraft;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationAuditLogDraft;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationAuditLogSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationOperaOperationAttemptDraft;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationOperaOperationAttemptSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationOperaOperationDraft;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationOperaOperationSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationOrderDraft;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationOrderSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationPageSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationTaskCardDraft;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationTaskCardSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationTaskDraft;
import cn.nianxx.thhotel.workflows.reservation.common.dto.ReservationTaskSnapshot;
import cn.nianxx.thhotel.workflows.reservation.common.request.ReservationTaskWorkbenchQueryRequest;
import cn.nianxx.thhotel.workflows.reservation.common.request.ReservationOrderListQueryRequest;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * Reservation AI 工作流持久化边界。Service 通过该接口访问数据库，不直接依赖 Mapper。
 */
public interface ReservationAiWorkflowRepository {

    /**
     * 按 SourceMessage 查询已接收批次，用于第一版幂等冲突判断。
     */
    Optional<ReservationAiBatchSnapshot> findBatchBySourceMessageId(String hotelId, Long sourceMessageId);

    /**
     * 新增 AI 接收批次，并返回批次 ID。
     */
    Long insertBatch(ReservationAiBatchDraft draft);

    /**
     * 新增 AI 过渡记录，并返回过渡记录 ID。
     */
    Long insertTransition(ReservationAiTransitionDraft draft);

    /**
     * 按业务号查询可承载任务的有效订单。
     */
    Optional<ReservationOrderSnapshot> findActiveOrderByBusinessKey(
            String hotelId,
            String orderKeyType,
            String orderBusinessKey);

    /**
     * 新增订单，并返回订单快照。
     */
    ReservationOrderSnapshot insertOrder(ReservationOrderDraft draft);

    /**
     * 计算同订单下下一条任务执行顺序。
     */
    int nextExecutionOrder(String hotelId, Long orderId);

    /**
     * 新增任务，并返回任务 ID。
     */
    Long insertTask(ReservationTaskDraft draft);

    /**
     * 新增任务卡，并返回任务卡 ID。
     */
    Long insertTaskCard(ReservationTaskCardDraft draft);

    /**
     * 按任务 ID 查询任务快照。
     */
    Optional<ReservationTaskSnapshot> findTaskById(Long taskId);

    /**
     * 按任务 ID 查询任务卡快照。
     */
    Optional<ReservationTaskCardSnapshot> findTaskCardByTaskId(String hotelId, Long taskId);

    /**
     * 按 AI transition ID 查询展示快照，用于任务详情补充 V3 路由和批次上下文。
     */
    Optional<ReservationAiTransitionSnapshot> findTransitionById(String hotelId, Long transitionId);

    /**
     * 查询同一 AI 批次下的 transition 展示快照，用于任务详情展示未建任务的契约错误和未处理意图。
     */
    List<ReservationAiTransitionSnapshot> findTransitionsByBatchId(String hotelId, Long batchId);

    /**
     * 查询同订单中排在当前任务之前且参与队列的任务。
     */
    List<ReservationTaskSnapshot> findQueueTasksBefore(String hotelId, Long orderId, Integer executionOrder);

    /**
     * 按订单 ID 查询订单快照。
     */
    Optional<ReservationOrderSnapshot> findOrderById(String hotelId, Long orderId);

    /**
     * 按 SuperAgent 查询 key 查找订单上下文，包含 ACTIVE、ENDED、LOGIC_DELETED 和 TEMPORARY。
     */
    List<ReservationAiQueryOrderSnapshot> findAiQueryOrdersByBusinessKeys(
            String hotelId,
            String groupCode,
            String confirmationNumber);

    /**
     * 按订单 ID 查询 SuperAgent 查询接口使用的订单详情快照。
     */
    Optional<ReservationAiQueryOrderSnapshot> findAiQueryOrderById(String hotelId, Long orderId);

    /**
     * 按订单 ID 批量查询订单快照，供前端列表补充展示字段。
     */
    List<ReservationAiQueryOrderSnapshot> findAiQueryOrdersByIds(String hotelId, List<Long> orderIds);

    /**
     * 按来源消息 ID 批量查询订单快照，用于 SourceMessage 会话关联业务摘要。
     */
    List<ReservationAiQueryOrderSnapshot> findAiQueryOrdersBySourceMessageIds(
            String hotelId,
            List<Long> sourceMessageIds);

    /**
     * 分页查询前端订单列表，默认包含全部订单状态；keyword 可匹配订单字段或来源消息安全摘要命中的 ID。
     */
    ReservationPageSnapshot<ReservationAiQueryOrderSnapshot> queryFrontendOrders(
            ReservationOrderListQueryRequest request,
            List<Long> keywordSourceMessageIds,
            int pageNum,
            int pageSize);

    /**
     * 分页查询前端任务列表 / 工作台摘要。
     */
    ReservationPageSnapshot<ReservationAiQueryTaskSnapshot> queryFrontendTasks(
            ReservationTaskWorkbenchQueryRequest request,
            List<Long> keywordSourceMessageIds,
            int pageNum,
            int pageSize);

    /**
     * 查询指定订单下全部任务，并带上对应 AI transition 的路由字段。
     */
    List<ReservationAiQueryTaskSnapshot> findAiQueryTasksByOrderIds(String hotelId, List<Long> orderIds);

    /**
     * 按来源消息 ID 批量查询任务快照，用于邮件会话关联任务摘要。
     */
    List<ReservationAiQueryTaskSnapshot> findAiQueryTasksBySourceMessageIds(
            String hotelId,
            List<Long> sourceMessageIds);

    /**
     * 按 AI transition 冗余业务 key 查询任务，用于查到待处理任务但尚无正式订单的场景。
     */
    List<ReservationAiQueryTaskSnapshot> findAiQueryTasksByBusinessKeys(
            String hotelId,
            String groupCode,
            String confirmationNumber);

    /**
     * 将临时订单激活为带真实业务号的 ACTIVE 订单。
     */
    boolean activateTemporaryOrderWithBusinessKey(
            String hotelId,
            Long orderId,
            String orderKeyType,
            String orderBusinessKey,
            String businessKeySource,
            LocalDateTime now);

    /**
     * 更新人工复核任务的类型、卡片和订单归属。
     */
    void updateTaskForManualConversion(
            String hotelId,
            Long taskId,
            Long orderId,
            String aiTaskType,
            String systemTaskType,
            String taskCardType,
            Integer executionOrder,
            LocalDateTime now);

    /**
     * 保存任务卡草稿 payload。
     */
    boolean updateTaskDraftPayload(String hotelId, Long taskId, String draftPayloadJson, LocalDateTime now);

    /**
     * 保存最终确认 payload，并将任务状态从 PENDING_CONFIRM 流转为 READY。
     */
    boolean confirmTaskPayload(
            String hotelId,
            Long taskId,
            String confirmedPayloadJson,
            String confirmedBy,
            LocalDateTime confirmedAt);

    /**
     * 保存同卡人工复核解阻结果、最终确认 payload，并将任务状态从 PENDING_CONFIRM 流转为 READY。
     */
    boolean resolveManualReview(
            String hotelId,
            Long taskId,
            String reviewStatus,
            String reviewResolutionJson,
            String confirmedPayloadJson,
            String confirmedBy,
            LocalDateTime confirmedAt);

    /**
     * 新增 OPERA 模拟操作，并返回操作 ID。
     */
    Long insertOperaOperation(ReservationOperaOperationDraft draft);

    /**
     * 查询任务下全部 OPERA 模拟操作。
     */
    List<ReservationOperaOperationSnapshot> findOperaOperationsByTaskId(String hotelId, Long taskId);

    /**
     * 按操作 ID 查询 OPERA 模拟操作。
     */
    Optional<ReservationOperaOperationSnapshot> findOperaOperationById(String hotelId, Long operationId);

    /**
     * 查询 OPERA 模拟操作的 attempt 历史。
     */
    List<ReservationOperaOperationAttemptSnapshot> findOperaOperationAttempts(String hotelId, Long operationId);

    /**
     * 新增 OPERA 模拟操作 attempt，并返回 attempt ID。
     */
    Long insertOperaOperationAttempt(ReservationOperaOperationAttemptDraft draft);

    /**
     * 更新 OPERA 模拟操作的当前状态和最近 attempt 摘要。
     */
    boolean updateOperaOperationAfterAttempt(
            String hotelId,
            Long operationId,
            String operationStatus,
            Long lastAttemptId,
            String lastErrorMessage,
            LocalDateTime now);

    /**
     * 更新任务状态，用于 OPERA 模拟操作全部成功后完成任务。
     */
    boolean updateTaskStatus(String hotelId, Long taskId, String taskStatus, LocalDateTime now);

    /**
     * 统计订单当前剩余任务数量，用于判断临时订单能否逻辑删除。
     */
    int countTasksByOrder(String hotelId, Long orderId);

    /**
     * 将空临时订单逻辑删除，并清空 ACTIVE 唯一辅助键。
     */
    boolean logicDeleteOrder(String hotelId, Long orderId, String reason, LocalDateTime now);

    /**
     * 新增订单任务审计记录。
     */
    Long insertAuditLog(ReservationAuditLogDraft draft);

    /**
     * 查询任务审计流水。
     */
    List<ReservationAuditLogSnapshot> findAuditLogsByTaskId(String hotelId, Long taskId);
}
