import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../models/history_entry_model.dart'; import '../models/word_model.dart'; import '../services/words_repository.dart'; import '../widgets/gradient_star_badge.dart'; import '../widgets/word_card_widget.dart'; class OracleSpreadScreen extends StatefulWidget { const OracleSpreadScreen({super.key}); @override State createState() => _OracleSpreadScreenState(); } class _OracleSpreadScreenState extends State { final _repo = WordsRepository(); final _questionController = TextEditingController(); int _selectedMode = 0; // 0 = Single Card (Жребий момента), 1 = Triad (3 карты) WordItem? _singleDraw; String? _singleHistoryId; List _triadDraw = []; List _triadHistoryIds = []; bool _isGenerating = false; @override void initState() { super.initState(); _singleDraw = _repo.getRandomWord(); } @override void dispose() { _questionController.dispose(); super.dispose(); } Future _performSingleDraw({bool saveHistory = true}) async { setState(() => _isGenerating = true); HapticFeedback.mediumImpact(); await Future.delayed(const Duration(milliseconds: 200)); final word = _repo.getRandomWord(); String? histId; if (saveHistory) { histId = DateTime.now().millisecondsSinceEpoch.toString(); final question = _questionController.text.trim(); final entry = HistoryEntry( id: histId, timestamp: DateTime.now(), word: word.word, sessionNumber: word.sessionNumber, partOfSpeech: word.partOfSpeech, symbolicMeaning: word.description, readingType: 'Жребий момента (1 символ)', question: question.isNotEmpty ? question : null, ); await _repo.addHistoryEntry(entry); } setState(() { _singleDraw = word; _singleHistoryId = histId ?? _singleHistoryId; _isGenerating = false; }); } Future _performTriadDraw() async { setState(() => _isGenerating = true); HapticFeedback.heavyImpact(); await Future.delayed(const Duration(milliseconds: 250)); final words = []; final titles = [ 'Истоки / Скрытая причина', 'Настоящее / Вызов', 'Совет / Исход', ]; while (words.length < 3) { final w = _repo.getRandomWord(); if (!words.any((item) => item.id == w.id)) { words.add(w); } } final question = _questionController.text.trim(); final ids = []; for (int i = 0; i < words.length; i++) { final histId = '${DateTime.now().millisecondsSinceEpoch}_$i'; ids.add(histId); final entry = HistoryEntry( id: histId, timestamp: DateTime.now(), word: words[i].word, sessionNumber: words[i].sessionNumber, partOfSpeech: words[i].partOfSpeech, symbolicMeaning: words[i].description, readingType: 'Триада судьбы', positionTitle: titles[i], question: question.isNotEmpty ? question : null, ); await _repo.addHistoryEntry(entry); } setState(() { _triadDraw = words; _triadHistoryIds = ids; _isGenerating = false; }); } @override Widget build(BuildContext context) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; return Scaffold( appBar: AppBar( title: const Row( children: [ GradientStar(size: 24), SizedBox(width: 10), Text( 'Расклады Оракула', style: TextStyle(fontWeight: FontWeight.w900), ), ], ), ), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Question Input TextField( controller: _questionController, decoration: InputDecoration( labelText: 'Ваш вопрос к раскладу (необязательно)', hintText: 'Например: Чему учит эта ситуация?', prefixIcon: const Icon(Icons.help_outline_rounded, color: Color(0xFFFFD54F), size: 20), suffixIcon: _questionController.text.isNotEmpty ? IconButton( icon: const Icon(Icons.clear, size: 18), onPressed: () => _questionController.clear(), ) : null, filled: true, fillColor: isDark ? const Color(0xFF17192C) : theme.colorScheme.surfaceContainerHigh, border: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide( color: const Color(0xFFFFD54F).withValues(alpha: 0.25), ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide( color: const Color(0xFFFFD54F).withValues(alpha: 0.2), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: const BorderSide( color: Color(0xFFFFD54F), width: 1.5, ), ), ), ), const SizedBox(height: 12), // Mode Selector (1 символ / Триада 3 символа) Container( padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: isDark ? const Color(0xFF1B1D30) : theme.colorScheme.surfaceContainerHigh, borderRadius: BorderRadius.circular(16), border: Border.all( color: const Color(0xFFFFD54F).withValues(alpha: 0.3), ), ), child: Row( children: [ Expanded( child: InkWell( onTap: () { setState(() => _selectedMode = 0); if (_singleDraw == null) _performSingleDraw(saveHistory: false); }, borderRadius: BorderRadius.circular(12), child: Container( padding: const EdgeInsets.symmetric(vertical: 10), decoration: BoxDecoration( color: _selectedMode == 0 ? const Color(0xFF2A2D4A) : Colors.transparent, borderRadius: BorderRadius.circular(12), border: _selectedMode == 0 ? Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.5)) : null, ), alignment: Alignment.center, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const GradientStar(size: 14), const SizedBox(width: 6), Text( 'Жребий момента (1)', style: TextStyle( fontWeight: FontWeight.bold, color: _selectedMode == 0 ? const Color(0xFFFFF9C4) : theme.colorScheme.outline, ), ), ], ), ), ), ), Expanded( child: InkWell( onTap: () { setState(() => _selectedMode = 1); if (_triadDraw.isEmpty) _performTriadDraw(); }, borderRadius: BorderRadius.circular(12), child: Container( padding: const EdgeInsets.symmetric(vertical: 10), decoration: BoxDecoration( color: _selectedMode == 1 ? const Color(0xFF2A2D4A) : Colors.transparent, borderRadius: BorderRadius.circular(12), border: _selectedMode == 1 ? Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.5)) : null, ), alignment: Alignment.center, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ const GradientStar(size: 14), const SizedBox(width: 6), Text( 'Триада судьбы (3)', style: TextStyle( fontWeight: FontWeight.bold, color: _selectedMode == 1 ? const Color(0xFFFFF9C4) : theme.colorScheme.outline, ), ), ], ), ), ), ), ], ), ), const SizedBox(height: 16), // Action draw button FilledButton.icon( onPressed: _isGenerating ? null : () { if (_selectedMode == 0) { _performSingleDraw(saveHistory: true); } else { _performTriadDraw(); } }, icon: const GradientStar(size: 20), label: Text( _selectedMode == 0 ? 'БРОСИТЬ ЖРЕБИЙ МОМЕНТА' : 'РАСКРЫТЬ ТРИАДУ СУДЬБЫ', style: const TextStyle( fontWeight: FontWeight.w900, letterSpacing: 0.8, ), ), style: FilledButton.styleFrom( backgroundColor: const Color(0xFF2A2D4A), foregroundColor: const Color(0xFFFFF9C4), padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18), side: const BorderSide( color: Color(0xFFFFD54F), width: 1.2, ), ), ), ), const SizedBox(height: 20), if (_isGenerating) const Center( child: Padding( padding: EdgeInsets.all(40.0), child: Column( children: [ CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Color(0xFFFFD54F)), ), SizedBox(height: 16), Text( 'Синхронизация с полем оракула...', style: TextStyle(fontStyle: FontStyle.italic), ), ], ), ), ) else if (_selectedMode == 0 && _singleDraw != null) WordCardWidget( key: ValueKey('${_singleDraw!.id}_${_singleDraw!.sessionNumber}'), word: _singleDraw!, positionTitle: 'Символ момента', question: _questionController.text.trim(), historyEntryId: _singleHistoryId, onRandom: () => _performSingleDraw(saveHistory: true), ) else if (_selectedMode == 1 && _triadDraw.isNotEmpty) Column( children: [ WordCardWidget( key: ValueKey('triad_0_${_triadDraw[0].id}_${_triadDraw[0].sessionNumber}'), word: _triadDraw[0], positionTitle: '1. Истоки / Скрытая причина', question: _questionController.text.trim(), historyEntryId: _triadHistoryIds.isNotEmpty ? _triadHistoryIds[0] : null, ), const SizedBox(height: 14), WordCardWidget( key: ValueKey('triad_1_${_triadDraw[1].id}_${_triadDraw[1].sessionNumber}'), word: _triadDraw[1], positionTitle: '2. Настоящее / Вызов', question: _questionController.text.trim(), historyEntryId: _triadHistoryIds.length > 1 ? _triadHistoryIds[1] : null, ), const SizedBox(height: 14), WordCardWidget( key: ValueKey('triad_2_${_triadDraw[2].id}_${_triadDraw[2].sessionNumber}'), word: _triadDraw[2], positionTitle: '3. Совет / Исход', question: _questionController.text.trim(), historyEntryId: _triadHistoryIds.length > 2 ? _triadHistoryIds[2] : null, ), ], ), const SizedBox(height: 24), ], ), ), ), ); } }