import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import '../../../../core/services/gamification_service.dart'; import '../../../../core/models/achievement.dart'; /// Dialog for creating custom achievements class CreateAchievementDialog extends StatefulWidget { final Function(Achievement) onAchievementCreated; const CreateAchievementDialog({ super.key, required this.onAchievementCreated, }); @override State createState() => _CreateAchievementDialogState(); } class _CreateAchievementDialogState extends State { final _formKey = GlobalKey(); final _nameController = TextEditingController(); final _descriptionController = TextEditingController(); final _valueController = TextEditingController(); String _selectedCategory = 'quiz'; String _selectedRequirementType = 'quiz_completion'; String _selectedOperator = '>='; String _selectedIcon = 'star'; String _selectedRarity = 'common'; int _points = 10; final List _categories = [ 'quiz', 'study_time', 'streak', 'concept', 'general', ]; final List _requirementTypes = [ 'quiz_completion', 'quiz_score', 'study_time', 'streak_days', 'concepts_mastered', ]; final List _operators = ['>=', '==', '>']; final List _icons = [ 'star', 'emoji_events', 'school', 'local_fire_department', 'schedule', 'trending_up', 'military_tech', 'workspace_premium', 'psychology', 'lightbulb', ]; final List _rarities = [ 'common', 'rare', 'epic', 'legendary', ]; final Map _rarityPoints = { 'common': 10, 'rare': 25, 'epic': 50, 'legendary': 100, }; @override void dispose() { _nameController.dispose(); _descriptionController.dispose(); _valueController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final cs = Theme.of(context).colorScheme; return Dialog( backgroundColor: cs.surface, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), child: Container( width: MediaQuery.of(context).size.width * 0.8, constraints: BoxConstraints( maxHeight: MediaQuery.of(context).size.height * 0.75, minWidth: 280, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Header Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: LinearGradient( colors: [cs.primary, cs.primary.withValues(alpha: 0.8)], ), borderRadius: const BorderRadius.only( topLeft: Radius.circular(16), topRight: Radius.circular(16), ), ), child: Row( children: [ const Icon(Icons.emoji_events, color: Colors.white, size: 28), const SizedBox(width: 12), const Expanded( child: Text( 'Criar Nova Conquista', style: TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold, ), ), ), IconButton( icon: const Icon(Icons.close, color: Colors.white), onPressed: () => Navigator.of(context).pop(), ), ], ), ), // Form Expanded( child: Form( key: _formKey, child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Basic Info _buildSectionTitle('Informações Básicas'), const SizedBox(height: 16), _buildTextField( controller: _nameController, label: 'Nome da Conquista', hint: 'Ex: Mestre dos Quizzes', validator: (value) { if (value == null || value.isEmpty) { return 'Campo obrigatório'; } return null; }, ), const SizedBox(height: 16), _buildTextField( controller: _descriptionController, label: 'Descrição', hint: 'Ex: Complete 10 quizzes com 100% de acerto', maxLines: 2, validator: (value) { if (value == null || value.isEmpty) { return 'Campo obrigatório'; } return null; }, ), const SizedBox(height: 16), Row( children: [ Expanded( child: _buildDropdownField( label: 'Categoria', value: _selectedCategory, items: _categories, onChanged: (value) { setState(() { _selectedCategory = value!; }); }, ), ), const SizedBox(width: 16), Expanded( child: _buildDropdownField( label: 'Ícone', value: _selectedIcon, items: _icons, onChanged: (value) { setState(() { _selectedIcon = value!; }); }, ), ), ], ), const SizedBox(height: 16), // Requirements _buildSectionTitle('Requisitos'), const SizedBox(height: 16), Row( children: [ Expanded( child: _buildDropdownField( label: 'Tipo de Requisito', value: _selectedRequirementType, items: _requirementTypes, onChanged: (value) { setState(() { _selectedRequirementType = value!; }); }, ), ), const SizedBox(width: 16), Expanded( child: _buildDropdownField( label: 'Operador', value: _selectedOperator, items: _operators, onChanged: (value) { setState(() { _selectedOperator = value!; }); }, ), ), ], ), const SizedBox(height: 16), _buildTextField( controller: _valueController, label: 'Valor', hint: 'Ex: 10', keyboardType: TextInputType.number, validator: (value) { if (value == null || value.isEmpty) { return 'Campo obrigatório'; } if (int.tryParse(value) == null) { return 'Digite um número válido'; } return null; }, ), const SizedBox(height: 16), // Reward _buildSectionTitle('Recompensa'), const SizedBox(height: 16), Row( children: [ Expanded( child: _buildDropdownField( label: 'Raridade', value: _selectedRarity, items: _rarities, onChanged: (value) { setState(() { _selectedRarity = value!; _points = _rarityPoints[value]!; }); }, ), ), const SizedBox(width: 16), Expanded( child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: cs.primaryContainer, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Pontos', style: TextStyle( color: cs.onPrimaryContainer, fontSize: 12, ), ), const SizedBox(height: 4), Text( '$_points', style: TextStyle( color: cs.onPrimaryContainer, fontSize: 20, fontWeight: FontWeight.bold, ), ), ], ), ), ), ], ), const SizedBox(height: 16), // Preview _buildSectionTitle('Preview'), const SizedBox(height: 16), _buildAchievementPreview(), ], ), ), ), ), // Actions Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: cs.surfaceContainerHighest, borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20), ), ), child: Row( children: [ Expanded( child: OutlinedButton( onPressed: () => Navigator.of(context).pop(), style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 12), side: BorderSide(color: cs.outline), ), child: Text('Cancelar', style: TextStyle(color: cs.onSurface)), ), ), const SizedBox(width: 12), Expanded( child: ElevatedButton( onPressed: _createAchievement, style: ElevatedButton.styleFrom( backgroundColor: cs.primary, foregroundColor: cs.onPrimary, padding: const EdgeInsets.symmetric(vertical: 12), ), child: const Text('Criar Conquista'), ), ), ], ), ), ], ), ), ); } Widget _buildSectionTitle(String title) { final cs = Theme.of(context).colorScheme; return Text( title, style: TextStyle( color: cs.onSurface, fontSize: 16, fontWeight: FontWeight.bold, ), ); } Widget _buildTextField({ required TextEditingController controller, required String label, required String hint, int maxLines = 1, TextInputType? keyboardType, String? Function(String?)? validator, }) { final cs = Theme.of(context).colorScheme; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: TextStyle( color: cs.onSurface, fontSize: 14, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), TextFormField( controller: controller, decoration: InputDecoration( hintText: hint, hintStyle: TextStyle(color: cs.onSurfaceVariant), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: cs.outline), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: cs.outline), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: cs.primary, width: 2), ), contentPadding: const EdgeInsets.all(16), ), maxLines: maxLines, keyboardType: keyboardType, validator: validator, ), ], ); } Widget _buildDropdownField({ required String label, required T value, required List items, required Function(T?) onChanged, }) { final cs = Theme.of(context).colorScheme; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: TextStyle( color: cs.onSurface, fontSize: 14, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), DropdownButtonFormField( isExpanded: true, value: value, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: cs.outline), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: cs.outline), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: cs.primary, width: 2), ), contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), ), items: items.map((item) { return DropdownMenuItem( value: item, child: Text( item.toString().split('_').map((word) => word[0].toUpperCase() + word.substring(1) ).join(' '), style: const TextStyle(fontSize: 12), overflow: TextOverflow.ellipsis, ), ); }).toList(), onChanged: onChanged, ), ], ); } Widget _buildAchievementPreview() { final cs = Theme.of(context).colorScheme; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: LinearGradient( colors: [ cs.primary.withValues(alpha: 0.1), cs.primary.withValues(alpha: 0.05), ], ), borderRadius: BorderRadius.circular(16), border: Border.all(color: cs.primary.withValues(alpha: 0.3)), ), child: Row( children: [ Container( width: 48, height: 48, decoration: BoxDecoration( color: _getRarityColor().withValues(alpha: 0.2), borderRadius: BorderRadius.circular(24), border: Border.all(color: _getRarityColor().withValues(alpha: 0.5)), ), child: Icon( _getIconData(), color: _getRarityColor(), size: 24, ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _nameController.text.isEmpty ? 'Nome da Conquista' : _nameController.text, style: TextStyle( color: cs.onSurface, fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 4), Text( _descriptionController.text.isEmpty ? 'Descrição da conquista' : _descriptionController.text, style: TextStyle( color: cs.onSurfaceVariant, fontSize: 12, ), ), ], ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: _getRarityColor().withValues(alpha: 0.2), borderRadius: BorderRadius.circular(8), ), child: Text( '$_points pts', style: TextStyle( color: _getRarityColor(), fontSize: 12, fontWeight: FontWeight.bold, ), ), ), ], ), ); } IconData _getIconData() { switch (_selectedIcon) { case 'emoji_events': return Icons.emoji_events; case 'school': return Icons.school; case 'local_fire_department': return Icons.local_fire_department; case 'schedule': return Icons.schedule; case 'trending_up': return Icons.trending_up; case 'military_tech': return Icons.military_tech; case 'workspace_premium': return Icons.workspace_premium; case 'psychology': return Icons.psychology; case 'lightbulb': return Icons.lightbulb; default: return Icons.star; } } Color _getRarityColor() { switch (_selectedRarity) { case 'common': return Colors.grey; case 'rare': return Colors.blue; case 'epic': return Colors.purple; case 'legendary': return Colors.orange; default: return Colors.grey; } } Future _createAchievement() async { if (!_formKey.currentState!.validate()) return; try { final user = FirebaseAuth.instance.currentUser; if (user == null) return; final achievement = Achievement( id: '', // Will be generated by Firestore name: _nameController.text, description: _descriptionController.text, icon: _selectedIcon, category: _selectedCategory, requirements: AchievementRequirement( type: _selectedRequirementType, value: int.parse(_valueController.text), operator: _selectedOperator, ), points: _points, rarity: _selectedRarity, isActive: true, createdAt: DateTime.now(), createdBy: user.uid, ); final achievementId = await GamificationService.createCustomAchievement( teacherId: user.uid, name: achievement.name, description: achievement.description, icon: achievement.icon, category: achievement.category, requirements: achievement.requirements, points: achievement.points, rarity: achievement.rarity, ); final createdAchievement = achievement.copyWith(id: achievementId); widget.onAchievementCreated(createdAchievement); Navigator.of(context).pop(); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Erro ao criar conquista: $e'), backgroundColor: Colors.red, ), ); } } }