/// JSON 응답 형태를 일관되게 다루기 위한 헬퍼 모음.
class JsonUtils {
  JsonUtils._();

  /// 리스트 응답을 추출한다.
  ///
  /// - [source]가 List이면 맵 형태의 요소만 반환한다.
  /// - Map이면 [keys] 순서대로 탐색하며 List/Map을 찾아 리스트로 변환한다.
  static List<Map<String, dynamic>> extractList(
    dynamic source, {
    List<String> keys = const ['items', 'data', 'results'],
  }) {
    if (source is List) {
      return source.whereType<Map<String, dynamic>>().toList(growable: false);
    }
    if (source is Map<String, dynamic>) {
      for (final key in keys) {
        if (!source.containsKey(key)) continue;
        final value = source[key];
        if (value is List) {
          return value.whereType<Map<String, dynamic>>().toList(
            growable: false,
          );
        }
        if (value is Map<String, dynamic>) {
          return [value];
        }
      }
    }
    return const [];
  }

  /// Map 응답을 추출한다. 기본적으로 `data` 키를 우선 확인한다.
  static Map<String, dynamic> extractMap(
    dynamic source, {
    List<String> keys = const ['data'],
  }) {
    if (source is Map<String, dynamic>) {
      for (final key in keys) {
        final value = source[key];
        if (value is Map<String, dynamic>) {
          return value;
        }
      }
      return source;
    }
    return const {};
  }

  /// 맵에서 정수 값을 안전하게 읽는다. 문자열/실수도 허용한다.
  static int readInt(
    Map<String, dynamic>? source,
    String key, {
    int fallback = 0,
  }) {
    if (source == null) {
      return fallback;
    }
    final value = source[key];
    if (value is int) {
      return value;
    }
    if (value is double) {
      return value.round();
    }
    if (value is String) {
      return int.tryParse(value) ?? fallback;
    }
    return fallback;
  }
}
