import 'dart:math'; import 'package:flutter/material.dart'; import 'quiz_question_screen.dart'; import 'quiz_result.dart'; class QuizRandomScreen extends StatefulWidget { const QuizRandomScreen({super.key, this.currentScore = 0, this.scopeId}); final int currentScore; final String? scopeId; @override State createState() => _QuizRandomScreenState(); } class _QuizRandomScreenState extends State { final List _allQuestions = [ QuizQuestion( id: 1, title: 'Quiz 1/26', question: 'Qual das seguintes imagens se assemelha à face do seu filho/a?', answerType: QuizAnswerType.image, answers: const [ QuizAnswer( //1.jpeg title: 'Opção A', description: 'Selecione se a imagem se assemelha à face do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/1.jpeg', ), QuizAnswer( //2.jpeg title: 'Opção B', description: 'Selecione se a imagem se assemelha à face do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/2.jpeg', ), QuizAnswer( //3.jpeg title: 'Opção C', description: 'Selecione se a imagem se assemelha à face do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/3.jpeg', ), ], ), QuizQuestion( id: 2, title: 'Quiz 2/26', question: 'Qual das seguintes imagens se assemelha à posição boca do seu filho/a habitualmente?', answerType: QuizAnswerType.image, answers: const [ QuizAnswer( //4.jpeg title: 'Opção A', description: 'Selecione se a imagem se assemelha à boca do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/4.jpeg', ), QuizAnswer( //5.png title: 'Opção B', description: 'Selecione se a imagem se assemelha à boca do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/5.png', ), ], ), QuizQuestion( id: 3, title: 'Quiz 3/26', question: 'Qual das seguintes imagens se assemelha às olheiras do seu filho/a?', answerType: QuizAnswerType.image, answers: const [ QuizAnswer( //8.jpeg title: 'Opção A', description: 'Selecione se a imagem se assemelha às olheiras do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/8.jpeg', ), QuizAnswer( //9.png title: 'Opção B', description: 'Selecione se a imagem se assemelha às olheiras do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/9.png', ), ], ), QuizQuestion( id: 4, title: 'Quiz 4/26', question: 'Qual das seguintes imagens se assemelha ao queixo do seu filho/a com a boca fechada?', answerType: QuizAnswerType.image, answers: const [ QuizAnswer( //6.jpeg title: 'Opção A', description: 'Selecione se a imagem se assemelha ao queixo do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/6.jpeg', ), QuizAnswer( //7.png title: 'Opção B', description: 'Selecione se a imagem se assemelha ao queixo do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/7.png', ), ], ), QuizQuestion( id: 6, title: 'Quiz 6/26', question: 'Qual das seguintes imagens se assemelha à boca do seu filho/a?', answerType: QuizAnswerType.image, answers: const [ QuizAnswer( //14.jpeg title: 'Opção A', description: 'Selecione se a imagem se assemelha à boca do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/14.jpeg', ), QuizAnswer( //15.png title: 'Opção B', description: 'Selecione se a imagem se assemelha à boca do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/15.png', ), QuizAnswer( //16.png title: 'Opção C', description: 'Selecione se a imagem se assemelha à boca do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/16.png', ), ], ), QuizQuestion( id: 7, title: 'Quiz 7/26', question: 'Qual das seguintes imagens se assemelha à boca do seu filho/a?', answerType: QuizAnswerType.image, answers: const [ QuizAnswer( //10.png title: 'Opção A', description: 'Selecione se a imagem se assemelha à boca do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/10.png', ), QuizAnswer( //11.png title: 'Opção B', description: 'Selecione se a imagem se assemelha à boca do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/11.png', ), QuizAnswer( //13.png title: 'Opção C', description: 'Selecione se a imagem se assemelha à boca do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/13.png', ), ], ), QuizQuestion( id: 8, title: 'Quiz 8/26', question: 'Qual das seguintes imagens se assemelha ao freio do seu filho/a?', answerType: QuizAnswerType.image, answers: const [ QuizAnswer( //17.png title: 'Opção A', description: 'Selecione se a imagem se assemelha ao freio do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/17.png', ), QuizAnswer( //18.jpeg title: 'Opção B', description: 'Selecione se a imagem se assemelha ao freio do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/18.jpeg', ), ], ), QuizQuestion( id: 8, title: 'Quiz 8/26', question: 'Qual das seguintes imagens se assemelha ao freio do seu filho/a?', answerType: QuizAnswerType.image, answers: const [ QuizAnswer( //19.jpeg title: 'Opção A', description: 'Selecione se a imagem se assemelha ao freio do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/19.jpeg', ), QuizAnswer( //20.png title: 'Opção B', description: 'Selecione se a imagem se assemelha ao freio do seu filho/a', weight: 2, imagePath: 'assets/mockup_images/20.png', ), ], ), QuizQuestion( id: 9, title: 'Quiz 9/26', question: 'O seu filho/a tem problemas respiratórios diagnosticados?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Problemas respiratórios diagnosticados', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Sem problemas respiratórios diagnosticados', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 10, title: 'Quiz 10/26', question: 'O seu filho/a respira habitualmente pela boca?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Respira habitualmente pela boca', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não respira habitualmente pela boca', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 11, title: 'Quiz 11/26', question: 'O seu filho/a ressona habitualmente durante a noite?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Ressonar habitualmente durante a noite', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não ressona habitualmente', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 12, title: 'Quiz 12/26', question: 'O seu filho/a sente habitualmente o nariz "tapado"?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Sente habitualmente o nariz tapado', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não sente habitualmente o nariz tapado', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 13, title: 'Quiz 13/26', question: 'Durante o sono, o seu filho/a tem habitualmente interrupções da respiração?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Tem habitualmente interrupções da respiração durante o sono', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não tem interrupções da respiração durante o sono', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 14, title: 'Quiz 14/26', question: 'O seu filho/a range os dentes com frequência?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Range os dentes com frequência', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não range os dentes com frequência', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 15, title: 'Quiz 15/26', question: 'O seu filho/a habitualmente tem alergias sazonais?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Habitualmente tem alergias sazonais', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não tem alergias sazonais', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 16, title: 'Quiz 16/26', question: 'O seu filho/a acorda com saliva seca na cara ou na almofada?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Acorda com saliva seca na cara ou na almofada', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não acorda com saliva seca', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 17, title: 'Quiz 17/26', question: 'O seu filho/a teve ou costuma ter com frequência otites?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Teve ou costuma ter com frequência otites', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não teve ou não costuma ter otites', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 18, title: 'Quiz 18/26', question: 'O seu filho/a teve ou costuma ter com frequência amigdalites?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Teve ou costuma ter com frequência amigdalites', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não teve ou não costuma ter amigdalites', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 19, title: 'Quiz 19/26', question: 'O seu filho/a teve ou costuma ter com frequência bronquiolites?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Teve ou costuma ter com frequência bronquiolites', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não teve ou não costuma ter bronquiolites', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 20, title: 'Quiz 20/26', question: 'O seu filho/a apresenta dificuldades a mastigar?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Apresenta dificuldades a mastigar', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não apresenta dificuldades a mastigar', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 21, title: 'Quiz 21/26', question: 'O seu filho/a habitualmente é lento a comer?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Habitualmente é lento a comer', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não é lento a comer', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 22, title: 'Quiz 22/26', question: 'O seu filho/a habitualmente prefere comer alimentos moles?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Habitualmente prefere comer alimentos moles', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não prefere alimentos moles', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 23, title: 'Quiz 23/26', question: 'Em bebé apenas foi alimentado por biberão?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Em bebé apenas foi alimentado por biberão', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não foi apenas alimentado por biberão', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 24, title: 'Quiz 24/26', question: 'O seu filho/a usa ou usou chupeta com frequência?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Usa ou usou chupeta com frequência', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não usa ou não usou chupeta com frequência', weight: 1, value: 'nao', ), ], ), QuizQuestion( id: 25, title: 'Quiz 25/26', question: 'O seu filho/a chucha ou já chuchou o dedo com frequência?', answerType: QuizAnswerType.yesNo, answers: const [ QuizAnswer( title: 'Sim', description: 'Chucha ou já chuchou o dedo com frequência', weight: 2, value: 'sim', ), QuizAnswer( title: 'Não', description: 'Não chucha ou não chuchou o dedo com frequência', weight: 1, value: 'nao', ), ], ), ]; late List _shuffledQuestions; int _currentQuestionIndex = 0; int _currentScore = 0; final Random _random = Random(); @override void initState() { super.initState(); _currentScore = widget.currentScore; _shuffledQuestions = List.from(_allQuestions)..shuffle(_random); } void _nextQuestion(int scoreToAdd) { setState(() { _currentScore += scoreToAdd; _currentQuestionIndex++; }); if (_currentQuestionIndex >= _shuffledQuestions.length) { // Quiz finished Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (_) => QuizResultScreen( finalScore: _currentScore, maxScore: 75, // 15 questions * 5 max points scopeId: widget.scopeId, ), ), ); } } @override Widget build(BuildContext context) { if (_currentQuestionIndex >= _shuffledQuestions.length) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } final currentQuestion = _shuffledQuestions[_currentQuestionIndex]; final isLastQuestion = _currentQuestionIndex == _shuffledQuestions.length - 1; return QuizQuestionScreen( title: currentQuestion.title, question: currentQuestion.question, answers: currentQuestion.answers, currentScore: _currentScore, nextRoute: (context, nextScore) { _nextQuestion(nextScore - _currentScore); return MaterialPageRoute(builder: (_) => const SizedBox.shrink()); }, isFinal: isLastQuestion, showBackButton: _currentQuestionIndex > 0, answerType: currentQuestion.answerType, questionImagePaths: currentQuestion.questionImagePaths, onFinished: isLastQuestion ? () { Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (_) => QuizResultScreen( finalScore: _currentScore, maxScore: 75, scopeId: widget.scopeId, ), ), ); } : null, ); } } class QuizQuestion { final int id; final String title; final String question; final List answers; final QuizAnswerType answerType; // Reference images shown ABOVE the question text (visualization only). final List questionImagePaths; QuizQuestion({ required this.id, required this.title, required this.question, required this.answers, this.answerType = QuizAnswerType.text, this.questionImagePaths = const [], }); } // Helper: returns the asset path for a numbered mockup image (0..27). // Use in QuizAnswer.imagePath or QuizQuestion.questionImagePaths. String mockup(int n) => 'assets/mockup_images/$n${_mockupExt[n] ?? '.png'}'; const Map _mockupExt = { 0: '.png', 1: '.jpeg', 2: '.jpeg', 3: '.jpeg', 4: '.jpeg', 5: '.png', 6: '.jpeg', 7: '.png', 8: '.jpeg', 9: '.png', 10: '.png', 11: '.png', 12: '.png', 13: '.png', 14: '.jpeg', 15: '.png', 16: '.png', 17: '.png', 18: '.jpeg', 19: '.jpeg', 20: '.png', 21: '.jpeg', 22: '.png', 23: '.jpeg', 24: '.png', 25: '.jpg', 26: '.png', 27: '.png', };