// lib/screens/daily_quiz_screen.dart import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:provider/provider.dart'; import 'package:intl/intl.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:math'; import 'package:kzeduca_app/services/i18n_service.dart'; import 'package:kzeduca_app/services/firebase_service.dart'; import 'package:kzeduca_app/models/app_models.dart'; class DailyQuizScreen extends StatefulWidget { final FinancialChallenge dailyChallenge; const DailyQuizScreen({super.key, required this.dailyChallenge}); @override State createState() => _DailyQuizScreenState(); } class _DailyQuizScreenState extends State { List _questions = []; bool _isLoading = true; String _error = ''; int _currentQuestionIndex = 0; int _score = 0; String? _selectedOption; bool _showAnswerFeedback = false; bool _quizFinished = false; @override void initState() { super.initState(); _loadDailyQuizQuestions(); } Future _loadDailyQuizQuestions() async { final firebaseService = Provider.of(context, listen: false); setState(() { _isLoading = true; }); try { final querySnapshot = await firebaseService.firestore .collection('artifacts') .doc('default-kzeduca-app') .collection('public') .doc('data') .collection('quizQuestions') .get(); final allQuestions = querySnapshot.docs.map((doc) => QuizQuestion.fromFirestore(doc)).toList(); if (allQuestions.length < 10) { throw Exception('Não há perguntas suficientes para o quiz diário.'); } allQuestions.shuffle(); _questions = allQuestions.take(10).toList(); } catch (e) { setState(() { _error = "Erro ao carregar o quiz diário: $e"; }); } finally { if (mounted) { setState(() { _isLoading = false; }); } } } void _showAlertDialog(String message, {bool isError = false}) { final i18n = Provider.of(context, listen: false); showDialog( context: context, builder: (ctx) => AlertDialog( title: Text(isError ? i18n.t('error_prefix') : 'Info'), content: Text(message), actions: [ TextButton( child: const Text('Ok'), onPressed: () { Navigator.of(ctx).pop(); }, ) ], ), ); } Future _handleAnswer(String option) async { if (_showAnswerFeedback) return; setState(() { _selectedOption = option; _showAnswerFeedback = true; if (option == _questions[_currentQuestionIndex].answer) { _score++; } }); await Future.delayed(const Duration(seconds: 2)); if (mounted) { _handleNextQuestion(); } } Future _handleNextQuestion() async { setState(() { _selectedOption = null; _showAnswerFeedback = false; }); if (_currentQuestionIndex < _questions.length - 1) { setState(() { _currentQuestionIndex++; }); } else { await _saveDailyQuizResult(); setState(() { _quizFinished = true; }); } } Future _saveDailyQuizResult() async { final i18n = Provider.of(context, listen: false); final firebaseService = Provider.of(context, listen: false); final userId = FirebaseAuth.instance.currentUser?.uid; if (userId == null) { _showAlertDialog(i18n.t('quiz_save_error'), isError: true); return; } try { await firebaseService.saveQuizResult(userId, { 'score': _score, 'totalQuestions': _questions.length, 'timestamp': DateTime.now().toIso8601String(), 'isDailyQuiz': true, // Marcar como quiz diário }); final prefs = await SharedPreferences.getInstance(); await prefs.setString('daily_quiz_completion_date', DateFormat('yyyy-MM-dd').format(DateTime.now())); final double scorePercentage = _score / _questions.length; if (scorePercentage >= 0.8) { _showBonusChallengeDialog(); } _showAlertDialog(i18n.t('quiz_saved')); } catch (e) { _showAlertDialog(i18n.t('quiz_save_error'), isError: true); } } void _showBonusChallengeDialog() { final i18n = Provider.of(context, listen: false); showDialog( context: context, builder: (ctx) => AlertDialog( title: Text(i18n.t('bonus_daily_challenge'), style: TextStyle(color: Colors.amber)), content: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Parabéns, você acertou ${_score} de 10 perguntas e desbloqueou um desafio bônus!'), SizedBox(height: 10), Text(widget.dailyChallenge.nome, style: TextStyle(fontWeight: FontWeight.bold)), Text(widget.dailyChallenge.meta), ], ), actions: [ TextButton( onPressed: () => Navigator.of(ctx).pop(), child: const Text('OK'), ), ], ), ); } @override Widget build(BuildContext context) { final i18n = Provider.of(context); return Scaffold( extendBodyBehindAppBar: true, appBar: AppBar( title: Text('Quiz Diário'), backgroundColor: Colors.purple[900]?.withOpacity(0.5), foregroundColor: Colors.white, elevation: 0, ), body: Stack( children: [ Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/quiz_background.png'), fit: BoxFit.cover, ), ), ), Center( child: SingleChildScrollView( padding: const EdgeInsets.all(16.0), child: Container( padding: const EdgeInsets.all(32.0), decoration: BoxDecoration( color: Colors.black.withOpacity(0.7), borderRadius: BorderRadius.circular(24.0), border: Border.all(color: Colors.white.withOpacity(0.2)), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.5), blurRadius: 32, offset: const Offset(0, 8), ), ], ), constraints: const BoxConstraints(maxWidth: 600), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ if (_isLoading) const Center(child: CircularProgressIndicator()) else if (_questions.isEmpty) Text( 'Não foi possível carregar o quiz diário.', style: TextStyle(color: Colors.white.withOpacity(0.8)), textAlign: TextAlign.center, ) else if (!_quizFinished) Column( children: [ LinearProgressIndicator( value: (_currentQuestionIndex + 1) / _questions.length, backgroundColor: Colors.white.withOpacity(0.3), color: Colors.teal[400], minHeight: 10, borderRadius: BorderRadius.circular(5), ), const SizedBox(height: 16), Text( 'Questão ${_currentQuestionIndex + 1} de ${_questions.length}', style: TextStyle(fontSize: 14, color: Colors.white.withOpacity(0.6)), textAlign: TextAlign.center, ), const SizedBox(height: 16), Text( _questions[_currentQuestionIndex].question, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white), textAlign: TextAlign.center, ), const SizedBox(height: 24), ..._questions[_currentQuestionIndex].options.map((option) { bool isCorrect = option == _questions[_currentQuestionIndex].answer; bool isSelected = option == _selectedOption; return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: ElevatedButton( onPressed: _showAnswerFeedback ? null : () => _handleAnswer(option), style: ElevatedButton.styleFrom( backgroundColor: _showAnswerFeedback ? (isCorrect ? Colors.green[500] : Colors.red[500]) : Colors.black.withOpacity(0.4), foregroundColor: Colors.white, side: BorderSide( color: _showAnswerFeedback ? (isCorrect ? Colors.green[400]! : Colors.red[400]!) : Colors.white.withOpacity(0.3), width: 1, ), padding: const EdgeInsets.all(16), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), elevation: isSelected ? 4 : 2, ), child: Align( alignment: Alignment.centerLeft, child: Text(option, style: const TextStyle(fontSize: 16)), ), ), ); }), if (_showAnswerFeedback) ...[ const SizedBox(height: 16), Card( elevation: 4, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), color: _selectedOption == _questions[_currentQuestionIndex].answer ? Colors.green[900]?.withOpacity(0.6) : Colors.red[900]?.withOpacity(0.6), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _selectedOption == _questions[_currentQuestionIndex].answer ? i18n.t('correct') : i18n.t('incorrect'), style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 8), Text( _questions[_currentQuestionIndex].explanation, style: TextStyle(fontSize: 16, color: Colors.white.withOpacity(0.9)), ), ], ), ), ), ], const SizedBox(height: 24), ElevatedButton.icon( onPressed: _showAnswerFeedback ? _handleNextQuestion : null, icon: Icon(_currentQuestionIndex < _questions.length - 1 ? Icons.arrow_forward : Icons.bar_chart), label: Text( _currentQuestionIndex < _questions.length - 1 ? i18n.t('next_question') : i18n.t('view_results'), ), style: ElevatedButton.styleFrom( backgroundColor: Colors.blue[500], foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), elevation: 8, shadowColor: Colors.blue[300]?.withOpacity(0.5), ), ), ], ) else if (_quizFinished) Column( children: [ Icon(Icons.emoji_events, size: 80, color: Colors.amber[600]), const SizedBox(height: 16), Text( 'Quiz Diário Concluído!', style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white), textAlign: TextAlign.center, ), const SizedBox(height: 10), Text( 'Você acertou ${_score} de ${_questions.length} perguntas!', style: TextStyle(fontSize: 20, color: Colors.teal[300], fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), const SizedBox(height: 24), ElevatedButton.icon( onPressed: () { Navigator.of(context).pop(); }, icon: const Icon(Icons.arrow_back), label: const Text('Voltar para o Quiz Normal'), style: ElevatedButton.styleFrom( backgroundColor: Colors.teal[500], foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 30), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), elevation: 8, ), ), ], ), ], ), ), ), ), ], ), ); } }