import 'dart:async'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:geosector_app/core/data/models/user_model.dart'; import 'package:geosector_app/core/constants/app_keys.dart'; import 'package:retry/retry.dart'; class ApiService { final Dio _dio = Dio(); final String _baseUrl = AppKeys.baseApiUrl; String? _sessionId; ApiService() { _dio.options.baseUrl = _baseUrl; _dio.options.connectTimeout = AppKeys.connectionTimeout; _dio.options.receiveTimeout = AppKeys.receiveTimeout; _dio.options.headers.addAll(AppKeys.defaultHeaders); // Ajouter des intercepteurs pour l'authentification par session _dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) { // Ajouter le session_id comme token Bearer aux en-têtes si disponible if (_sessionId != null) { options.headers[AppKeys.sessionHeader] = 'Bearer $_sessionId'; } return handler.next(options); }, onError: (DioException error, handler) { // Gérer les erreurs d'authentification (401) if (error.response?.statusCode == 401) { // Session expirée ou invalide _sessionId = null; } return handler.next(error); })); } // Définir l'ID de session void setSessionId(String? sessionId) { _sessionId = sessionId; } // Vérifier la connectivité réseau Future hasInternetConnection() async { final connectivityResult = await (Connectivity().checkConnectivity()); return connectivityResult != ConnectivityResult.none; } // Méthode POST générique Future post(String path, {dynamic data}) async { try { return await _dio.post(path, data: data); } catch (e) { rethrow; } } // Méthode GET générique Future get(String path, {Map? queryParameters}) async { try { return await _dio.get(path, queryParameters: queryParameters); } catch (e) { rethrow; } } // Méthode PUT générique Future put(String path, {dynamic data}) async { try { return await _dio.put(path, data: data); } catch (e) { rethrow; } } // Méthode DELETE générique Future delete(String path) async { try { return await _dio.delete(path); } catch (e) { rethrow; } } // Authentification avec PHP session Future> login(String username, String password, {String type = 'admin'}) async { try { final response = await _dio.post(AppKeys.loginEndpoint, data: { 'username': username, 'password': password, 'type': type, // Ajouter le type de connexion (user ou admin) }); // Vérifier la structure de la réponse final data = response.data as Map; final status = data['status'] as String?; // Afficher le message en cas d'erreur if (status != 'success') { final message = data['message'] as String?; debugPrint('Erreur d\'authentification: $message'); } // Si le statut est 'success', récupérer le session_id if (status == 'success' && data.containsKey('session_id')) { final sessionId = data['session_id']; // Définir la session pour les futures requêtes if (sessionId != null) { setSessionId(sessionId); } } return data; } catch (e) { rethrow; } } // Déconnexion Future logout() async { try { if (_sessionId != null) { await _dio.post(AppKeys.logoutEndpoint); _sessionId = null; } } catch (e) { // Même en cas d'erreur, on réinitialise la session _sessionId = null; rethrow; } } // Utilisateurs Future> getUsers() async { try { final response = await retry( () => _dio.get('/users'), retryIf: (e) => e is SocketException || e is TimeoutException, ); return (response.data as List) .map((json) => UserModel.fromJson(json)) .toList(); } catch (e) { // Gérer les erreurs rethrow; } } Future getUserById(int id) async { try { final response = await _dio.get('/users/$id'); return UserModel.fromJson(response.data); } catch (e) { rethrow; } } Future createUser(UserModel user) async { try { final response = await _dio.post('/users', data: user.toJson()); return UserModel.fromJson(response.data); } catch (e) { rethrow; } } Future updateUser(UserModel user) async { try { final response = await _dio.put('/users/${user.id}', data: user.toJson()); return UserModel.fromJson(response.data); } catch (e) { rethrow; } } Future deleteUser(String id) async { try { await _dio.delete('/users/$id'); } catch (e) { rethrow; } } // Espace réservé pour les futures méthodes de gestion des profils // Espace réservé pour les futures méthodes de gestion des données // Synchronisation en batch Future> syncData({ List? users, }) async { try { final Map payload = { if (users != null) 'users': users.map((u) => u.toJson()).toList(), }; final response = await _dio.post('/sync', data: payload); return response.data; } catch (e) { rethrow; } } }