/**
 * 帖子列表数据源抽象：游标、偏移分页实现同一契约，PostManager 只依赖接口。
 */

import { Post } from '../../types';
import { postService } from '@/services/post';
import type { CursorPaginationRequest } from '../../types/dto';

export const POST_LIST_PAGE_SIZE = 20;

/** 帖子列表类型 */
export type PostListTab = 'hot' | 'latest' | 'follow';

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

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

/**
 * 远端帖子列表（游标分页）
 */
export class NetworkCursorPostListPagedSource implements IPostListPagedSource {
  private nextCursor: string | null = null;
  private hasMoreAfterLastLoad = false;
  private loadedOnce = false;
  private readonly pageSize: number;
  private readonly tab?: PostListTab;
  private readonly channelId?: string;

  constructor(
    options: { tab?: PostListTab; channelId?: string; pageSize?: number } = {}
  ) {
    this.tab = options.tab;
    this.channelId = options.channelId;
    this.pageSize = options.pageSize ?? POST_LIST_PAGE_SIZE;
  }

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

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

  async loadNext(): Promise<PostListPage> {
    const params: CursorPaginationRequest = {
      cursor: this.nextCursor ?? '',
      page_size: this.pageSize,
      post_type: this.tab,
    };

    const result = await postService.getPostsCursor(params);

    this.hasMoreAfterLastLoad = result.has_more ?? false;
    this.nextCursor = result.next_cursor ?? null;
    this.loadedOnce = true;

    return { items: result.list ?? [], hasMore: this.hasMoreAfterLastLoad };
  }
}

/**
 * 远端帖子列表（偏移分页）
 */
export class NetworkOffsetPostListPagedSource implements IPostListPagedSource {
  private nextPage = 1;
  private hasMoreAfterLastLoad = false;
  private loadedOnce = false;
  private readonly pageSize: number;
  private readonly tab?: PostListTab;
  private readonly channelId?: string;

  constructor(
    options: { tab?: PostListTab; channelId?: string; pageSize?: number } = {}
  ) {
    this.tab = options.tab;
    this.channelId = options.channelId;
    this.pageSize = options.pageSize ?? POST_LIST_PAGE_SIZE;
  }

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

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

  async loadNext(): Promise<PostListPage> {
    const result = await postService.getPosts(
      this.nextPage,
      this.pageSize,
      this.tab,
      this.channelId
    );

    const items = result.list ?? [];
    const total = result.total ?? 0;
    const totalPages = result.total_pages ?? 1;

    this.hasMoreAfterLastLoad = this.nextPage < totalPages;
    this.nextPage++;
    this.loadedOnce = true;

    return { items, hasMore: this.hasMoreAfterLastLoad };
  }
}

/** 远端帖子列表分页策略 */
export type RemotePostListSourceKind = 'cursor' | 'offset';

export function createRemotePostListSource(
  kind: RemotePostListSourceKind = 'cursor',
  options: { tab?: PostListTab; channelId?: string; pageSize?: number } = {}
): IPostListPagedSource {
  if (kind === 'offset') {
    return new NetworkOffsetPostListPagedSource(options);
  }
  return new NetworkCursorPostListPagedSource(options);
}
