import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../models/history_entry_model.dart'; import '../services/words_repository.dart'; import '../widgets/gradient_star_badge.dart'; import 'session_result_screen.dart'; class HistoryScreen extends StatefulWidget { const HistoryScreen({super.key}); @override State createState() => _HistoryScreenState(); } class _HistoryScreenState extends State { final _repo = WordsRepository(); void _confirmClearHistory() { showDialog( context: context, builder: (ctx) => AlertDialog( title: const Row( children: [ GradientStar(size: 20), SizedBox(width: 8), Text('Очистить историю?'), ], ), content: const Text( 'Все сохранённые сессии гаданий и AI-трактовки будут удалены.', ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Отмена'), ), FilledButton( onPressed: () async { Navigator.pop(ctx); await _repo.clearHistory(); setState(() {}); HapticFeedback.mediumImpact(); }, style: FilledButton.styleFrom(backgroundColor: Colors.red.shade800), child: const Text('Очистить'), ), ], ), ); } void _copySession(OracleSession session) { final buf = StringBuffer(); buf.writeln('✨ Оракул 999 — Запись Сессии ✨'); buf.writeln('Дата: ${session.formattedDate}'); if (session.question != null && session.question!.isNotEmpty) { buf.writeln('Вопрос: «${session.question}»'); } buf.writeln('Знаков: ${session.words.length}\n'); for (int i = 0; i < session.words.length; i++) { final w = session.words[i]; buf.writeln('🔮 Знак #${w.formattedSessionNumber}: ${w.word.toUpperCase()} (${w.partOfSpeech})'); buf.writeln(' ${w.symbolicMeaning}\n'); } if (session.aiInterpretation != null && session.aiInterpretation!.isNotEmpty) { buf.writeln('🤖 AI Трактовка (G4F):'); buf.writeln(session.aiInterpretation); } Clipboard.setData(ClipboardData(text: buf.toString())); HapticFeedback.lightImpact(); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Row( children: [ GradientStar(size: 18), SizedBox(width: 10), Expanded(child: Text('Сессия скопирована в буфер обмена')), ], ), duration: const Duration(seconds: 2), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), ); } @override Widget build(BuildContext context) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; final sessionsList = _repo.sessions; return Scaffold( appBar: AppBar( title: const Row( children: [ GradientStar(size: 24), SizedBox(width: 10), Text( 'История сессий', style: TextStyle(fontWeight: FontWeight.w900), ), ], ), actions: [ if (sessionsList.isNotEmpty) IconButton( tooltip: 'Очистить историю', icon: const Icon(Icons.delete_outline_rounded), onPressed: _confirmClearHistory, ), ], ), body: sessionsList.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const GradientStar(size: 48), const SizedBox(height: 16), Text( 'История сессий пока пуста', style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), Padding( padding: const EdgeInsets.symmetric(horizontal: 32), child: Text( 'Задайте вопрос, совершите броски и откройте знаки, чтобы сохранить сессию здесь.', textAlign: TextAlign.center, style: TextStyle(color: theme.colorScheme.outline), ), ), ], ), ) : ListView.separated( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), itemCount: sessionsList.length, separatorBuilder: (_, _) => const SizedBox(height: 12), itemBuilder: (context, index) { final session = sessionsList[index]; return Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), side: BorderSide( color: const Color(0xFFFFD54F).withValues(alpha: 0.25), ), ), color: isDark ? const Color(0xFF1B1D30) : theme.colorScheme.surface, child: InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => SessionResultScreen(session: session), ), ).then((_) => setState(() {})); }, borderRadius: BorderRadius.circular(20), child: Padding( padding: const EdgeInsets.all(14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Top Header: Date, Words Count, Actions Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ const Icon( Icons.access_time_rounded, size: 14, color: Color(0xFFFFD54F), ), const SizedBox(width: 5), Text( session.formattedDate, style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xFFFFD54F), ), ), ], ), Row( children: [ Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: const Color(0xFF2A2D4A), borderRadius: BorderRadius.circular(8), border: Border.all( color: const Color(0xFFFFD54F).withValues(alpha: 0.3), ), ), child: Text( '${session.words.length} ${session.words.length == 1 ? "знак" : (session.words.length < 5 ? "знака" : "знаков")}', style: const TextStyle( fontSize: 11, color: Color(0xFFFFF9C4), fontWeight: FontWeight.bold, ), ), ), const SizedBox(width: 4), IconButton( icon: const Icon(Icons.copy_rounded, size: 16), tooltip: 'Скопировать', onPressed: () => _copySession(session), ), IconButton( icon: const Icon(Icons.delete_outline, size: 16), tooltip: 'Удалить', onPressed: () async { await _repo.deleteSession(session.id); setState(() {}); }, ), ], ), ], ), // Question Box if present if (session.question != null && session.question!.isNotEmpty) ...[ const SizedBox(height: 8), Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), decoration: BoxDecoration( color: const Color(0xFF22243C), borderRadius: BorderRadius.circular(10), ), child: Row( children: [ const Icon(Icons.help_outline_rounded, size: 14, color: Color(0xFFFFD54F)), const SizedBox(width: 6), Expanded( child: Text( 'Вопрос: «${session.question}»', style: const TextStyle( fontSize: 12.5, fontStyle: FontStyle.italic, color: Color(0xFFFFF9C4), ), ), ), ], ), ), ], const SizedBox(height: 10), // Words Chips Row Wrap( spacing: 6, runSpacing: 6, children: session.words.map((w) { return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: isDark ? const Color(0xFF131524) : theme.colorScheme.surfaceContainerLow, borderRadius: BorderRadius.circular(10), border: Border.all( color: const Color(0xFFFFD54F).withValues(alpha: 0.3), ), ), child: Text( '#${w.formattedSessionNumber} ${w.word.toUpperCase()}', style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 12, color: Color(0xFFFFD54F), ), ), ); }).toList(), ), // AI Interpretation Snippet if generated if (session.aiInterpretation != null && session.aiInterpretation!.isNotEmpty) ...[ const SizedBox(height: 10), Container( width: double.infinity, padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: const Color(0xFF261D3A), borderRadius: BorderRadius.circular(12), border: Border.all( color: const Color(0xFFBA68C8).withValues(alpha: 0.4), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Row( children: [ Icon(Icons.psychology_rounded, size: 14, color: Color(0xFFE1BEE7)), SizedBox(width: 6), Text( 'AI Трактовка (G4F)', style: TextStyle( fontSize: 11, fontWeight: FontWeight.bold, color: Color(0xFFE1BEE7), ), ), ], ), const SizedBox(height: 4), Text( session.aiInterpretation!, maxLines: 3, overflow: TextOverflow.ellipsis, style: const TextStyle( fontSize: 12, height: 1.4, color: Color(0xFFF3E5F5), ), ), ], ), ), ], ], ), ), ), ); }, ), ); } }