import 'package:flutter/material.dart'; import 'package:em2rp/models/depot_model.dart'; import 'package:em2rp/services/travel_service.dart'; import 'package:em2rp/utils/colors.dart'; import 'package:em2rp/views/widgets/inputs/address_autocomplete_field.dart'; class DepotManagement extends StatefulWidget { const DepotManagement({super.key}); @override State createState() => _DepotManagementState(); } class _DepotManagementState extends State { final _service = TravelService(); bool _isLoading = false; void _showDepotDialog({DepotModel? depot}) { final nameCtrl = TextEditingController(text: depot?.name ?? ''); final addressCtrl = TextEditingController(text: depot?.address ?? ''); final formKey = GlobalKey(); showDialog( context: context, builder: (ctx) => AlertDialog( title: Text(depot == null ? 'Ajouter un dépôt' : 'Modifier le dépôt'), content: SizedBox( width: 420, child: Form( key: formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ TextFormField( controller: nameCtrl, decoration: const InputDecoration( labelText: 'Nom du dépôt *', border: OutlineInputBorder(), prefixIcon: Icon(Icons.warehouse_outlined), hintText: 'ex: Dépôt principal', ), validator: (v) => v == null || v.trim().isEmpty ? 'Requis' : null, ), const SizedBox(height: 16), AddressAutocompleteField( controller: addressCtrl, label: 'Adresse du dépôt *', validator: (v) => v == null || v.trim().isEmpty ? 'Requis' : null, ), ], ), ), ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Annuler'), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: AppColors.rouge, foregroundColor: Colors.white, ), onPressed: () async { if (!formKey.currentState!.validate()) return; Navigator.pop(ctx); setState(() => _isLoading = true); try { if (depot == null) { await _service.addDepot(DepotModel( id: '', name: nameCtrl.text.trim(), address: addressCtrl.text.trim(), )); } else { await _service.updateDepot(depot.copyWith( name: nameCtrl.text.trim(), address: addressCtrl.text.trim(), )); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Erreur: $e'), backgroundColor: Colors.red), ); } } finally { if (mounted) setState(() => _isLoading = false); } }, child: Text(depot == null ? 'Ajouter' : 'Enregistrer'), ), ], ), ); } Future _delete(DepotModel depot) async { final confirm = await showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('Supprimer le dépôt'), content: Text('Supprimer "${depot.name}" ?'), actions: [ TextButton(onPressed: () => Navigator.pop(ctx, false), child: const Text('Annuler')), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, ), onPressed: () => Navigator.pop(ctx, true), child: const Text('Supprimer'), ), ], ), ); if (confirm == true) { setState(() => _isLoading = true); try { await _service.deleteDepot(depot.id); } finally { if (mounted) setState(() => _isLoading = false); } } } @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.warehouse_outlined, color: AppColors.rouge, size: 28), const SizedBox(width: 12), Text( 'Dépôts', style: Theme.of(context) .textTheme .headlineSmall ?.copyWith(fontWeight: FontWeight.bold), ), const Spacer(), ElevatedButton.icon( icon: const Icon(Icons.add), label: const Text('Ajouter un dépôt'), style: ElevatedButton.styleFrom( backgroundColor: AppColors.rouge, foregroundColor: Colors.white, ), onPressed: () => _showDepotDialog(), ), ], ), const SizedBox(height: 8), Text( 'Définissez les adresses de départ pour le calcul des frais de déplacement.', style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: Colors.grey[600]), ), const SizedBox(height: 24), if (_isLoading) const Center(child: CircularProgressIndicator()), Expanded( child: StreamBuilder>( stream: _service.watchDepots(), builder: (context, snap) { if (snap.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } final depots = snap.data ?? []; if (depots.isEmpty) { return Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.warehouse_outlined, size: 64, color: Colors.grey[300]), const SizedBox(height: 16), Text( 'Aucun dépôt configuré', style: Theme.of(context) .textTheme .titleMedium ?.copyWith(color: Colors.grey[500]), ), const SizedBox(height: 8), const Text('Ajoutez un dépôt pour commencer.'), ], ), ); } return ListView.separated( itemCount: depots.length, separatorBuilder: (_, __) => const Divider(height: 1), itemBuilder: (context, i) { final d = depots[i]; return ListTile( leading: CircleAvatar( backgroundColor: AppColors.rouge.withValues(alpha: 0.1), child: Icon(Icons.warehouse_outlined, color: AppColors.rouge), ), title: Text(d.name, style: const TextStyle(fontWeight: FontWeight.w600)), subtitle: Text(d.address), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon(Icons.edit_outlined), tooltip: 'Modifier', onPressed: () => _showDepotDialog(depot: d), ), IconButton( icon: const Icon(Icons.delete_outline, color: Colors.red), tooltip: 'Supprimer', onPressed: () => _delete(d), ), ], ), ); }, ); }, ), ), ], ), ); } }