import 'package:flutter/material.dart'; import '../models/sito.dart'; import '../services/api_service.dart'; import '../widgets/sito_card.dart'; import '../utils/constants.dart'; class SitiScreen extends StatefulWidget { const SitiScreen({super.key}); @override State createState() => _SitiScreenState(); } class _SitiScreenState extends State { final _apiService = ApiService(); List _siti = []; List _sitiFiltered = []; bool _isLoading = true; String? _errorMessage; String? _selectedTipo; final Map _tipiSito = { 'ponte': 'Ponte', 'galleria': 'Galleria', 'diga': 'Diga', 'frana': 'Frana', 'versante': 'Versante', 'edificio': 'Edificio', }; @override void initState() { super.initState(); _loadSiti(); } Future _loadSiti({bool refresh = false}) async { if (refresh) setState(() => _isLoading = true); try { final siti = await _apiService.getSiti(); setState(() { _siti = siti; _applyFilter(); _isLoading = false; _errorMessage = null; }); } catch (e) { setState(() { _errorMessage = 'Errore caricamento siti: $e'; _isLoading = false; }); } } void _applyFilter() { if (_selectedTipo == null) { _sitiFiltered = _siti; } else { _sitiFiltered = _siti.where((s) => s.tipo == _selectedTipo).toList(); } } void _showFilterDialog() { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Filtra per Tipo'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ _buildFilterOption(null, 'Tutti i siti', Icons.all_inclusive), const Divider(), ..._tipiSito.entries.map((entry) { return _buildFilterOption( entry.key, entry.value, _getIconForTipo(entry.key), ); }), ], ), ), ), ); } Widget _buildFilterOption(String? tipo, String label, IconData icon) { final isSelected = _selectedTipo == tipo; return ListTile( leading: Icon( icon, color: isSelected ? AppColors.primary : AppColors.textSecondary, ), title: Text( label, style: TextStyle( fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, color: isSelected ? AppColors.primary : null, ), ), trailing: isSelected ? const Icon(Icons.check, color: AppColors.primary) : null, onTap: () { Navigator.pop(context); setState(() { _selectedTipo = tipo; _applyFilter(); }); }, ); } IconData _getIconForTipo(String tipo) { switch (tipo) { case 'ponte': return Icons.architecture; case 'galleria': return Icons.south_west; case 'diga': return Icons.water_damage; case 'frana': return Icons.landscape; case 'versante': return Icons.terrain; case 'edificio': return Icons.business; default: return Icons.location_on; } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Siti Monitorati'), Text( _selectedTipo != null ? _tipiSito[_selectedTipo]! : '${_siti.length} siti totali', style: const TextStyle(fontSize: 12), ), ], ), actions: [ IconButton( icon: const Icon(Icons.filter_list), onPressed: _showFilterDialog, tooltip: 'Filtra per tipo', ), ], ), body: _isLoading ? const Center(child: CircularProgressIndicator()) : _errorMessage != null ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon( Icons.error_outline, size: 64, color: AppColors.critical, ), const SizedBox(height: 16), Text(_errorMessage!), const SizedBox(height: 16), ElevatedButton.icon( onPressed: () => _loadSiti(refresh: true), icon: const Icon(Icons.refresh), label: const Text('Riprova'), ), ], ), ) : _sitiFiltered.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Icon( Icons.location_off, size: 64, color: AppColors.textSecondary, ), const SizedBox(height: 16), Text( _selectedTipo != null ? 'Nessun sito di tipo ${_tipiSito[_selectedTipo]}' : 'Nessun sito disponibile', style: AppTextStyles.h3, ), ], ), ) : RefreshIndicator( onRefresh: () => _loadSiti(refresh: true), child: ListView.builder( padding: const EdgeInsets.all(AppSizes.paddingM), itemCount: _sitiFiltered.length, itemBuilder: (context, index) { return SitoCard(sito: _sitiFiltered[index]); }, ), ), floatingActionButton: _isLoading ? null : FloatingActionButton( onPressed: () => _loadSiti(refresh: true), child: const Icon(Icons.refresh), ), ); } }