import 'package:dio/dio.dart';
import 'package:laba1/data/mappers/spells_mapper.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';

import '../../domain/models/card.dart';
import '../../domain/models/home.dart';
import '../dtos/spells_dto.dart';
import 'api_interface.dart';

class PotterRepository extends ApiInterface {
  static final Dio _dio = Dio()
    ..interceptors.add(PrettyDioLogger(
      requestHeader: true,
      requestBody: true,
    ));

  static const String _baseUrl = 'https://api.potterdb.com';

  @override
  Future<HomeData?> loadData({
    OnErrorCallback? onError,
    String? q,
    int page = 1,
    int pageSize = 25,
  }) async {
    try {
      const String url = '$_baseUrl/v1/spells';

      SpellsDto dto;
      if (q == null) {
        final Response<dynamic> response =
            await _dio.get<Map<dynamic, dynamic>>(url, queryParameters: {
          'filter[name_cont]': q,
          'page[number]': page,
          'page[size]': pageSize,
        });
        dto = SpellsDto.fromJson(response.data as Map<String, dynamic>);
        return dto.toDomain();
      }

      final Response<dynamic> response1 =
          await _dio.get<Map<dynamic, dynamic>>(url, queryParameters: {
        'filter[name_cont]': q,
        'page[number]': page,
        'page[size]': pageSize,
      });
      SpellsDto dto1 =
      SpellsDto.fromJson(response1.data as Map<String, dynamic>);

      final HomeData homeData1 = dto1.toDomain();
      if (homeData1.data != null && homeData1.data!.isNotEmpty)
        return HomeData(data: homeData1.data, nextPage: page+1);

      page -= ((dto1.meta?.pagination?.records ?? 0) / pageSize).ceil();

      final Response<dynamic> response2 =
          await _dio.get<Map<dynamic, dynamic>>(url, queryParameters: {
        'filter[incantation_cont]': q,
        'page[number]': page,
        'page[size]': pageSize,
      });
      SpellsDto dto2 =
      SpellsDto.fromJson(response2.data as Map<String, dynamic>);

      return dto2.toDomain();

    } on DioException catch (e) {
      onError?.call(e.error?.toString());
      return null;
    }
  }
}
