import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:intl/intl.dart'; import 'package:open_filex/open_filex.dart'; import '../../models/project_model.dart'; import '../../models/user_model.dart'; import '../../services/report_service.dart'; import '../../services/task_log_service.dart'; import '../../services/project_service.dart'; import '../../services/auth_service.dart'; class ReportsTab extends StatefulWidget { const ReportsTab({super.key}); @override State createState() => _ReportsTabState(); } class _ReportsTabState extends State { DateTime _startDate = DateTime.now().subtract(const Duration(days: 30)); DateTime _endDate = DateTime.now().add(const Duration(hours: 23, minutes: 59)); String? _selectedProjectId; String? _selectedUserId; bool _isGenerating = false; List _projects = []; List _users = []; @override void initState() { super.initState(); _loadFilters(); } void _loadFilters() async { final projects = await context.read().getProjects().first; final users = await context.read().getUsers().first; if (mounted) { setState(() { _projects = projects; _users = users; }); } } Future _generateReport(String type) async { if (_isGenerating) return; setState(() => _isGenerating = true); try { final logs = await context.read().getTaskLogs( from: _startDate, to: _endDate, projectId: _selectedProjectId, userId: _selectedUserId, ).first; if (logs.isEmpty) { if (mounted) ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("No data found for selected filters."))); setState(() => _isGenerating = false); return; } final reportService = context.read(); dynamic file; if (type == 'pdf') { file = await reportService.generatePDF(logs, _startDate, _endDate); } else { file = await reportService.generateExcel(logs); } if (file != null && mounted) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Report generated! Opening..."), backgroundColor: Colors.green)); await OpenFilex.open(file.path); } } catch (e) { if (mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Report generation failed: $e"))); } finally { if (mounted) setState(() => _isGenerating = false); } } @override Widget build(BuildContext context) { final DateFormat formatter = DateFormat('EEE, dd MMM yyyy'); return Scaffold( body: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Card( color: Colors.indigo, shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16))), child: Padding( padding: EdgeInsets.all(24), child: Column( children: [ Icon(Icons.bar_chart, color: Colors.white, size: 48), SizedBox(height: 16), Text( "Generate Analytics Report", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 18), ), SizedBox(height: 8), Text( "Select filters below to download your team work log report.", textAlign: TextAlign.center, style: TextStyle(color: Colors.white70, fontSize: 14), ), ], ), ), ), const SizedBox(height: 32), _buildFilterRow("Date Range", "${formatter.format(_startDate)} - ${formatter.format(_endDate)}", Icons.date_range, _pickDateRange), _buildDropdownFilter( "Project", _selectedProjectId, _projects.map((p) => DropdownMenuItem(value: p.id, child: Text(p.name))).toList(), (v) => setState(() => _selectedProjectId = v), Icons.folder_outlined, ), _buildDropdownFilter( "Team Member", _selectedUserId, _users.map((u) => DropdownMenuItem(value: u.uid, child: Text(u.name))).toList(), (v) => setState(() => _selectedUserId = v), Icons.person_outline, ), const SizedBox(height: 48), _isGenerating ? const Center(child: CircularProgressIndicator()) : Column( children: [ ElevatedButton.icon( onPressed: () => _generateReport('pdf'), icon: const Icon(Icons.picture_as_pdf), label: const Text("DOWNLOAD PDF"), style: ElevatedButton.styleFrom( backgroundColor: Colors.red.shade700, foregroundColor: Colors.white, minimumSize: const Size(double.infinity, 55), ), ), const SizedBox(height: 16), OutlinedButton.icon( onPressed: () => _generateReport('excel'), icon: const Icon(Icons.table_chart), label: const Text("DOWNLOAD EXCEL"), style: OutlinedButton.styleFrom( minimumSize: const Size(double.infinity, 55), side: const BorderSide(color: Colors.green, width: 2), foregroundColor: Colors.green.shade800, ), ), ], ), ], ), ), ); } Widget _buildFilterRow(String label, String value, IconData icon, VoidCallback onTap) { return ListTile( contentPadding: EdgeInsets.zero, leading: CircleAvatar(backgroundColor: Colors.indigo.shade50, child: Icon(icon, color: Colors.indigo, size: 20)), title: Text(label, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14)), subtitle: Text(value), trailing: const Icon(Icons.chevron_right), onTap: onTap, ); } Widget _buildDropdownFilter(String label, T value, List> items, ValueChanged onChanged, IconData icon) { return ListTile( contentPadding: EdgeInsets.zero, leading: CircleAvatar(backgroundColor: Colors.indigo.shade50, child: Icon(icon, color: Colors.indigo, size: 20)), title: Text(label, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14)), subtitle: DropdownButton( value: value, isExpanded: true, underline: const SizedBox(), hint: const Text("All"), items: [ DropdownMenuItem(value: null, child: const Text("All")), ...items, ], onChanged: (v) { if (v != null || true) onChanged(v as T); }, ), ); } void _pickDateRange() async { final range = await showDateRangePicker( context: context, firstDate: DateTime(2024), lastDate: DateTime.now(), initialDateRange: DateTimeRange(start: _startDate, end: _endDate), ); if (range != null) { setState(() { _startDate = range.start; _endDate = DateTime(range.end.year, range.end.month, range.end.day, 23, 59, 59); }); } } }