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/inventory/transactions/data/repositories/transaction_customer_repository_remote.dart';
import 'package:superport_v2/features/inventory/transactions/domain/entities/stock_transaction_input.dart';

class _MockApiClient extends Mock implements ApiClient {}

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

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

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

  test('addCustomers는 거래 ID를 포함해 POST 요청을 보낸다', () async {
    const path = '/api/v1/stock-transactions/77/customers';
    when(
      () => apiClient.post<void>(
        path,
        data: any(named: 'data'),
        options: any(named: 'options'),
        cancelToken: any(named: 'cancelToken'),
      ),
    ).thenAnswer(
      (_) async => Response<void>(
        requestOptions: RequestOptions(path: path),
        statusCode: 204,
      ),
    );

    await repository.addCustomers(77, [
      TransactionCustomerCreateInput(customerId: 700, note: '비고'),
    ]);

    final payload =
        verify(
              () => apiClient.post<void>(
                captureAny(),
                data: captureAny(named: 'data'),
                options: any(named: 'options'),
                cancelToken: any(named: 'cancelToken'),
              ),
            ).captured[1]
            as Map<String, dynamic>;

    expect(payload['id'], 77);
    expect(payload['customers'], isA<List>());
  });

  test('updateCustomers는 PATCH 요청을 보낸다', () async {
    const path = '/api/v1/stock-transactions/77/customers';
    when(
      () => apiClient.patch<void>(
        path,
        data: any(named: 'data'),
        options: any(named: 'options'),
        cancelToken: any(named: 'cancelToken'),
      ),
    ).thenAnswer(
      (_) async => Response<void>(
        requestOptions: RequestOptions(path: path),
        statusCode: 204,
      ),
    );

    await repository.updateCustomers(77, [
      TransactionCustomerUpdateInput(id: 301, note: '수정'),
    ]);

    verify(
      () => apiClient.patch<void>(
        path,
        data: any(named: 'data'),
        options: any(named: 'options'),
        cancelToken: any(named: 'cancelToken'),
      ),
    ).called(1);
  });

  test('deleteCustomer는 /transaction-customers/{id} 엔드포인트를 호출한다', () async {
    const path = '/api/v1/transaction-customers/301';
    when(
      () => apiClient.delete<void>(
        path,
        data: any(named: 'data'),
        options: any(named: 'options'),
        cancelToken: any(named: 'cancelToken'),
      ),
    ).thenAnswer(
      (_) async => Response<void>(
        requestOptions: RequestOptions(path: path),
        statusCode: 204,
      ),
    );

    await repository.deleteCustomer(301);

    verify(
      () => apiClient.delete<void>(
        path,
        data: any(named: 'data'),
        options: any(named: 'options'),
        cancelToken: any(named: 'cancelToken'),
      ),
    ).called(1);
  });
}
