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/masters/customer/data/repositories/customer_repository_remote.dart';

class _MockApiClient extends Mock implements ApiClient {}

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

  setUpAll(() {
    registerFallbackValue(Options());
    registerFallbackValue(CancelToken());
    registerFallbackValue(
      Response<dynamic>(requestOptions: RequestOptions(path: '/')),
    );
  });

  setUp(() {
    apiClient = _MockApiClient();
    repository = CustomerRepositoryRemote(apiClient: apiClient);
    when(() => apiClient.unwrapAsMap(any())).thenAnswer((invocation) {
      final response = invocation.positionalArguments.first;
      if (response is Response) {
        final data = response.data;
        if (data is Map<String, dynamic>) {
          final nested = data['data'];
          if (nested is Map<String, dynamic>) {
            return nested;
          }
          return data;
        }
      }
      return <String, dynamic>{};
    });
  });

  test('list 호출 시 필터를 쿼리에 포함한다', () async {
    when(
      () => apiClient.get<Map<String, dynamic>>(
        any(),
        query: any(named: 'query'),
        options: any(named: 'options'),
        cancelToken: any(named: 'cancelToken'),
      ),
    ).thenAnswer(
      (_) async => Response<Map<String, dynamic>>(
        data: {
          'items': [
            {'id': 1, 'customer_code': 'C-001', 'customer_name': '슈퍼포트'},
          ],
          'page': 2,
          'page_size': 30,
          'total': 1,
        },
        requestOptions: RequestOptions(path: '/api/v1/customers'),
        statusCode: 200,
      ),
    );

    final result = await repository.list(
      page: 2,
      pageSize: 30,
      query: 'sup',
      isPartner: true,
      isGeneral: false,
      isActive: true,
    );

    expect(result.items, isNotEmpty);

    final verification = verify(
      () => apiClient.get<Map<String, 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/customers'));
    expect(query['page'], 2);
    expect(query['page_size'], 30);
    expect(query['q'], 'sup');
    expect(query['is_partner'], true);
    expect(query['is_general'], false);
    expect(query['active'], true);
  });

  test('fetchDetail은 include=zipcode 파라미터를 전달한다', () async {
    when(
      () => apiClient.get<Map<String, dynamic>>(
        any(),
        query: any(named: 'query'),
        options: any(named: 'options'),
        cancelToken: any(named: 'cancelToken'),
      ),
    ).thenAnswer(
      (_) async => Response<Map<String, dynamic>>(
        data: {
          'data': {
            'id': 10,
            'customer_code': 'C-010',
            'customer_name': '테스트 고객',
            'zipcode': {'zipcode': '06000'},
          },
        },
        requestOptions: RequestOptions(path: '/api/v1/customers/10'),
        statusCode: 200,
      ),
    );

    final customer = await repository.fetchDetail(10);

    expect(customer.customerCode, 'C-010');

    final verification = verify(
      () => apiClient.get<Map<String, 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/customers/10'));
    expect(query['include'], 'zipcode');
  });
}
