import 'dart:convert'; import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import '../utils/session_manager.dart'; import 'package:http/http.dart' as http; import '../utils/api_config.dart'; import 'history_detail_screen.dart'; class HistoryScreen extends StatefulWidget { const HistoryScreen({super.key}); @override State createState() => _HistoryScreenState(); } class _HistoryScreenState extends State { List _history = []; bool _isLoading = true; bool _isSelectionMode = false; final Set _selectedIds = {}; @override void initState() { super.initState(); _loadHistory(); } Future _loadHistory() async { final url = Uri.parse("${ApiConfig.baseUrl}/get_history.php?id_users=${SessionManager.userId}"); try { final response = await http.get(url); if (response.statusCode == 200) { List decodedHistory = jsonDecode(response.body); setState(() { _history = decodedHistory; _isLoading = false; }); } } catch (e) { debugPrint("Gagal memuat data riwayat dari server: $e"); setState(() { _isLoading = false; }); } } Future _clearHistory() async { final url = Uri.parse("${ApiConfig.baseUrl}/clear_history.php"); try { final response = await http.post(url, body: { 'id_users': SessionManager.userId.toString(), }); if (response.statusCode == 200) { _loadHistory(); } } catch (e) { debugPrint("Gagal menghapus data riwayat di server: $e"); } } Future _deleteHistoryItem(dynamic id) async { final url = Uri.parse("${ApiConfig.baseUrl}/delete_history_item.php"); try { final response = await http.post(url, body: { 'id': id.toString(), }); if (response.statusCode == 200) { _loadHistory(); } } catch (e) { debugPrint("Gagal menghapus item riwayat: $e"); } } Future _deleteSelectedItems() async { if (_selectedIds.isEmpty) return; final url = Uri.parse("${ApiConfig.baseUrl}/delete_history_item.php"); try { // Loop delete sequentially for now as the API expects single ID // Alternatively, update API to accept multiple IDs for (var id in _selectedIds) { await http.post(url, body: { 'id': id.toString(), }); } setState(() { _selectedIds.clear(); _isSelectionMode = false; }); _loadHistory(); } catch (e) { debugPrint("Gagal menghapus beberapa item riwayat: $e"); } } String _formatDuration(dynamic seconds) { if (seconds == null) return "-"; int secs = int.tryParse(seconds.toString()) ?? 0; if (secs <= 0) return "0 mnt"; int m = secs ~/ 60; if (m >= 60) { int h = m ~/ 60; int remainingM = m % 60; return "$h jam $remainingM mnt"; } return "$m mnt"; } @override Widget build(BuildContext context) { return Scaffold( extendBodyBehindAppBar: true, appBar: AppBar( automaticallyImplyLeading: !_isSelectionMode, title: Text(_isSelectionMode ? "${_selectedIds.length} Terpilih" : "Riwayat Gowes", style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), centerTitle: true, backgroundColor: _isSelectionMode ? Colors.redAccent.withOpacity(0.8) : Colors.transparent, elevation: 0, leading: _isSelectionMode ? IconButton( icon: const Icon(Icons.close, color: Colors.white), onPressed: () { setState(() { _isSelectionMode = false; _selectedIds.clear(); }); }, ) : null, actions: [ if (_history.isNotEmpty) _isSelectionMode ? IconButton( icon: const Icon(Icons.delete, color: Colors.white), onPressed: _selectedIds.isEmpty ? null : () => _confirmDeleteSelected(), ) : IconButton( icon: const Icon(Icons.delete_outline, color: Colors.white70), onPressed: () { setState(() { _isSelectionMode = true; }); }, ) ], ), body: Container( decoration: const BoxDecoration( gradient: LinearGradient( colors: [Color(0xFF1A237E), Color(0xFF121212)], begin: Alignment.topCenter, end: Alignment.bottomCenter, ), ), child: SafeArea( child: _isLoading ? const Center(child: CircularProgressIndicator(color: Colors.blueAccent)) : _history.isEmpty ? _buildEmptyState() : ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), itemCount: _history.length, itemBuilder: (context, index) { final item = _history[index]; return _buildHistoryCard(item); }, ), ), ), ); } Widget _buildEmptyState() { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.history_toggle_off, size: 80, color: Colors.white.withOpacity(0.2)), const SizedBox(height: 20), Text( "Belum ada riwayat rute", style: TextStyle(color: Colors.white.withOpacity(0.5), fontSize: 18), ), ], ), ); } Widget _buildHistoryCard(dynamic item) { DateTime date = DateTime.parse(item['tanggal']); String formattedDate = DateFormat('dd MMM yyyy, HH:mm').format(date); String statusText = item['status'].toString().toUpperCase(); if (statusText == "0") statusText = "GAGAL"; bool isSuccess = statusText == "BERHASIL"; bool isSelected = _selectedIds.contains(item['id']); return GestureDetector( onTap: () { if (_isSelectionMode) { setState(() { if (isSelected) { _selectedIds.remove(item['id']); } else { _selectedIds.add(item['id']); } }); } else { Navigator.push( context, MaterialPageRoute( builder: (context) => HistoryDetailScreen(historyItem: item), ), ); } }, onLongPress: () { if (!_isSelectionMode) { setState(() { _isSelectionMode = true; _selectedIds.add(item['id']); }); } }, child: Container( margin: const EdgeInsets.only(bottom: 16), child: ClipRRect( borderRadius: BorderRadius.circular(20), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: isSelected ? Colors.blueAccent.withOpacity(0.15) : Colors.white.withOpacity(0.05), borderRadius: BorderRadius.circular(20), border: Border.all(color: isSelected ? Colors.blueAccent : Colors.white.withOpacity(0.1), width: isSelected ? 2 : 1), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( item['nama_rute'], style: const TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold), overflow: TextOverflow.ellipsis, ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: isSuccess ? Colors.green.withOpacity(0.2) : Colors.red.withOpacity(0.2), borderRadius: BorderRadius.circular(10), border: Border.all(color: isSuccess ? Colors.green : Colors.red, width: 0.5), ), child: Text( statusText, style: TextStyle( color: isSuccess ? Colors.greenAccent : Colors.redAccent, fontSize: 10, fontWeight: FontWeight.bold, ), ), ), if (_isSelectionMode) Icon( isSelected ? Icons.check_circle : Icons.radio_button_unchecked, color: isSelected ? Colors.blueAccent : Colors.white38, size: 24, ), ], ), const SizedBox(height: 12), Row( children: [ _buildInfoMini(Icons.calendar_today, formattedDate), ], ), const SizedBox(height: 16), Divider(color: Colors.white.withOpacity(0.05)), const SizedBox(height: 8), Row( children: [ Expanded(child: _buildStatDetail(Icons.straighten, "${item['jarak_tempuh'] ?? item['jarak']} KM", "JARAK")), Expanded(child: _buildStatDetail(Icons.timer, _formatDuration(item['waktu_tempuh']), "WAKTU")), Expanded(child: _buildStatDetail(Icons.speed, "${item['kecepatan_rata_rata'] ?? '-'} km/j", "SPEED")), Expanded(child: _buildStatDetail( isSuccess ? Icons.check_circle : Icons.cancel, isSuccess ? "Berhasil" : "Gagal", "MISI" )), ], ), ], ), ), ), ), ), ); } Widget _buildInfoMini(IconData icon, String text) { return Row( children: [ Icon(icon, color: Colors.white54, size: 14), const SizedBox(width: 8), Text(text, style: const TextStyle(color: Colors.white54, fontSize: 12)), ], ); } Widget _buildStatDetail(IconData icon, String value, String label) { return Column( children: [ Icon(icon, color: Colors.blueAccent, size: 20), const SizedBox(height: 6), Text(value, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w600, fontSize: 14)), Text(label, style: const TextStyle(color: Colors.white38, fontSize: 10, fontWeight: FontWeight.bold)), ], ); } void _confirmDeleteSelected() { showDialog( context: context, builder: (context) => AlertDialog( backgroundColor: const Color(0xFF1E2140), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), title: const Text("Hapus Riwayat", style: TextStyle(color: Colors.white)), content: Text("Anda yakin ingin menghapus ${_selectedIds.length} riwayat rute yang dipilih?", style: const TextStyle(color: Colors.white70)), actions: [ TextButton(onPressed: () => Navigator.pop(context), child: const Text("BATAL", style: TextStyle(color: Colors.white54))), TextButton( onPressed: () { Navigator.pop(context); _deleteSelectedItems(); }, child: const Text("HAPUS", style: TextStyle(color: Colors.redAccent)) ), ], ), ); } }