import '../widgets/divination_instruction_modal.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../services/words_repository.dart'; import '../widgets/gradient_star_badge.dart'; import 'home_search_screen.dart'; import 'houses_field_screen.dart'; import 'runes_divination_screen.dart'; import 'lenormand_divination_screen.dart'; import 'tarot_divination_screen.dart'; import 'iching_divination_screen.dart'; import 'cross_system_comparison_screen.dart'; import 'numerology_divination_screen.dart'; import 'geomancy_divination_screen.dart'; import 'ogham_divination_screen.dart'; import '../services/word_of_the_day_service.dart'; import 'word_of_the_day_screen.dart'; class DivinationHubScreen extends StatefulWidget { const DivinationHubScreen({super.key}); @override State createState() => _DivinationHubScreenState(); } class _DivinationHubScreenState extends State { final _repo = WordsRepository(); final _wordOfDayService = WordOfTheDayService(); void _openComparisonScreen() { Navigator.push( context, MaterialPageRoute( builder: (_) => CrossSystemComparisonScreen( session: _repo.currentSyncreticSession, ), ), ).then((_) => setState(() {})); } void _showNewSessionDialog() { final controller = TextEditingController(); showDialog( context: context, builder: (ctx) => AlertDialog( backgroundColor: const Color(0xFF151829), title: const Row( children: [ GradientStar(size: 20), SizedBox(width: 8), Text('Новая Сессия Дня', style: TextStyle(color: Color(0xFFFFF9C4), fontSize: 17, fontWeight: FontWeight.bold)), ], ), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Начните новую синхронистическую сессию по новой теме или вопросу. Предыдущая сессия сохранится в архиве.', style: TextStyle(color: Color(0xFF8C93B8), fontSize: 13, height: 1.4), ), const SizedBox(height: 14), TextField( controller: controller, style: const TextStyle(color: Colors.white, fontSize: 14), decoration: InputDecoration( hintText: 'Главный вопрос / тема сессии...', hintStyle: const TextStyle(color: Color(0xFF8C93B8), fontSize: 12), filled: true, fillColor: const Color(0xFF1E2238), border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: const Text('Отмена'), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFFFFD54F), foregroundColor: Colors.black, ), onPressed: () async { Navigator.pop(ctx); await _repo.startNewSyncreticSession(question: controller.text.trim()); setState(() {}); HapticFeedback.mediumImpact(); }, child: const Text('Начать'), ), ], ), ); } Widget _buildWordOfDayHeroBanner() { final now = DateTime.now(); final rec = _wordOfDayService.getRecord(now); final isTriptych = rec.isTriptychMode; final singleWord = _wordOfDayService.getWordForDate(now, phase: 'main'); final triptych = _wordOfDayService.getTriptychWordsForDate(now); final streak = _wordOfDayService.calculateStreak(); final isRevealed = isTriptych ? rec.isAnyRevealed : rec.isRevealed; final isDone = isTriptych ? rec.isDayStepCompleted : rec.isStepCompleted; String titleTag = isTriptych ? 'ТРИПТИХ СУТОК (3 СЛОВА)' : 'СЛОВО ДНЯ • КАЛЕНДАРЬ'; String subtitle; if (isTriptych) { if (rec.areAllTriptychRevealed) { subtitle = '🌅 ${triptych.morning.word.toUpperCase()} • ⚡ ${triptych.day.word.toUpperCase()} • 🌙 ${triptych.evening.word.toUpperCase()}'; } else if (rec.isAnyRevealed) { final m = rec.isMorningRevealed ? triptych.morning.word.toUpperCase() : '•••'; final d = rec.isDayRevealed ? triptych.day.word.toUpperCase() : '•••'; final e = rec.isEveningRevealed ? triptych.evening.word.toUpperCase() : '•••'; subtitle = '🌅 $m • ⚡ $d • 🌙 $e'; } else { subtitle = 'Печати суток не распечатаны'; } } else { subtitle = rec.isRevealed ? '${singleWord.word.toUpperCase()} (#${singleWord.sessionNumber})' : 'Печать не распечатана'; } String statusText; if (isDone) { statusText = 'Выполнено ✓'; } else if (isTriptych) { statusText = rec.areAllTriptychRevealed ? 'Открыты 3/3' : (rec.isAnyRevealed ? 'В процессе' : 'Триптих'); } else { statusText = rec.isRevealed ? 'В процессе' : 'Открыть'; } String descText; if (isTriptych) { if (rec.areAllTriptychRevealed) { descText = 'Утро: «${triptych.morning.asks}» | Вызов дня: «${triptych.day.step}»'; } else { descText = 'Коснитесь, чтобы распечатать три слова дня: Настройка, Действие и Тень.'; } } else { descText = rec.isRevealed ? (singleWord.asks.isNotEmpty ? '«${singleWord.asks}»' : (singleWord.oracle.isNotEmpty ? singleWord.oracle : singleWord.description)) : 'Коснитесь, чтобы узнать архетип, коан и практическое задание на сегодня.'; } return InkWell( onTap: () { Navigator.push( context, MaterialPageRoute(builder: (_) => const WordOfTheDayScreen()), ).then((_) => setState(() {})); }, borderRadius: BorderRadius.circular(20), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF2E2045), Color(0xFF14172B)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(20), border: Border.all( color: isRevealed ? const Color(0xFFFFD54F) : const Color(0xFFFFD54F).withValues(alpha: 0.5), width: isRevealed ? 1.5 : 1.0, ), boxShadow: [ BoxShadow( color: const Color(0xFFFFD54F).withValues(alpha: 0.12), blurRadius: 12, ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 38, height: 38, alignment: Alignment.center, decoration: BoxDecoration( shape: BoxShape.circle, gradient: const LinearGradient( colors: [Color(0xFFFFD54F), Color(0xFFFF8F00)], ), boxShadow: [ BoxShadow( color: const Color(0xFFFFD54F).withValues(alpha: 0.3), blurRadius: 8, ), ], ), child: Text( isTriptych ? '⏳' : (rec.isRevealed && singleWord.emoji.isNotEmpty ? singleWord.emoji : '☀️'), style: const TextStyle(fontSize: 18), ), ), const SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( titleTag, style: const TextStyle( color: Color(0xFFFFD54F), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 1.0, ), ), if (streak > 0) ...[ const SizedBox(width: 6), Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: const Color(0xFF3B2314), borderRadius: BorderRadius.circular(6), border: Border.all(color: const Color(0xFFFFB74D).withValues(alpha: 0.4)), ), child: Text( '🔥 $streak дн.', style: const TextStyle( color: Color(0xFFFFB74D), fontSize: 10, fontWeight: FontWeight.bold, ), ), ), ], ], ), const SizedBox(height: 2), Text( subtitle, style: TextStyle( color: isRevealed ? const Color(0xFFFFF9C4) : const Color(0xFF8C93B8), fontSize: isTriptych ? 12.5 : 14, fontWeight: FontWeight.bold, ), ), ], ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: isDone ? const Color(0xFF1B3D23) : (isRevealed ? const Color(0xFF2A2D4A) : const Color(0xFF332A1C)), borderRadius: BorderRadius.circular(8), border: Border.all( color: isDone ? const Color(0xFF81C784) : const Color(0xFFFFD54F).withValues(alpha: 0.4), ), ), child: Text( statusText, style: TextStyle( color: isDone ? const Color(0xFF81C784) : const Color(0xFFFFD54F), fontSize: 11, fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(height: 10), Text( descText, maxLines: 2, overflow: TextOverflow.ellipsis, style: const TextStyle(color: Color(0xFF8C93B8), fontSize: 12, height: 1.35), ), ], ), ), ); } @override Widget build(BuildContext context) { final session = _repo.currentSyncreticSession; final readingsCount = session.readings.length; return Scaffold( backgroundColor: const Color(0xFF0C0E1A), appBar: AppBar( title: const Row( children: [ GradientStar(size: 22), SizedBox(width: 8), Text('Предсказания', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)), ], ), actions: [ IconButton( tooltip: 'Начать новую тему сессии', icon: const Icon(Icons.add_circle_outline_rounded, color: Color(0xFFFFD54F)), onPressed: _showNewSessionDialog, ), IconButton( tooltip: 'Сравнительный Мета-Промпт', icon: const Icon(Icons.psychology_alt_rounded, color: Color(0xFFFFD54F)), onPressed: _openComparisonScreen, ), ], ), body: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(16, 8, 16, 24), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Word of the Day Hero Banner _buildWordOfDayHeroBanner(), const SizedBox(height: 14), // Active Day Session Banner InkWell( onTap: _openComparisonScreen, borderRadius: BorderRadius.circular(20), child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFF2A1F45), Color(0xFF151829)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(20), border: Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.5)), boxShadow: [ BoxShadow(color: const Color(0xFFFFD54F).withValues(alpha: 0.1), blurRadius: 10), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const GradientStar(size: 18), const SizedBox(width: 8), const Expanded( child: Text( 'АКТИВНАЯ СЕССИЯ ДНЯ', style: TextStyle( color: Color(0xFFFFD54F), fontSize: 11, fontWeight: FontWeight.w900, letterSpacing: 1.0, ), ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: const Color(0xFF3B2B5E), borderRadius: BorderRadius.circular(8), border: Border.all(color: const Color(0xFFFFD54F).withValues(alpha: 0.4)), ), child: Text( '$readingsCount ${readingsCount == 1 ? "гадание" : (readingsCount < 5 ? "гадания" : "гаданий")}', style: const TextStyle(color: Color(0xFFFFF9C4), fontSize: 11, fontWeight: FontWeight.bold), ), ), ], ), const SizedBox(height: 8), Text( session.mainQuestion?.isNotEmpty == true ? '«${session.mainQuestion!}»' : 'Синхронистический сосуд дня (все гадания аккумулируются здесь)', style: const TextStyle(color: Color(0xFFECEFF1), fontSize: 13.5, height: 1.4), ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( readingsCount > 0 ? 'Нажмите, чтобы сравнить системы' : 'Сделайте расклад в любой системе ниже', style: const TextStyle(color: Color(0xFF80DEEA), fontSize: 11, fontWeight: FontWeight.bold), ), const Icon(Icons.arrow_forward_ios_rounded, size: 12, color: Color(0xFFFFD54F)), ], ), ], ), ), ), const SizedBox(height: 20), // Section 1: Core 999 Systems _buildSectionHeader('СИСТЕМЫ ОРАКУЛА 999', Icons.auto_awesome_rounded), const SizedBox(height: 10), Row( children: [ Expanded( child: _buildSystemCard( title: 'Оракул', instructionId: 'cleromancy', subtitle: 'Клеромантия d10', icon: '🎲', desc: '1..10 знаков по жребию костей или прямому вводу', accentColor: const Color(0xFFFFD54F), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const HomeSearchScreen())).then((_) => setState(() {})), ), ), const SizedBox(width: 12), Expanded( child: _buildSystemCard( title: 'Матрица 33×30', instructionId: 'matrix', subtitle: '990 Домов Судьбы', icon: '🏛️', desc: 'Полотно Домов, Архонты и цепочки диспозиций', accentColor: const Color(0xFF80DEEA), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const HousesFieldScreen())).then((_) => setState(() {})), ), ), ], ), const SizedBox(height: 20), // Section 2: Classical Divination Systems _buildSectionHeader('КЛАССИЧЕСКИЕ ТРАДИЦИИ', Icons.history_edu_rounded), const SizedBox(height: 10), Row( children: [ Expanded( child: _buildSystemCard( title: 'Руны Футарка', instructionId: 'runes', subtitle: '24 Руны (2×d12)', icon: 'ᚱ', desc: 'Жребий двумя d12 либо сетка рун (прямые/перев.)', accentColor: const Color(0xFF81C784), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const RunesDivinationScreen())).then((_) => setState(() {})), ), ), const SizedBox(width: 12), Expanded( child: _buildSystemCard( title: 'Кельтский Огам', instructionId: 'ogham', subtitle: '20 Фед Рощи (d20)', icon: '᚛', desc: 'Священные деревья друидов: жребий палочек и 4 Аикмы', accentColor: const Color(0xFF66BB6A), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const OghamDivinationScreen())).then((_) => setState(() {})), ), ), ], ), const SizedBox(height: 12), Row( children: [ Expanded( child: _buildSystemCard( title: 'Таро', instructionId: 'tarot', subtitle: '22 Старших Аркана', icon: '🎴', desc: 'Жребий колоды или выбор из 22 Арканов', accentColor: const Color(0xFFBA68C8), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const TarotDivinationScreen())).then((_) => setState(() {})), ), ), const SizedBox(width: 12), Expanded( child: _buildSystemCard( title: 'Ленорман', instructionId: 'lenormand', subtitle: '36 Домов (d6+d12)', icon: '🪶', desc: 'Бросок d6+d12 со смещением или ввод 1..36', accentColor: const Color(0xFFFFB74D), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const LenormandDivinationScreen())).then((_) => setState(() {})), ), ), ], ), const SizedBox(height: 12), Row( children: [ Expanded( child: _buildSystemCard( title: 'И Цзин', instructionId: 'iching', subtitle: '3 монеты × 6', icon: '☯️', desc: 'Книга Перемен: 6 бросков монет или ввод черт', accentColor: const Color(0xFF4DD0E1), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const IChingDivinationScreen())).then((_) => setState(() {})), ), ), const SizedBox(width: 12), Expanded( child: _buildSystemCard( title: 'Геомантия', instructionId: 'geomancy', subtitle: "16 Фигур ('Илм ар-рамл)", icon: '⌛', desc: 'Земной жребий песка, Свидетели и Щит Судьбы', accentColor: const Color(0xFFFFB74D), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const GeomancyDivinationScreen())).then((_) => setState(() {})), ), ), ], ), const SizedBox(height: 12), Row( children: [ Expanded( child: _buildSystemCard( title: 'Нумерология', instructionId: 'numerology', subtitle: 'Психоматрица 3×3', icon: '🔢', desc: '4 рабочих числа, психоматрица Пифагора и Число Судьбы', accentColor: const Color(0xFFFFD54F), onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const NumerologyDivinationScreen())).then((_) => setState(() {})), ), ), ], ), ], ), ), ); } Widget _buildSectionHeader(String title, IconData icon) { return Row( children: [ Icon(icon, size: 16, color: const Color(0xFFFFD54F)), const SizedBox(width: 8), Text( title, style: const TextStyle( color: Color(0xFFFFD54F), fontSize: 11.5, fontWeight: FontWeight.w900, letterSpacing: 1.0, ), ), ], ); } Widget _buildSystemCard({ required String title, required String subtitle, required String icon, required String desc, required Color accentColor, String? instructionId, required VoidCallback onTap, }) { return InkWell( onTap: () { HapticFeedback.selectionClick(); onTap(); }, borderRadius: BorderRadius.circular(16), child: Container( padding: const EdgeInsets.all(14), decoration: BoxDecoration( color: const Color(0xFF151829), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFF2A2D4A)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( width: 36, height: 36, alignment: Alignment.center, decoration: BoxDecoration( color: const Color(0xFF232742), borderRadius: BorderRadius.circular(10), border: Border.all(color: accentColor.withValues(alpha: 0.4)), ), child: Text(icon, style: const TextStyle(fontSize: 18)), ), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 13)), Text(subtitle, style: TextStyle(color: accentColor, fontSize: 10, fontWeight: FontWeight.bold)), ], ), ), if (instructionId != null) IconButton( icon: const Icon(Icons.info_outline_rounded, size: 18, color: Color(0xFF8C93B8)), padding: EdgeInsets.zero, constraints: const BoxConstraints(), tooltip: 'Инструкция', onPressed: () => DivinationInstructionModal.show(context, instructionId), ), ], ), const SizedBox(height: 8), Text( desc, maxLines: 2, overflow: TextOverflow.ellipsis, style: const TextStyle(color: Color(0xFF8C93B8), fontSize: 11, height: 1.3), ), ], ), ), ); } }