class ApiResponse<T> {
  const ApiResponse({required this.code, required this.message, this.data});

  final int code;
  final String message;
  final T? data;

  bool get isSuccess => code == 0 || code >= 200 && code < 300;

  factory ApiResponse.fromJson(
    Map<String, dynamic> json, {
    T Function(dynamic json)? fromJsonT,
  }) {
    return ApiResponse<T>(
      code: (json['code'] as num?)?.toInt() ?? 200,
      message: (json['message'] ?? json['msg'] ?? '').toString(),
      data: fromJsonT == null ? json['data'] as T? : fromJsonT(json['data']),
    );
  }
}

class PageResponse<T> {
  const PageResponse({
    required this.items,
    required this.total,
    this.page,
    this.pageSize,
  });

  final List<T> items;
  final int total;
  final int? page;
  final int? pageSize;

  bool get isEmpty => items.isEmpty;

  factory PageResponse.fromJson(
    Map<String, dynamic> json, {
    required T Function(dynamic json) fromJsonT,
  }) {
    final rawItems = json['items'] ?? json['rows'] ?? json['list'] ?? const [];
    return PageResponse<T>(
      items: rawItems is List ? rawItems.map(fromJsonT).toList() : <T>[],
      total: (json['total'] as num?)?.toInt() ?? 0,
      page: (json['page'] as num?)?.toInt(),
      pageSize: (json['pageSize'] as num?)?.toInt(),
    );
  }
}
