import 'package:dio/dio.dart'; import 'package:injectable/injectable.dart'; import '../../../../core/config/environment.dart'; import '../../../../core/utils/logger.dart'; import '../../../../features/authentication/data/datasources/keycloak_auth_service.dart'; import '../models/formule_model.dart'; import '../models/souscription_status_model.dart'; @lazySingleton class SouscriptionDatasource { final KeycloakAuthService _authService; final Dio _dio = Dio(); SouscriptionDatasource(this._authService); Future _authOptions() async { final token = await _authService.getValidToken(); return Options( headers: {'Authorization': 'Bearer $token'}, validateStatus: (s) => s != null && s < 500, ); } String get _base => AppConfig.apiBaseUrl; /// Liste toutes les formules disponibles (public) Future> getFormules() async { try { final opts = await _authOptions(); final response = await _dio.get('$_base/api/souscriptions/formules', options: opts); if (response.statusCode == 200 && response.data is List) { return (response.data as List) .map((e) => FormuleModel.fromJson(e as Map)) .toList(); } } catch (e) { AppLogger.error('SouscriptionDatasource.getFormules: $e'); } return []; } /// Récupère la souscription courante de l'OrgAdmin connecté Future getMaSouscription() async { try { final opts = await _authOptions(); final response = await _dio.get('$_base/api/souscriptions/ma-souscription', options: opts); if (response.statusCode == 200 && response.data is Map) { return SouscriptionStatusModel.fromJson(response.data as Map); } } catch (e) { AppLogger.error('SouscriptionDatasource.getMaSouscription: $e'); } return null; } /// Crée une demande de souscription Future creerDemande({ required String typeFormule, required String plageMembres, required String typePeriode, required String typeOrganisation, required String organisationId, }) async { try { final opts = await _authOptions(); final response = await _dio.post( '$_base/api/souscriptions/demande', data: { 'typeFormule': typeFormule, 'plageMembres': plageMembres, 'typePeriode': typePeriode, 'typeOrganisation': typeOrganisation, 'organisationId': organisationId, }, options: opts, ); if ((response.statusCode == 200 || response.statusCode == 201) && response.data is Map) { return SouscriptionStatusModel.fromJson(response.data as Map); } AppLogger.warning('SouscriptionDatasource.creerDemande: HTTP ${response.statusCode}'); } catch (e) { AppLogger.error('SouscriptionDatasource.creerDemande: $e'); } return null; } /// Initie le paiement Wave pour une souscription existante Future initierPaiement(String souscriptionId) async { try { final opts = await _authOptions(); final response = await _dio.post( '$_base/api/souscriptions/$souscriptionId/initier-paiement', options: opts, ); if (response.statusCode == 200 && response.data is Map) { return SouscriptionStatusModel.fromJson(response.data as Map); } } catch (e) { AppLogger.error('SouscriptionDatasource.initierPaiement: $e'); } return null; } /// Confirme le paiement Wave après retour du deep link Future confirmerPaiement(String souscriptionId) async { try { final opts = await _authOptions(); final response = await _dio.post( '$_base/api/souscriptions/$souscriptionId/confirmer-paiement', options: opts, ); return response.statusCode == 200; } catch (e) { AppLogger.error('SouscriptionDatasource.confirmerPaiement: $e'); } return false; } }