ApiClient constructor

ApiClient({
  1. Future<String?> getToken()?,
  2. void onUnauthorized()?,
  3. Dio? dio,
})

onUnauthorized: callback que se invoca cuando la API devuelve 401 durante una sesión activa (token caducado en mitad del uso). Se usa desde main.dart para limpiar el estado y redirigir al Login. dio es opcional y se utiliza para inyectar mocks durante los tests.

Implementation

ApiClient({this.getToken, void Function()? onUnauthorized, Dio? dio}) {
  _dio =
      dio ??
      Dio(
        BaseOptions(
          baseUrl: Platform.isAndroid
              ? 'http://10.0.2.2:8080/api/v1'
              : 'http://localhost:8080/api/v1',
          connectTimeout: const Duration(seconds: 5),
          receiveTimeout: const Duration(seconds: 15),
          contentType: 'application/json',
        ),
      );

  // Capa 2: interceptor de sesión — captura 401 durante el uso de la app
  _dio.interceptors.add(
    InterceptorsWrapper(
      onRequest: (options, handler) async {
        if (getToken != null) {
          final token = await getToken!();
          if (token != null) {
            options.headers['Authorization'] = 'Bearer $token';
          }
        }
        handler.next(options);
      },
      onError: (DioException error, ErrorInterceptorHandler handler) {
        // Solo interceptamos el 401 si hay sesión activa (token caducado).
        // Si no hay callback, dejamos pasar el error para que _handleError
        // lo procese con el mensaje correcto (ej.: credenciales incorrectas).
        if (error.response?.statusCode == 401 &&
            onUnauthorized != null &&
            !(error.requestOptions.path.contains('/auth/login'))) {
          onUnauthorized();
        }
        handler.next(error);
      },
    ),
  );
}