import 'package:flutter/material.dart'; import '../utils/constants.dart'; import '../models/allarme.dart'; import '../services/api_service.dart'; import '../widgets/allarme_card.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { final _apiService = ApiService(); List _allarmi = []; List _allarmiFiltered = []; bool _isLoading = true; String? _errorMessage; String? _selectedSeverita; String _searchQuery = ''; String _sortBy = 'data_desc'; // data_desc, data_asc, severita @override void initState() { super.initState(); _loadAllarmi(); } Future _loadAllarmi({bool refresh = false}) async { if (refresh) setState(() => _isLoading = true); try { final response = await _apiService.getAllarmi(severita: _selectedSeverita); setState(() { _allarmi = response.items; _applyFiltersAndSort(); _isLoading = false; }); } catch (e) { setState(() { _errorMessage = 'Errore caricamento allarmi'; _isLoading = false; }); } } void _applyFiltersAndSort() { // Filtra per ricerca var filtered = _allarmi.where((allarme) { if (_searchQuery.isEmpty) return true; final query = _searchQuery.toLowerCase(); return allarme.titolo.toLowerCase().contains(query) || allarme.descrizione?.toLowerCase().contains(query) == true || allarme.tipoReadable.toLowerCase().contains(query); }).toList(); // Ordina switch (_sortBy) { case 'data_desc': filtered.sort((a, b) => b.timestampRilevamento.compareTo(a.timestampRilevamento)); break; case 'data_asc': filtered.sort((a, b) => a.timestampRilevamento.compareTo(b.timestampRilevamento)); break; case 'severita': filtered.sort((a, b) { final severityOrder = {'critical': 0, 'warning': 1, 'info': 2}; return (severityOrder[a.severita] ?? 3).compareTo(severityOrder[b.severita] ?? 3); }); break; } _allarmiFiltered = filtered; } void _showFilterDialog() { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Filtri'), content: Column( mainAxisSize: MainAxisSize.min, children: [ ListTile( title: const Text('Tutti'), leading: Radio(value: null, groupValue: _selectedSeverita, onChanged: (val) { Navigator.pop(context); setState(() => _selectedSeverita = val); _loadAllarmi(refresh: true); }), ), ListTile( title: const Text('CRITICO'), leading: Radio(value: 'critical', groupValue: _selectedSeverita, onChanged: (val) { Navigator.pop(context); setState(() => _selectedSeverita = val); _loadAllarmi(refresh: true); }), ), ListTile( title: const Text('AVVISO'), leading: Radio(value: 'warning', groupValue: _selectedSeverita, onChanged: (val) { Navigator.pop(context); setState(() => _selectedSeverita = val); _loadAllarmi(refresh: true); }), ), ], ), ), ); } void _showSortDialog() { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Ordina per'), content: Column( mainAxisSize: MainAxisSize.min, children: [ _buildSortOption('data_desc', 'Più recenti', Icons.arrow_downward), _buildSortOption('data_asc', 'Meno recenti', Icons.arrow_upward), _buildSortOption('severita', 'Severità', Icons.warning), ], ), ), ); } Widget _buildSortOption(String value, String label, IconData icon) { final isSelected = _sortBy == value; 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(() { _sortBy = value; _applyFiltersAndSort(); }); }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Column( children: [Text('ASE Monitor'), Text('Allarmi Attivi', style: TextStyle(fontSize: 12))], ), actions: [ IconButton(icon: const Icon(Icons.sort), onPressed: _showSortDialog), IconButton(icon: const Icon(Icons.filter_list), onPressed: _showFilterDialog), ], ), body: Column( children: [ // Search bar Padding( padding: const EdgeInsets.all(AppSizes.paddingM), child: TextField( decoration: InputDecoration( hintText: 'Cerca allarmi...', prefixIcon: const Icon(Icons.search), suffixIcon: _searchQuery.isNotEmpty ? IconButton( icon: const Icon(Icons.clear), onPressed: () { setState(() { _searchQuery = ''; _applyFiltersAndSort(); }); }, ) : null, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), ), filled: true, fillColor: Colors.grey[100], ), onChanged: (value) { setState(() { _searchQuery = value; _applyFiltersAndSort(); }); }, ), ), // Results count if (_searchQuery.isNotEmpty) Padding( padding: const EdgeInsets.symmetric(horizontal: AppSizes.paddingM), child: Text( '${_allarmiFiltered.length} risultati trovati', style: AppTextStyles.bodySmall.copyWith(color: AppColors.textSecondary), ), ), // List Expanded( child: _isLoading ? const Center(child: CircularProgressIndicator()) : _errorMessage != null ? Center(child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [const Icon(Icons.error_outline, size: 64, color: AppColors.critical), Text(_errorMessage!)])) : _allarmiFiltered.isEmpty ? const Center(child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [Icon(Icons.check_circle_outline, size: 64, color: AppColors.success), SizedBox(height: 16), Text('Nessun allarme', style: AppTextStyles.h3)])) : RefreshIndicator( onRefresh: () => _loadAllarmi(refresh: true), child: ListView.builder( padding: const EdgeInsets.all(AppSizes.paddingM), itemCount: _allarmiFiltered.length, itemBuilder: (context, index) => AllarmeCard(allarme: _allarmiFiltered[index]), ), ), ), ], ), floatingActionButton: FloatingActionButton( onPressed: () => _loadAllarmi(refresh: true), child: const Icon(Icons.refresh), ), ); } }