/**
 * 会话列表数据源抽象：游标、常规页码、SQLite 等实现同一契约，MessageManager 只依赖接口。
 */

import { ConversationResponse } from '../types/dto';
import { messageService } from '../services/messageService';
import { getConversationListCache } from '../services/database';

export const CONVERSATION_LIST_PAGE_SIZE = 20;

/** 单次拉取结果（一页或一批） */
export interface ConversationListPage {
  items: ConversationResponse[];
  /** 在当前源上是否还能再 loadNext 一页 */
  hasMore: boolean;
}

/**
 * 分页式会话列表源：restart 后开始新序列；首次 loadNext 为第一页，之后为后续页。
 */
export interface IConversationListPagedSource {
  restart(): void;
  loadNext(): Promise<ConversationListPage>;
  /** 至少成功 loadNext 过一次且仍有下一页时为 true */
  readonly hasMore: boolean;
}

/**
 * 远端会话列表（offset 与 cursor 共用实现）
 * 均通过 messageService.fetchRemoteConversationListPage 拉取并落库，行为一致。
 */
export class NetworkRemoteConversationListPagedSource implements IConversationListPagedSource {
  private nextPage = 1;
  private nextCursor: string | null = null;
  private hasMoreAfterLastLoad = false;
  private loadedOnce = false;
  private readonly pageSize: number;
  private readonly mode: RemoteConversationListSourceKind;

  constructor(
    mode: RemoteConversationListSourceKind,
    pageSize: number = CONVERSATION_LIST_PAGE_SIZE
  ) {
    this.mode = mode;
    this.pageSize = pageSize;
  }

  restart(): void {
    this.nextPage = 1;
    this.nextCursor = null;
    this.hasMoreAfterLastLoad = false;
    this.loadedOnce = false;
  }

  get hasMore(): boolean {
    return this.loadedOnce && this.hasMoreAfterLastLoad;
  }

  async loadNext(): Promise<ConversationListPage> {
    const result = await messageService.fetchRemoteConversationListPage({
      mode: this.mode,
      pageSize: this.pageSize,
      ...(this.mode === 'offset'
        ? { page: this.nextPage }
        : { cursor: this.nextCursor }),
    });

    this.hasMoreAfterLastLoad = result.hasMore;
    if (this.mode === 'offset') {
      this.nextPage = result.nextPage ?? this.nextPage + 1;
    } else {
      this.nextCursor = result.nextCursor ?? null;
    }
    this.loadedOnce = true;
    return { items: result.items, hasMore: result.hasMore };
  }
}

/** SQLite 会话列表缓存（单批，无后续页） */
export class SqliteConversationListPagedSource implements IConversationListPagedSource {
  private consumed = false;

  restart(): void {
    this.consumed = false;
  }

  get hasMore(): boolean {
    return false;
  }

  async loadNext(): Promise<ConversationListPage> {
    if (this.consumed) {
      return { items: [], hasMore: false };
    }
    this.consumed = true;
    try {
      const items = await getConversationListCache();
      return { items, hasMore: false };
    } catch (e) {
      console.warn('[SqliteConversationListPagedSource] 读取会话列表缓存失败:', e);
      return { items: [], hasMore: false };
    }
  }
}

/** 远端会话列表分页策略 */
export type RemoteConversationListSourceKind = 'cursor' | 'offset';

export function createRemoteConversationListSource(
  kind: RemoteConversationListSourceKind,
  pageSize: number = CONVERSATION_LIST_PAGE_SIZE
): IConversationListPagedSource {
  return new NetworkRemoteConversationListPagedSource(kind, pageSize);
}
