// services/restaurant_api_service.dart (mise à jour) import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'package:itrimobe/models/command_detail.dart'; import 'package:itrimobe/models/payment_method.dart'; import 'package:itrimobe/models/tables_order.dart'; class RestaurantApiService { static const String baseUrl = 'https://restaurant.careeracademy.mg'; static final Map _headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', }; static Future updateCommandeStatus({ required String commandeId, required String newStatus, }) async { try { final response = await http.put( Uri.parse('$baseUrl/api/commandes/$commandeId/status'), headers: _headers, body: json.encode({'statut': newStatus}), ); if (response.statusCode == 200 || response.statusCode == 204) { return true; } else { print('Erreur updateCommandeStatus: ${response.statusCode} ${response.body}'); return false; } } catch (e) { print('Exception updateCommandeStatus: $e'); return false; } } // Récupérer les commandes static Future> getCommandes() async { try { final response = await http .get( Uri.parse('$baseUrl/api/commandes?statut=servie'), headers: _headers, ) .timeout( const Duration(seconds: 30), onTimeout: () => throw TimeoutException('Délai d\'attente dépassé'), ); if (response.statusCode == 200) { final dynamic responseBody = json.decode(response.body); print('Réponse getCommandes: ${responseBody['data']['commandes']}'); // Validation de la structure de réponse if (responseBody == null) { throw const FormatException('Réponse vide du serveur'); } final List data = responseBody is Map ? (responseBody['data']['commandes'] ?? responseBody['commandes'] ?? []) : responseBody as List; if (data.isEmpty) { return []; // Retourner une liste vide si pas de données } return data.map((json) { try { return TableOrder.fromJson(json as Map); } catch (e) { if (kDebugMode) { print('Erreur parsing commande: $json - $e'); } rethrow; } }).toList(); } else if (response.statusCode >= 400 && response.statusCode < 500) { throw Exception( 'Erreur client ${response.statusCode}: ${response.reasonPhrase}', ); } else if (response.statusCode >= 500) { throw Exception( 'Erreur serveur ${response.statusCode}: ${response.reasonPhrase}', ); } else { throw Exception( 'Réponse inattendue ${response.statusCode}: ${response.body}', ); } } on SocketException { throw Exception('Pas de connexion internet. Vérifiez votre connexion.'); } on TimeoutException { throw Exception( 'Délai d\'attente dépassé. Le serveur met trop de temps à répondre.', ); } on FormatException catch (e) { throw Exception('Réponse serveur invalide: ${e.message}'); } on http.ClientException catch (e) { throw Exception('Erreur de connexion: ${e.message}'); } catch (e) { print('Erreur inattendue getCommandes: $e'); throw Exception('Erreur lors de la récupération des commandes: $e'); } } // Créer une commande directe static Future creerCommandeDirecte( Map commandeData, ) async { try { final response = await http.post( Uri.parse('$baseUrl/api/commandes'), headers: _headers, body: json.encode(commandeData), ); return response.statusCode == 201; } catch (e) { print('Erreur lors de la création de la commande directe: $e'); return false; // Pour la démo } } //processPayment // Dans services/restaurant_api_service.dart static Future processPayment({ required String commandeId, // Ajoutez ce paramètre required String paymentMethodId, required double amount, }) async { try { final response = await http.post( Uri.parse('$baseUrl/api/commandes/$commandeId'), headers: _headers, body: json.encode({ 'mode_paiement': paymentMethodId, 'statut': 'payee', }), ); if (response.statusCode == 200 || response.statusCode == 201) { final data = json.decode(response.body); return data['success'] ?? true; } else { throw Exception('Erreur ${response.statusCode}: ${response.body}'); } } catch (e) { print('Erreur API processPayment: $e'); // Pour les tests, retourner true return true; } } // Récupérer les détails d'une commande // services/restaurant_api_service.dart (mise à jour de la méthode) static Future getCommandeDetails(String commandeId) async { try { final response = await http.get( Uri.parse('$baseUrl/api/commandes/$commandeId'), headers: _headers, ); if (response.statusCode == 200) { final Map jsonData = json.decode(response.body); // Gestion de la réponse avec wrapper "success" et "data" if (jsonData['success'] == true) { return CommandeDetail.fromJson(jsonData); } else { throw Exception( 'Erreur API: ${jsonData['message'] ?? 'Erreur inconnue'}', ); } } else { throw Exception('Erreur ${response.statusCode}: ${response.body}'); } } catch (e) { print('Erreur API getCommandeDetails: $e'); // Données de test basées sur votre JSON return CommandeDetail( id: int.tryParse(commandeId) ?? 31, clientId: 1, tableId: 2, reservationId: 1, numeroCommande: "CMD-1754147024077", statut: "payee", totalHt: 14.00, totalTva: 0.00, totalTtc: 14.00, modePaiement: null, commentaires: null, tablename: 'a', serveur: "Serveur par défaut", dateCommande: DateTime.parse("2025-08-02T15:03:44.000Z"), dateService: null, createdAt: DateTime.parse("2025-08-02T15:03:44.000Z"), updatedAt: DateTime.parse("2025-08-02T15:05:21.000Z"), items: [ CommandeItem( id: 37, commandeId: 31, menuId: 3, quantite: 1, prixUnitaire: 14.00, totalItem: 14.00, commentaires: null, statut: "commande", createdAt: DateTime.parse("2025-08-02T15:03:44.000Z"), updatedAt: DateTime.parse("2025-08-02T15:03:44.000Z"), menuNom: "Pizza Margherita", menuDescription: "Pizza traditionnelle tomate, mozzarella, basilic", menuPrixActuel: 14.00, ), ], ); } } // Récupérer toutes les tables static Future> getTables() async { try { final response = await http.get( Uri.parse('$baseUrl/api/tables'), headers: _headers, ); if (response.statusCode == 200) { final List data = json.decode(response.body); return data.map((json) => TableOrder.fromJson(json)).toList(); } else { throw Exception('Erreur ${response.statusCode}: ${response.body}'); } } catch (e) { print('Erreur API getTables: $e'); // Données de test basées sur votre structure DB return [ TableOrder( id: 1, nom: 'Table 1', capacity: 4, status: 'available', location: 'Salle principale', createdAt: DateTime.now().subtract(Duration(days: 1)), updatedAt: DateTime.now(), ), TableOrder( id: 2, nom: 'Table 2', capacity: 2, status: 'occupied', location: 'Terrasse', createdAt: DateTime.now().subtract(Duration(hours: 2)), updatedAt: DateTime.now(), total: 27.00, time: '00:02', ), // Ajoutez d'autres tables de test... ]; } } // Récupérer les commandes prêtes à encaisser static Future> getCommandesPretesAEncaisser() async { try { final response = await http.get( Uri.parse('$baseUrl/api/commandes'), headers: _headers, ); if (response.statusCode == 200) { final dynamic responseBody = json.decode(response.body); // Gérer les réponses avec wrapper "data" final List data = responseBody is Map ? (responseBody['data'] ?? responseBody['commandes'] ?? []) : responseBody as List; return data.map((json) => TableOrder.fromJson(json)).toList(); } else { throw Exception( 'Erreur serveur ${response.statusCode}: ${response.body}', ); } } on SocketException { throw Exception('Pas de connexion internet'); } on TimeoutException { throw Exception('Délai d\'attente dépassé'); } on FormatException { throw Exception('Réponse serveur invalide'); } catch (e) { print('Erreur API getCommandesPretesAEncaisser: $e'); throw Exception('Erreur lors de la récupération des commandes: $e'); } } // Mettre à jour le statut d'une table static Future updateTableStatus(int tableId, String newStatus) async { try { final response = await http.put( Uri.parse('$baseUrl/api/tables/$tableId'), headers: _headers, body: json.encode({ 'status': newStatus, 'updated_at': DateTime.now().toIso8601String(), }), ); return response.statusCode == 200; } catch (e) { print('Erreur lors de la mise à jour du statut: $e'); return true; // Pour la démo } } }