// Components/RemiseDialog.dart import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:youmazgestion/Models/client.dart'; import 'package:youmazgestion/Models/produit.dart'; class RemiseDialog extends StatefulWidget { final Product product; final int quantite; final double prixUnitaire; final DetailCommande? detailExistant; const RemiseDialog({ super.key, required this.product, required this.quantite, required this.prixUnitaire, this.detailExistant, }); @override State createState() => _RemiseDialogState(); } class _RemiseDialogState extends State { final _formKey = GlobalKey(); final _valeurController = TextEditingController(); RemiseType _selectedType = RemiseType.pourcentage; double _montantRemise = 0.0; double _prixFinal = 0.0; late double _sousTotal; @override void initState() { super.initState(); _sousTotal = widget.quantite * widget.prixUnitaire; // Si on modifie une remise existante if (widget.detailExistant?.aRemise == true) { _selectedType = widget.detailExistant!.remiseType!; _valeurController.text = widget.detailExistant!.remiseValeur.toString(); _calculateRemise(); } else { _prixFinal = _sousTotal; } } void _calculateRemise() { final valeur = double.tryParse(_valeurController.text) ?? 0.0; setState(() { if (_selectedType == RemiseType.pourcentage) { final pourcentage = valeur.clamp(0.0, 100.0); _montantRemise = _sousTotal * (pourcentage / 100); } else { _montantRemise = valeur.clamp(0.0, _sousTotal); } _prixFinal = _sousTotal - _montantRemise; }); } @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.orange.shade100, borderRadius: BorderRadius.circular(8), ), child: Icon(Icons.discount, color: Colors.orange.shade700), ), const SizedBox(width: 12), Expanded( child: Text( 'Appliquer une remise', style: TextStyle(fontSize: isMobile ? 16 : 18), ), ), ], ), content: Container( width: isMobile ? double.maxFinite : 400, child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Informations du produit Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( widget.product.name, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4), Text( 'Quantité: ${widget.quantite}', style: const TextStyle(fontSize: 12), ), Text( 'Prix unitaire: ${widget.prixUnitaire.toStringAsFixed(2)} MGA', style: const TextStyle(fontSize: 12), ), Text( 'Sous-total: ${_sousTotal.toStringAsFixed(2)} MGA', style: const TextStyle( fontSize: 12, fontWeight: FontWeight.bold, ), ), ], ), ), const SizedBox(height: 16), // Type de remise const Text( 'Type de remise:', style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500), ), const SizedBox(height: 8), Row( children: [ Expanded( child: RadioListTile( title: const Text('Pourcentage (%)', style: TextStyle(fontSize: 12)), value: RemiseType.pourcentage, groupValue: _selectedType, onChanged: (value) { setState(() { _selectedType = value!; _calculateRemise(); }); }, contentPadding: EdgeInsets.zero, dense: true, ), ), Expanded( child: RadioListTile( title: const Text('Montant (MGA)', style: TextStyle(fontSize: 12)), value: RemiseType.montant, groupValue: _selectedType, onChanged: (value) { setState(() { _selectedType = value!; _calculateRemise(); }); }, contentPadding: EdgeInsets.zero, dense: true, ), ), ], ), const SizedBox(height: 16), // Valeur de la remise TextFormField( controller: _valeurController, decoration: InputDecoration( labelText: _selectedType == RemiseType.pourcentage ? 'Pourcentage (0-100)' : 'Montant en MGA', prefixIcon: Icon( _selectedType == RemiseType.pourcentage ? Icons.percent : Icons.attach_money, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), filled: true, fillColor: Colors.grey.shade50, ), keyboardType: const TextInputType.numberWithOptions(decimal: true), inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d*')), ], validator: (value) { if (value == null || value.isEmpty) { return 'Veuillez entrer une valeur'; } final valeur = double.tryParse(value); if (valeur == null || valeur < 0) { return 'Valeur invalide'; } if (_selectedType == RemiseType.pourcentage && valeur > 100) { return 'Le pourcentage ne peut pas dépasser 100%'; } if (_selectedType == RemiseType.montant && valeur > _sousTotal) { return 'La remise ne peut pas dépasser le sous-total'; } return null; }, onChanged: (value) => _calculateRemise(), ), const SizedBox(height: 16), // Aperçu du calcul Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.green.shade50, borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.green.shade200), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('Sous-total:', style: TextStyle(fontSize: 12)), Text( '${_sousTotal.toStringAsFixed(2)} MGA', style: const TextStyle(fontSize: 12), ), ], ), if (_montantRemise > 0) ...[ const SizedBox(height: 4), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Remise ${_selectedType == RemiseType.pourcentage ? "(${_valeurController.text}%)" : ""}:', style: TextStyle( fontSize: 12, color: Colors.orange.shade700, ), ), Text( '-${_montantRemise.toStringAsFixed(2)} MGA', style: TextStyle( fontSize: 12, color: Colors.orange.shade700, fontWeight: FontWeight.bold, ), ), ], ), ], const Divider(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( 'Prix final:', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, ), ), Text( '${_prixFinal.toStringAsFixed(2)} MGA', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.green.shade700, ), ), ], ), ], ), ), ], ), ), ), actions: [ if (widget.detailExistant?.aRemise == true) TextButton.icon( onPressed: () => Navigator.of(context).pop('supprimer'), icon: const Icon(Icons.delete, color: Colors.red), label: const Text('Supprimer remise', style: TextStyle(color: Colors.red)), ), TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Annuler'), ), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { final valeur = double.parse(_valeurController.text); Navigator.of(context).pop({ 'type': _selectedType, 'valeur': valeur, 'montantRemise': _montantRemise, 'prixFinal': _prixFinal, }); } }, style: ElevatedButton.styleFrom( backgroundColor: Colors.orange.shade700, foregroundColor: Colors.white, ), child: const Text('Appliquer'), ), ], ); } @override void dispose() { _valeurController.dispose(); super.dispose(); } }