// Mirrors the server's Page[T] envelope used by paged endpoints
// (/api/search, /api/library/artists, /api/library/albums,
// /api/likes/*). Class is named `Paged<T>` rather than `Page<T>`
// to avoid ambiguous imports with Flutter Material's Navigator-2.0
// `Page` class.
//
// Wire shape from internal/api/types.go Page[T]:
//   { items: T[], total: int, limit: int, offset: int }
//
// Dart generics can't auto-infer T from JSON, so callers pass an
// itemFromJson function alongside the raw map. Parse logic stays in
// each entity's own fromJson; this class only handles the envelope.
class Paged<T> {
  const Paged({
    required this.items,
    required this.total,
    required this.limit,
    required this.offset,
  });

  final List<T> items;
  final int total;
  final int limit;
  final int offset;

  factory Paged.fromJson(
    Map<String, dynamic> j,
    T Function(Map<String, dynamic>) itemFromJson,
  ) {
    final raw = (j['items'] as List?) ?? const [];
    return Paged<T>(
      items: raw
          .map((e) => itemFromJson((e as Map).cast<String, dynamic>()))
          .toList(growable: false),
      total: (j['total'] as num?)?.toInt() ?? 0,
      limit: (j['limit'] as num?)?.toInt() ?? 0,
      offset: (j['offset'] as num?)?.toInt() ?? 0,
    );
  }

  /// Convenience for endpoints that always return the first page or
  /// when the caller just wants the items.
  bool get hasMore => offset + items.length < total;
}
