import 'package:dio/dio.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';

import 'package:superport_v2/core/network/api_client.dart';
import 'package:superport_v2/features/util/postal_search/data/repositories/postal_search_repository_remote.dart';

class _MockApiClient extends Mock implements ApiClient {}

void main() {
  late ApiClient apiClient;
  late PostalSearchRepositoryRemote repository;

  setUpAll(() {
    registerFallbackValue(Options());
    registerFallbackValue(CancelToken());
  });

  setUp(() {
    apiClient = _MockApiClient();
    repository = PostalSearchRepositoryRemote(apiClient: apiClient);
  });

  test('검색 키워드가 비어 있으면 빈 배열을 반환한다', () async {
    final result = await repository.search(keyword: '   ');
    expect(result, isEmpty);
    verifyNever(() => apiClient.get<dynamic>(any()));
  });

  test('검색 요청 시 q/page/page_size 파라미터를 전달한다', () async {
    when(
      () => apiClient.get<dynamic>(
        any(),
        query: any(named: 'query'),
        options: any(named: 'options'),
        cancelToken: any(named: 'cancelToken'),
      ),
    ).thenAnswer(
      (_) async => Response<dynamic>(
        data: {
          'items': [
            {
              'zipcode': '06000',
              'sido': '서울특별시',
              'sigungu': '강남구',
              'road_name': '테헤란로',
            },
          ],
        },
        requestOptions: RequestOptions(path: '/api/v1/zipcodes'),
        statusCode: 200,
      ),
    );

    final result = await repository.search(keyword: '테헤란로', limit: 10, page: 2);

    expect(result, hasLength(1));

    final verification = verify(
      () => apiClient.get<dynamic>(
        captureAny(),
        query: captureAny(named: 'query'),
        options: any(named: 'options'),
        cancelToken: any(named: 'cancelToken'),
      ),
    );
    final path = verification.captured[0] as String;
    final query = verification.captured[1] as Map<String, dynamic>;

    expect(path, equals('/api/v1/zipcodes'));
    expect(query['q'], '테헤란로');
    expect(query['page'], 2);
    expect(query['page_size'], 10);
    expect(query.containsKey('zipcode'), isFalse);
    expect(query.containsKey('road_name'), isFalse);
  });
}
