import 'package:dio/dio.dart'; import '../models/api_error.dart'; import '../blocs/session/session_bloc.dart'; import '../blocs/session/session_event.dart'; import '../blocs/session/session_state.dart'; class ApiClient { late final Dio _dio; final SessionBloc _sessionBloc; ApiClient(this._sessionBloc, {String baseUrl = 'https://go.b0esche.cloud'}) { _dio = Dio( BaseOptions( baseUrl: baseUrl, connectTimeout: const Duration(seconds: 10), receiveTimeout: const Duration(seconds: 10), ), ); _dio.interceptors.add( InterceptorsWrapper( onRequest: (options, handler) { // Add JWT if available final token = _getCurrentToken(); if (token != null) { options.headers['Authorization'] = 'Bearer $token'; } return handler.next(options); }, onError: (error, handler) async { if (error.response?.statusCode == 401) { // Session expired, trigger logout _sessionBloc.add(SessionExpired()); } return handler.next(error); }, ), ); } String get baseUrl => _dio.options.baseUrl; String? _getCurrentToken() { // Get from SessionBloc state final state = _sessionBloc.state; if (state is SessionActive) { return state.token; } return null; } Future get( String path, { Map? queryParameters, required T Function(dynamic data) fromJson, }) async { try { final response = await _dio.get(path, queryParameters: queryParameters); return fromJson(response.data); } on DioException catch (e) { throw _handleError(e); } } Future post( String path, { dynamic data, required T Function(dynamic data) fromJson, }) async { try { final response = await _dio.post(path, data: data); return fromJson(response.data); } on DioException catch (e) { throw _handleError(e); } } Future> getList( String path, { Map? queryParameters, required T Function(dynamic data) fromJson, }) async { try { final response = await _dio.get(path, queryParameters: queryParameters); return (response.data as List).map(fromJson).toList(); } on DioException catch (e) { throw _handleError(e); } } ApiError _handleError(DioException e) { final status = e.response?.statusCode; final data = e.response?.data; // Handle network errors if (e.type == DioExceptionType.connectionError || e.type == DioExceptionType.connectionTimeout || e.type == DioExceptionType.receiveTimeout || e.type == DioExceptionType.sendTimeout) { return ApiError( code: 'NETWORK_ERROR', message: 'Network error. Please check your connection and try again.', status: status, ); } String code = data?['code'] ?? 'UNKNOWN'; String message = data?['message'] ?? 'Unknown error'; return ApiError(code: code, message: message, status: status); } }