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'; 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( 'Все сохранённые записи гаданий и жребиев с датами будут удалены.', ), 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 _copyEntry(HistoryEntry entry) { final text = '✨ Оракул 999 — Запись из Истории ✨\n' 'Время: ${entry.formattedDate}\n' 'Тип: ${entry.readingType}${entry.positionTitle != null ? ' (${entry.positionTitle})' : ''}\n' 'Знак №${entry.formattedSessionNumber}: ${entry.word.toUpperCase()}\n' 'Часть речи: ${entry.partOfSpeech}\n\n' '🔮 Толкование:\n${entry.symbolicMeaning}'; Clipboard.setData(ClipboardData(text: text)); 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 historyList = _repo.history; return Scaffold( appBar: AppBar( title: const Row( children: [ GradientStar(size: 24), SizedBox(width: 10), Text( 'История гаданий', style: TextStyle(fontWeight: FontWeight.w900), ), ], ), actions: [ if (historyList.isNotEmpty) IconButton( tooltip: 'Очистить историю', icon: const Icon(Icons.delete_outline_rounded), onPressed: _confirmClearHistory, ), ], ), body: historyList.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: historyList.length, separatorBuilder: (_, _) => const SizedBox(height: 10), itemBuilder: (context, index) { final item = historyList[index]; return Card( elevation: 3, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18), side: BorderSide( color: const Color(0xFFFFD54F).withValues(alpha: 0.2), ), ), color: isDark ? const Color(0xFF1B1D30) : theme.colorScheme.surface, child: Padding( padding: const EdgeInsets.all(14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Top header: Timestamp and Reading type Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ const Icon( Icons.access_time_rounded, size: 14, color: Color(0xFFFFD54F), ), const SizedBox(width: 5), Text( item.formattedDate, style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xFFFFD54F), ), ), ], ), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: const Color(0xFF2A2D4A), borderRadius: BorderRadius.circular(8), ), child: Text( item.readingType, style: const TextStyle( fontSize: 11, color: Color(0xFFFFF9C4), fontWeight: FontWeight.w600, ), ), ), ], ), if (item.positionTitle != null) ...[ const SizedBox(height: 6), Text( item.positionTitle!, style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: theme.colorScheme.primary, ), ), ], const SizedBox(height: 10), // Word row with number badge Row( children: [ GradientStarBadge( text: '#${item.formattedSessionNumber}', size: 14, ), const SizedBox(width: 10), Expanded( child: Text( item.word.toUpperCase(), style: const TextStyle( fontWeight: FontWeight.w900, fontSize: 18, letterSpacing: 0.8, ), ), ), IconButton( icon: const Icon(Icons.copy_rounded, size: 18), tooltip: 'Скопировать', onPressed: () => _copyEntry(item), ), IconButton( icon: const Icon(Icons.delete_outline, size: 18), tooltip: 'Удалить', onPressed: () async { await _repo.deleteHistoryEntry(item.id); setState(() {}); }, ), ], ), const SizedBox(height: 8), // Meaning snippet Container( width: double.infinity, padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: isDark ? const Color(0xFF131524) : theme.colorScheme.surfaceContainerLow, borderRadius: BorderRadius.circular(12), ), child: Text( item.symbolicMeaning, style: TextStyle( fontSize: 13, height: 1.4, color: isDark ? const Color(0xFFD4D6E6) : Colors.black87, ), ), ), ], ), ), ); }, ), ); } }