import 'package:dio/dio.dart'; import 'package:flutter_android_app/components/locale/l10n/app_localizations.dart'; import 'package:flutter_android_app/components/utils/error_callback.dart'; import 'package:flutter_android_app/data/dtos/coins_dto.dart'; import 'package:flutter_android_app/data/dtos/search_coins_dto.dart'; import 'package:flutter_android_app/data/mappers/crypto_mapper.dart'; import 'package:flutter_android_app/repositories/api_interface.dart'; import 'package:pretty_dio_logger/pretty_dio_logger.dart'; import '../domain/models/home.dart'; class CryptoRepository extends ApiInterface { static const String _baseUrl = 'https://api.coingecko.com/api/v3'; static const String _searchUrl = '/search'; static const String _coinsDataUrl = '/coins/markets'; static const String _apiKey = 'CG-oer6F3AAhVpNxGDxc7mjzZCo'; static final Dio _dio = Dio() ..interceptors.add(PrettyDioLogger( requestBody: true, requestHeader: true, )); @override Future loadData({ OnErrorCallback? onError, String? search, int page = 1, int pageSize = 20, AppLocale? locale, }) async { try { Map queryParams = { 'x_cg_demo_api_key': _apiKey, 'vs_currency': _getCurrencyName(locale?.localeName), 'per_page': pageSize, 'page': page, }; if (search != null && search.isNotEmpty) { final Response searchResponse = await _dio.get>( '$_baseUrl$_searchUrl', queryParameters: { 'x_cg_demo_api_key': _apiKey, 'query': search, } ); final SearchCoinsDto searchCoinsDto = SearchCoinsDto.fromJson(searchResponse.data as Map); if (searchCoinsDto.coins != null) { String ids = ''; for (var coinData in searchCoinsDto.coins!) { ids += coinData.id != null ? '${coinData.id},' : ''; } if (ids.isEmpty) { return HomeData(); } queryParams['ids'] = ids; } } final response = await _dio.get( '$_baseUrl$_coinsDataUrl', queryParameters: queryParams, ); final CoinsDto dto = CoinsDto.fromJson(response.data as List); final HomeData data = dto.toDomain(locale, page); return data; } on DioException catch (e) { onError?.call(e.error?.toString()); return null; } } @override Future loadDataWithIds({ OnErrorCallback? onError, List ids = const [], int page = 1, int pageSize = 20, AppLocale? locale, }) async { try { Map queryParams = { 'x_cg_demo_api_key': _apiKey, 'vs_currency': _getCurrencyName(locale?.localeName), 'per_page': pageSize, 'page': page, }; String idsCommaSeparated = ''; for (var id in ids) { idsCommaSeparated += '$id,'; } if (ids.isEmpty) { return HomeData(); } queryParams['ids'] = idsCommaSeparated; final response = await _dio.get( '$_baseUrl$_coinsDataUrl', queryParameters: queryParams, ); final CoinsDto dto = CoinsDto.fromJson(response.data as List); final HomeData data = dto.toDomain(locale, page); return data; } on DioException catch (e) { onError?.call(e.error?.toString()); return null; } } String _getCurrencyName(String? localeName) { if (localeName == null) { return 'usd'; } return switch (localeName) { 'ru' => 'rub', _ => 'usd', }; } }