package cn.nianxx.thhotel.platform.message.repository;

import cn.nianxx.thhotel.platform.message.common.dto.SourceMessageInboxDraft;
import cn.nianxx.thhotel.platform.message.common.dto.SourceMessageInboxSnapshot;
import cn.nianxx.thhotel.platform.message.common.dto.SourceMessageOriginalAccessAuditDraft;
import cn.nianxx.thhotel.platform.message.common.dto.SourceMessageOriginalContent;
import cn.nianxx.thhotel.platform.message.common.dto.SourceMessagePayloadDuplicateDraft;
import cn.nianxx.thhotel.platform.message.common.request.SourceMessageQueryRequest;
import cn.nianxx.thhotel.platform.message.common.result.SourceMessagePageResult;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * SourceMessage Inbox 持久化端口。应用服务依赖该端口，不直接依赖 MyBatis Mapper 或数据库 Entity。
 */
public interface SourceMessageInboxRepository {

    /**
     * 按内部 SourceMessage ID 查询已保存的 Inbox 快照。
     */
    Optional<SourceMessageInboxSnapshot> findById(Long id);

    /**
     * 按内部 SourceMessage ID 批量查询 Inbox 安全快照，供列表类接口预取摘要。
     */
    List<SourceMessageInboxSnapshot> findByIds(List<Long> ids);

    /**
     * 按外部邮件会话 ID 查询同一会话全部 Inbox 安全快照。
     */
    List<SourceMessageInboxSnapshot> findByExternalConversationId(String hotelId, String externalConversationId);

    /**
     * 按酒店、来源、渠道和外部邮件会话 ID 查询同一会话全部 Inbox 安全快照。
     */
    List<SourceMessageInboxSnapshot> findByExternalConversationId(
            String hotelId,
            String provider,
            String channel,
            String externalConversationId);

    /**
     * 按酒店、来源、渠道、外部邮件 ID 查询幂等记录。
     */
    Optional<SourceMessageInboxSnapshot> findByIdempotencyKey(
            String hotelId,
            String provider,
            String channel,
            String externalMessageId);

    /**
     * 按酒店和外部邮件 ID 查询 Inbox 快照，用于外部回调只携带 AgentBus external_message_id 的场景。
     */
    List<SourceMessageInboxSnapshot> findByExternalMessageId(String hotelId, String externalMessageId);

    /**
     * 按查询条件分页读取 Inbox 快照，分页参数已经由 Service 层归一化。
     */
    SourceMessagePageResult<SourceMessageInboxSnapshot> query(
            SourceMessageQueryRequest request,
            int pageNum,
            int pageSize);

    /**
     * 按来源消息安全摘要关键词查询内部 SourceMessage ID，只匹配普通列表可展示字段。
     */
    List<Long> findIdsBySafeKeyword(String hotelId, String keyword, int limit);

    /**
     * 批量统计外部邮件会话下的 SourceMessage 数量，用于任务和订单前端摘要。
     */
    Map<String, Long> countByExternalConversationIds(String hotelId, List<String> externalConversationIds);

    /**
     * 插入 Inbox 及其 payload/body/media 子记录，返回内部 SourceMessage ID。
     */
    Long insert(SourceMessageInboxDraft draft);

    /**
     * 幂等命中但 payload 变化时，标记差异并保存安全排查摘要。
     */
    void markDuplicatePayloadChanged(Long id, String safeErrorSummary, LocalDateTime updatedAt);

    /**
     * 幂等命中且 payload 变化时，追加保存本次重复投递 payload，便于数据库排查差异。
     */
    void insertDuplicatePayload(SourceMessagePayloadDuplicateDraft draft);

    /**
     * 按内部 SourceMessage ID 读取原文内容和媒体 URL，仅供受控原文读取服务使用。
     */
    Optional<SourceMessageOriginalContent> findOriginalContent(Long id);

    /**
     * 写入 SourceMessage 原文读取审计记录，记录调用方、场景和访问时间。
     */
    void insertOriginalAccessAudit(SourceMessageOriginalAccessAuditDraft draft);
}
