// Components/newCommandComponents/CadeauDialog.dart import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:youmazgestion/Models/client.dart'; import 'package:youmazgestion/Models/produit.dart'; import 'package:youmazgestion/Services/stock_managementDatabase.dart'; class CadeauDialog extends StatefulWidget { final Product product; final int quantite; final DetailCommande? detailExistant; const CadeauDialog({ Key? key, required this.product, required this.quantite, this.detailExistant, }) : super(key: key); @override _CadeauDialogState createState() => _CadeauDialogState(); } class _CadeauDialogState extends State { final AppDatabase _database = AppDatabase.instance; List _produitsDisponibles = []; Product? _produitCadeauSelectionne; int _quantiteCadeau = 1; bool _isLoading = true; String _searchQuery = ''; @override void initState() { super.initState(); _loadProduitsDisponibles(); } Future _loadProduitsDisponibles() async { try { final produits = await _database.getProducts(); setState(() { _produitsDisponibles = produits.where((p) => p.id != widget.product.id && // Exclure le produit principal (p.stock == null || p.stock! > 0) // Seulement les produits en stock ).toList(); _isLoading = false; }); } catch (e) { setState(() { _isLoading = false; }); Get.snackbar( 'Erreur', 'Impossible de charger les produits: $e', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.red, colorText: Colors.white, ); } } List get _produitsFiltres { if (_searchQuery.isEmpty) { return _produitsDisponibles; } return _produitsDisponibles.where((p) => p.name.toLowerCase().contains(_searchQuery.toLowerCase()) || (p.reference?.toLowerCase().contains(_searchQuery.toLowerCase()) ?? false) ).toList(); } @override Widget build(BuildContext context) { final isMobile = MediaQuery.of(context).size.width < 600; return AlertDialog( title: Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.green.shade100, borderRadius: BorderRadius.circular(8), ), child: Icon(Icons.card_giftcard, color: Colors.green.shade700), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Ajouter un cadeau', style: TextStyle(fontSize: isMobile ? 16 : 18), ), Text( 'Pour: ${widget.product.name}', style: TextStyle( fontSize: isMobile ? 12 : 14, color: Colors.grey.shade600, fontWeight: FontWeight.normal, ), ), ], ), ), ], ), content: Container( width: isMobile ? double.maxFinite : 500, constraints: BoxConstraints( maxHeight: MediaQuery.of(context).size.height * 0.7, ), child: _isLoading ? const Center(child: CircularProgressIndicator()) : Column( mainAxisSize: MainAxisSize.min, children: [ // Information sur le produit principal Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.blue.shade200), ), child: Row( children: [ Icon(Icons.shopping_bag, color: Colors.blue.shade700), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Produit acheté', style: TextStyle( fontSize: 12, color: Colors.blue.shade700, fontWeight: FontWeight.bold, ), ), Text( '${widget.quantite}x ${widget.product.name}', style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, ), ), Text( 'Prix: ${NumberFormat('#,##0', 'fr_FR').format(widget.product.price)} MGA', style: TextStyle( fontSize: 12, color: Colors.grey.shade600, ), ), ], ), ), ], ), ), const SizedBox(height: 16), // Barre de recherche TextField( decoration: InputDecoration( labelText: 'Rechercher un produit cadeau', prefixIcon: Icon(Icons.search, color: Colors.green.shade600), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), filled: true, fillColor: Colors.green.shade50, ), onChanged: (value) { setState(() { _searchQuery = value; }); }, ), const SizedBox(height: 16), // Liste des produits disponibles Expanded( child: _produitsFiltres.isEmpty ? Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.card_giftcard_outlined, size: 48, color: Colors.grey.shade400, ), const SizedBox(height: 8), Text( 'Aucun produit disponible', style: TextStyle( color: Colors.grey.shade600, fontSize: 14, ), ), ], ), ) : ListView.builder( itemCount: _produitsFiltres.length, itemBuilder: (context, index) { final produit = _produitsFiltres[index]; final isSelected = _produitCadeauSelectionne?.id == produit.id; return Card( margin: const EdgeInsets.only(bottom: 8), elevation: isSelected ? 4 : 1, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), side: BorderSide( color: isSelected ? Colors.green.shade300 : Colors.grey.shade200, width: isSelected ? 2 : 1, ), ), child: ListTile( contentPadding: const EdgeInsets.all(12), leading: Container( width: 40, height: 40, decoration: BoxDecoration( color: isSelected ? Colors.green.shade100 : Colors.grey.shade100, borderRadius: BorderRadius.circular(8), ), child: Icon( Icons.card_giftcard, color: isSelected ? Colors.green.shade700 : Colors.grey.shade600, ), ), title: Text( produit.name, style: TextStyle( fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, ), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Prix normal: ${NumberFormat('#,##0', 'fr_FR').format(produit.price)} MGA', style: TextStyle( fontSize: 12, color: Colors.grey.shade600, decoration: TextDecoration.lineThrough, ), ), Row( children: [ Icon( Icons.card_giftcard, size: 14, color: Colors.green.shade600, ), const SizedBox(width: 4), Text( 'GRATUIT', style: TextStyle( fontSize: 12, color: Colors.green.shade700, fontWeight: FontWeight.bold, ), ), ], ), if (produit.stock != null) Text( 'Stock: ${produit.stock}', style: TextStyle( fontSize: 11, color: Colors.grey.shade500, ), ), ], ), trailing: isSelected ? Icon( Icons.check_circle, color: Colors.green.shade700, ) : null, onTap: () { setState(() { _produitCadeauSelectionne = produit; }); }, ), ); }, ), ), // Sélection de la quantité si un produit est sélectionné if (_produitCadeauSelectionne != null) ...[ const SizedBox(height: 16), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.green.shade200), ), child: Row( children: [ Icon(Icons.card_giftcard, color: Colors.green.shade700), const SizedBox(width: 8), Expanded( child: Text( 'Quantité de ${_produitCadeauSelectionne!.name}', style: TextStyle( fontWeight: FontWeight.w500, color: Colors.green.shade700, ), ), ), Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), border: Border.all(color: Colors.green.shade300), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon(Icons.remove, size: 16), onPressed: _quantiteCadeau > 1 ? () { setState(() { _quantiteCadeau--; }); } : null, ), Text( _quantiteCadeau.toString(), style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 14, ), ), IconButton( icon: const Icon(Icons.add, size: 16), onPressed: () { final maxStock = _produitCadeauSelectionne!.stock ?? 99; if (_quantiteCadeau < maxStock) { setState(() { _quantiteCadeau++; }); } }, ), ], ), ), ], ), ), ], ], ), ), actions: [ TextButton( onPressed: () => Get.back(), child: const Text('Annuler'), ), ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: Colors.green.shade700, foregroundColor: Colors.white, padding: EdgeInsets.symmetric( horizontal: isMobile ? 16 : 20, vertical: isMobile ? 10 : 12, ), ), icon: const Icon(Icons.card_giftcard), label: Text( isMobile ? 'Offrir' : 'Offrir le cadeau', style: TextStyle(fontSize: isMobile ? 12 : 14), ), onPressed: _produitCadeauSelectionne != null ? () { Get.back(result: { 'produit': _produitCadeauSelectionne!, 'quantite': _quantiteCadeau, }); } : null, ), ], ); } }