/**
 * IChatRepository 接口
 *
 * 聚合聊天远程操作、身份隔离的本地历史，以及媒体缓存能力。
 */

import type {
  ChatHistoryResponse,
  ChatPreviewsResponse,
  ChatImageData,
  ChatLockDetailData,
  ChatLockType,
  ChatMediaKind,
  ChatMessage,
  ChatSendResponse,
  OpeningMessageResponse,
  UnlockHistoryResponse,
  UnlockPrivateResponse,
} from "@/data/schemas/chat";
import type { LocalChatMediaRow } from "@/data/storage/chat";
import type { Result } from "@/utils/result";

export interface ChatMediaLookupInput {
  characterId: string;
  messageId: string;
  kind: ChatMediaKind;
}

export interface CacheRemoteChatMediaInput extends ChatMediaLookupInput {
  remoteUrl: string;
}

export interface UnlockedPrivateMessageLocalPatch {
  lockDetail?: ChatLockDetailData;
  audioUrl?: string | null;
  image?: ChatImageData;
  content?: string;
}

export interface UnlockPrivateMessageInput {
  characterId: string;
  messageId?: string;
  lockType?: ChatLockType;
  clientLockId?: string;
}

export interface ChatRequestOptions {
  signal?: AbortSignal;
}

export interface ChatSendOptions extends ChatRequestOptions {
  /** 同一次逻辑发送在重试或 HTTP/WS 切换时必须复用。 */
  clientMessageId?: string;
  imageId?: string;
  imageThumbUrl?: string;
  imageMediumUrl?: string;
  imageOriginalUrl?: string;
  imageWidth?: number;
  imageHeight?: number;
  useWebSocket?: boolean;
}

export interface IChatRepository {
  /** 发送一条消息。 */
  sendMessage(
    characterId: string,
    message: string,
    options?: ChatSendOptions,
  ): Promise<Result<ChatSendResponse>>;

  /** 幂等保存角色首次开场白。 */
  saveOpeningMessage(
    characterId: string,
    openingMessage: string,
    options?: ChatRequestOptions,
  ): Promise<Result<OpeningMessageResponse>>;

  /** 获取聊天历史，分页参数默认 limit=50, offset=0。 */
  getHistory(
    characterId: string,
    limit?: number,
    offset?: number,
    options?: ChatRequestOptions,
  ): Promise<Result<ChatHistoryResponse>>;

  /** 批量获取所有可聊天角色的最新消息。 */
  getPreviews(
    options?: ChatRequestOptions,
  ): Promise<Result<ChatPreviewsResponse>>;

  /** 解锁单条历史付费 / 私密消息。 */
  unlockPrivateMessage(
    input: UnlockPrivateMessageInput,
    options?: ChatRequestOptions,
  ): Promise<Result<UnlockPrivateResponse>>;

  /** 一键解锁历史锁定消息。 */
  unlockHistory(
    characterId: string,
    options?: ChatRequestOptions,
  ): Promise<Result<UnlockHistoryResponse>>;

  /** 把本地缓存中的单条锁定消息标记为已解锁。 */
  markPrivateMessageUnlockedInLocal(
    messageId: string,
    patch?: UnlockedPrivateMessageLocalPatch,
    cacheIdentity?: string,
  ): Promise<Result<void>>;

  /** 把一条消息写入本地存储。 */
  saveMessageToLocal(
    message: ChatMessage,
    cacheIdentity?: string,
  ): Promise<Result<void>>;

  /** 批量覆盖写入：先清空本地存储，再写入新列表。 */
  saveMessagesToLocal(
    messages: readonly ChatMessage[],
    cacheIdentity?: string,
  ): Promise<Result<void>>;

  /** 读取所有本地消息，按 dbId 升序。 */
  getLocalMessages(
    cacheIdentity?: string,
  ): Promise<Result<readonly ChatMessage[]>>;

  /** 清空本地消息。 */
  clearLocalMessages(cacheIdentity?: string): Promise<Result<void>>;

  /** 获取本地消息数量。 */
  getLocalMessageCount(cacheIdentity?: string): Promise<Result<number>>;

  /** 获取本地缓存的图片 / 音频。 */
  getCachedMedia(
    input: ChatMediaLookupInput,
  ): Promise<Result<LocalChatMediaRow | null>>;

  /** 下载并缓存远程图片 / 音频。 */
  cacheRemoteMedia(
    input: CacheRemoteChatMediaInput,
    cacheIdentity?: string,
  ): Promise<Result<LocalChatMediaRow>>;

  /** 后台预缓存历史消息中的图片 / 音频。失败不影响聊天主流程。 */
  prefetchMediaForMessages(
    messages: readonly ChatMessage[],
    characterId: string,
    cacheIdentity?: string,
  ): Promise<Result<void>>;

  /** 后台预缓存发送响应中的图片 / 音频。失败不影响聊天主流程。 */
  prefetchMediaForSendResponse(
    response: ChatSendResponse,
    characterId: string,
    cacheIdentity?: string,
  ): Promise<Result<void>>;
}
