import 'package:flutter/material.dart'; import 'package:geosector_app/core/constants/app_keys.dart'; import 'package:geosector_app/presentation/widgets/charts/passage_data.dart'; import 'package:intl/intl.dart'; /// Utilitaires pour les passages et règlements class PassageUtils { /// Convertit les données de passage brutes en liste de PassageData /// /// [passageData] est une liste d'objets contenant date, type_passage et nb static List> getPassageDataByType( List> passageData) { // Créer un Map pour stocker les données par type de passage final Map> passagesByType = {}; // Initialiser les listes pour chaque type de passage for (final entry in AppKeys.typesPassages.entries) { passagesByType[entry.key] = []; } // Grouper les passages par type for (final data in passageData) { final int typeId = data['type_passage']; final int count = data['nb']; if (AppKeys.typesPassages.containsKey(typeId)) { final typeData = AppKeys.typesPassages[typeId]!; final Color color = Color(typeData['couleur1'] as int); final String iconPath = typeData['icone'] as String; final String title = typeData['titre'] as String; // Utiliser la méthode factory qui gère les dates au format ISO 8601 if (data['date'] is String) { passagesByType[typeId]!.add( PassageData.fromIsoDate( isoDate: data['date'], typeId: typeId, count: count, color: color, iconPath: iconPath, title: title, ), ); } else { // Fallback pour les objets DateTime (pour compatibilité) final DateTime date = data['date'] as DateTime; passagesByType[typeId]!.add( PassageData( date: date, typeId: typeId, count: count, color: color, iconPath: iconPath, title: title, ), ); } } } // Convertir le Map en liste de listes return passagesByType.values.toList(); } /// Convertit les données de règlement brutes en liste de PaymentAmountData /// /// [paymentData] est une liste d'objets contenant date, type_reglement et montant static List> getPaymentDataByType( List> paymentData) { // Créer un Map pour stocker les données par type de règlement final Map> paymentsByType = {}; // Initialiser les listes pour chaque type de règlement (sauf 0 qui est "Pas de règlement") for (final entry in AppKeys.typesReglements.entries) { if (entry.key > 0) { // Ignorer le type 0 (Pas de règlement) paymentsByType[entry.key] = []; } } // Grouper les règlements par type for (final data in paymentData) { final int typeId = data['type_reglement']; final double amount = data['montant'] is double ? data['montant'] : double.parse(data['montant'].toString()); if (typeId > 0 && AppKeys.typesReglements.containsKey(typeId)) { final typeData = AppKeys.typesReglements[typeId]!; final Color color = Color(typeData['couleur'] as int); final dynamic iconData = _getIconForPaymentType(typeId); final String title = typeData['titre'] as String; // Utiliser la méthode factory qui gère les dates au format ISO 8601 if (data['date'] is String) { paymentsByType[typeId]!.add( PaymentAmountData.fromIsoDate( isoDate: data['date'], typeId: typeId, amount: amount, color: color, iconData: iconData, title: title, ), ); } else { // Fallback pour les objets DateTime (pour compatibilité) final DateTime date = data['date'] as DateTime; paymentsByType[typeId]!.add( PaymentAmountData( date: date, typeId: typeId, amount: amount, color: color, iconData: iconData, title: title, ), ); } } } // Convertir le Map en liste de listes return paymentsByType.values.toList(); } /// Génère des données de passage fictives pour les 14 derniers jours static List> generateMockPassageData() { final List> mockData = []; final now = DateTime.now(); for (int i = 13; i >= 0; i--) { final date = now.subtract(Duration(days: i)); // Ajouter des données pour chaque type de passage for (int typeId = 1; typeId <= 6; typeId++) { // Générer un nombre aléatoire de passages entre 0 et 5 final count = (typeId == 1 || typeId == 2) ? (1 + (date.day % 5)) // Plus de passages pour les types 1 et 2 : (date.day % 3); // Moins pour les autres types if (count > 0) { mockData.add({ 'date': date, 'type_passage': typeId, 'nb': count, }); } } } return mockData; } /// Génère des données de règlement fictives pour les 14 derniers jours static List> generateMockPaymentData() { final List> mockData = []; final now = DateTime.now(); for (int i = 13; i >= 0; i--) { final date = now.subtract(Duration(days: i)); // Ajouter des données pour chaque type de règlement for (int typeId = 1; typeId <= 3; typeId++) { // Générer un montant aléatoire final amount = (typeId * 100.0) + (date.day * 10.0); mockData.add({ 'date': date, 'type_reglement': typeId, 'montant': amount, }); } } return mockData; } /// Obtenir l'icône correspondant au type de règlement /// Retourne un IconData pour les règlements car ils n'ont pas de chemin d'icône défini dans AppKeys static IconData _getIconForPaymentType(int typeId) { switch (typeId) { case 1: // Espèces return Icons.payments; case 2: // Chèque return Icons.money; case 3: // CB return Icons.credit_card; default: return Icons.euro; } } /// Formater une date pour l'affichage dans les graphiques static String formatDateForChart(DateTime date, String periodType) { switch (periodType.toLowerCase()) { case 'jour': return DateFormat('dd/MM').format(date); case 'semaine': // Calculer le numéro de la semaine dans l'année final firstDayOfYear = DateTime(date.year, 1, 1); final dayOfYear = date.difference(firstDayOfYear).inDays; final weekNumber = ((dayOfYear + firstDayOfYear.weekday - 1) / 7).ceil(); return 'S$weekNumber'; case 'mois': return DateFormat('MMM').format(date); case 'année': return DateFormat('yyyy').format(date); default: return DateFormat('dd/MM').format(date); } } }