import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:go_router/go_router.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import '../../../../core/theme/app_theme_extension.dart'; import '../../../../core/services/auth_service.dart'; import '../../../../core/services/gamification_service.dart'; import '../../../../core/models/class_stats.dart'; import '../../../../core/models/achievement.dart'; import '../widgets/class_analytics_card.dart'; import '../widgets/class_students_inline_widget.dart'; import '../widgets/create_achievement_dialog.dart'; /// Analytics page for teachers with class breakdowns and rankings class AnalyticsPage extends StatefulWidget { const AnalyticsPage({super.key}); @override State createState() => _AnalyticsPageState(); } class _AnalyticsPageState extends State with SingleTickerProviderStateMixin { late TabController _tabController; final _classSearchController = TextEditingController(); String _classSearchQuery = ''; List _classStats = []; bool _loading = true; String? _selectedClassId; String? _selectedClassName; @override void initState() { super.initState(); _tabController = TabController(length: 2, vsync: this); _loadClassStats(); } @override void dispose() { _tabController.dispose(); _classSearchController.dispose(); super.dispose(); } Future _loadClassStats() async { try { final user = AuthService.currentUser; if (user == null) return; // Obter turmas do professor final classesSnapshot = await FirebaseFirestore.instance .collection('classes') .where('teacherId', isEqualTo: user.uid) .get(); final classStatsList = []; for (final classDoc in classesSnapshot.docs) { final classId = classDoc.id; // Forçar atualização para obter dados mais recentes final stats = await GamificationService.getClassStats( classId, forceRefresh: true, ); if (stats != null) { classStatsList.add(stats); } } if (mounted) { setState(() { _classStats = classStatsList; _loading = false; }); } } catch (e) { print('Error loading class stats: $e'); if (mounted) { setState(() { _loading = false; }); } } } @override Widget build(BuildContext context) { final themeExtras = AppThemeExtras.of(context); return PopScope( canPop: false, onPopInvoked: (didPop) { if (didPop) return; context.go('/teacher-dashboard'); }, child: Scaffold( backgroundColor: Colors.transparent, resizeToAvoidBottomInset: false, body: DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: themeExtras.dashboardBackgroundGradient, stops: themeExtras.dashboardGradientStops, ), ), child: SafeArea( top: false, bottom: false, child: Column( children: [ // Header Container( padding: const EdgeInsets.only( left: 24, right: 24, bottom: 28, top: 52, ), child: Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ IconButton( icon: const Icon( Icons.arrow_back, color: Colors.white, ), onPressed: () => context.go('/teacher-dashboard'), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Analytics', style: TextStyle( color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4), Text( 'Acompanhe o desempenho das turmas', style: TextStyle( color: Colors.white.withValues(alpha: 0.8), fontSize: 16, ), ), ], ), ), IconButton( icon: const Icon(Icons.add, color: Colors.white), onPressed: _showCreateAchievementDialog, tooltip: 'Criar Conquista', ), ], ), const SizedBox(height: 20), TabBar( controller: _tabController, labelColor: Colors.white, unselectedLabelColor: Colors.white.withValues( alpha: 0.7, ), indicatorColor: Colors.white, indicatorWeight: 2, tabs: const [ Tab(text: 'Turmas'), Tab(text: 'Alunos'), ], ), ], ), ), // Content Expanded( child: TabBarView( controller: _tabController, children: [_buildClassesTab(), _buildStudentsTab()], ), ), ], ), ), ), ), ); } Widget _buildClassesTab() { if (_loading) { return const Center( child: CircularProgressIndicator(color: Colors.white), ); } if (_classStats.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.analytics_outlined, size: 64, color: Colors.white.withValues(alpha: 0.5), ), const SizedBox(height: 16), Text( 'Nenhuma turma encontrada', style: TextStyle( color: Colors.white.withValues(alpha: 0.7), fontSize: 18, ), ), const SizedBox(height: 8), Text( 'Crie turmas para ver as analytics aqui', style: TextStyle( color: Colors.white.withValues(alpha: 0.5), fontSize: 14, ), ), ], ), ); } final filtered = _classSearchQuery.isEmpty ? _classStats : _classStats .where( (s) => s.className.toLowerCase().contains(_classSearchQuery), ) .toList(); return CustomScrollView( slivers: [ SliverPadding( padding: const EdgeInsets.fromLTRB(24, 24, 24, 0), sliver: SliverToBoxAdapter( child: Column( children: [ // Overview Cards Center( child: _buildOverviewCard( 'Total de Alunos', '${_classStats.fold(0, (sum, s) => sum + s.totalStudents)}', Icons.people, Colors.blue, ), ), const SizedBox(height: 20), // Search bar Container( padding: const EdgeInsets.symmetric( horizontal: 14, vertical: 10, ), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.white.withValues(alpha: 0.2), ), ), child: Row( children: [ Icon( Icons.search, color: Colors.white.withValues(alpha: 0.7), size: 20, ), const SizedBox(width: 10), Expanded( child: Theme( data: ThemeData.dark().copyWith( textSelectionTheme: const TextSelectionThemeData( cursorColor: Colors.white, selectionColor: Colors.white24, selectionHandleColor: Colors.white, ), ), child: TextField( controller: _classSearchController, onChanged: (v) => setState( () => _classSearchQuery = v.trim().toLowerCase(), ), style: const TextStyle( color: Colors.white, fontSize: 14, ), cursorColor: Colors.white, decoration: InputDecoration( hintText: 'Pesquisar turma…', hintStyle: TextStyle( color: Colors.white.withValues(alpha: 0.5), fontSize: 14, ), border: InputBorder.none, isDense: true, contentPadding: EdgeInsets.zero, ), ), ), ), if (_classSearchQuery.isNotEmpty) GestureDetector( onTap: () { _classSearchController.clear(); setState(() => _classSearchQuery = ''); }, child: Icon( Icons.close, color: Colors.white.withValues(alpha: 0.7), size: 18, ), ), ], ), ), const SizedBox(height: 20), ], ), ), ), if (filtered.isEmpty) SliverFillRemaining( hasScrollBody: false, child: Center( child: Text( 'Nenhuma turma encontrada', style: TextStyle( color: Colors.white.withValues(alpha: 0.6), fontSize: 15, ), ), ), ) else SliverPadding( padding: const EdgeInsets.fromLTRB(24, 0, 24, 24), sliver: SliverList( delegate: SliverChildBuilderDelegate( (context, index) => ClassAnalyticsCard( classStats: filtered[index], onTap: () => _showClassStudents(filtered[index]), ), childCount: filtered.length, ), ), ), ], ); } Widget _buildStudentsTab() { if (_selectedClassId == null) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.people_outline, size: 64, color: Colors.white.withValues(alpha: 0.5), ), const SizedBox(height: 16), Text( 'Seleciona uma turma', style: TextStyle( color: Colors.white.withValues(alpha: 0.7), fontSize: 18, ), ), const SizedBox(height: 8), Text( 'Clica numa turma no separador "Turmas" para ver os alunos', style: TextStyle( color: Colors.white.withValues(alpha: 0.5), fontSize: 14, ), textAlign: TextAlign.center, ), ], ), ); } return ClassStudentsInlineWidget( classId: _selectedClassId!, className: _selectedClassName ?? '', ); } Widget _buildOverviewCard( String title, String value, IconData icon, Color color, ) { return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16), border: Border.all(color: Colors.white.withValues(alpha: 0.2)), ), child: Column( children: [ Icon(icon, color: color, size: 32), const SizedBox(height: 12), Text( value, style: const TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4), Text( title, style: TextStyle( color: Colors.white.withValues(alpha: 0.8), fontSize: 14, ), textAlign: TextAlign.center, ), ], ), ).animate().scale(duration: 600.ms, curve: Curves.elasticOut); } void _showClassStudents(ClassStats stats) { setState(() { _selectedClassId = stats.classId; _selectedClassName = stats.className; }); _tabController.animateTo(1); } void _showCreateAchievementDialog() { showDialog( context: context, builder: (context) => CreateAchievementDialog( onAchievementCreated: (achievement) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( 'Conquista "${achievement.name}" criada com sucesso!', ), backgroundColor: Colors.green, ), ); }, ), ); } }