import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:random_avatar/random_avatar.dart'; import '../../../../core/theme/app_theme.dart'; import '../../../../core/widgets/game_ui.dart'; import '../../../auth/presentation/bloc/auth_bloc.dart'; import '../../../auth/presentation/bloc/auth_event.dart'; import '../../domain/entities/wallet_entity.dart'; import '../bloc/daily_status.dart'; import '../bloc/wallet_bloc.dart'; import '../bloc/wallet_event.dart'; import '../bloc/wallet_state.dart'; import '../bloc/wallet_status.dart'; import '../widgets/coin_fly.dart'; import '../widgets/streak_dialog.dart'; /// لابی اصلی: کیف‌پول، دکمه بازی/دورهمی/فروشگاه/سکه روزانه. class LobbyScreen extends StatefulWidget { const LobbyScreen({super.key}); @override State createState() => _LobbyScreenState(); } class _LobbyScreenState extends State { final _coinKey = GlobalKey(); // چیپِ سکه (مقصدِ پروازِ سکه‌ها) final _dailyKey = GlobalKey(); // کارتِ هدیه‌ی روزانه (مبدأ) @override void initState() { super.initState(); context.read().add(LoadWalletEvent()); } void _reload() => context.read().add(LoadWalletEvent()); Offset? _center(GlobalKey k) { final box = k.currentContext?.findRenderObject() as RenderBox?; if (box == null || !box.attached) return null; return box.localToGlobal(box.size.center(Offset.zero)); } void _flyCoins() { final from = _center(_dailyKey); final to = _center(_coinKey); if (from != null && to != null && mounted) { CoinFly.play(context, from: from, to: to); } } @override Widget build(BuildContext context) { return Scaffold( body: GameBackground( child: BlocConsumer( listenWhen: (a, b) => a.dailyStatus != b.dailyStatus, listener: (context, state) { final d = state.dailyStatus; if (d is DailySuccess) { _flyCoins(); // پروازِ سکه‌ها از کارتِ هدیه به چیپِ سکه ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('سکه روزانه دریافت شد: +${d.amount}')), ); } else if (d is DailyError) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(d.message))); } }, builder: (context, state) { final st = state.walletStatus; final wallet = st is WalletLoaded ? st.wallet : null; return SafeArea( child: Column( children: [ _TopBar( wallet: wallet, coinKey: _coinKey, onCoinTap: () => _openShop(context)), Expanded( child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(16, 6, 16, 8), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const SizedBox(height: 6), const _LobbyHeader(), const SizedBox(height: 18), // اکشنِ اصلی: بازیِ سریع. _PrimaryPlay( onTap: () async { await context.push('/game/tiers'); if (context.mounted) _reload(); }, ), const SizedBox(height: 14), // اکشن‌های ثانویه در گریدِ دوستونه. GridView.count( crossAxisCount: 2, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), mainAxisSpacing: 12, crossAxisSpacing: 12, childAspectRatio: 1.55, children: [ _ActionTile( icon: Icons.group_add, label: 'دورهمی', sub: 'بازی با دوستان', accent: AppColors.accent, onTap: () async { await context.push('/private'); if (context.mounted) _reload(); }, ), _ActionTile( icon: Icons.emoji_events, label: 'تورنومنت', sub: 'جایزه بگیر', accent: const Color(0xFF9B7BE0), onTap: () async { await context.push('/tournaments'); if (context.mounted) _reload(); }, ), _ActionTile( icon: Icons.leaderboard, label: 'رتبه‌بندی', sub: 'جدول قهرمانان', accent: AppColors.gold, onTap: () => context.push('/leaderboard'), ), _ActionTile( icon: Icons.storefront, label: 'فروشگاه', sub: 'سکه و آیتم', accent: AppColors.success, onTap: () => _openShop(context), ), ], ), const SizedBox(height: 14), _DailyCard( key: _dailyKey, wallet: wallet, onTap: () => StreakDialog.show( context, streak: wallet?.dailyStreak ?? 0, best: wallet?.bestStreak ?? 0, ready: wallet?.dailyReady ?? true, nextReward: wallet?.nextDaily ?? 200, onClaim: () => context.read().add( ClaimDailyEvent(), ), ), ), ], ), ), ), TextButton.icon( onPressed: () { context.read().add(LogoutEvent()); context.go('/login'); }, icon: const Icon( Icons.logout, color: Colors.white38, size: 18, ), label: const Text( 'خروج از حساب', style: TextStyle(color: Colors.white38, fontSize: 13), ), ), ], ), ); }, ), ), ); } Future _openShop(BuildContext context) async { await context.push('/shop'); if (context.mounted) _reload(); } } /// عنوانِ لابی: تاجِ طلایی + نامِ بازی + زیرعنوان. class _LobbyHeader extends StatelessWidget { const _LobbyHeader(); @override Widget build(BuildContext context) { return Column( children: const [ Icon(Icons.workspace_premium, color: AppColors.gold, size: 34), SizedBox(height: 4), GlowText('حاکم ایرانی', size: 36), SizedBox(height: 2), Text( 'بازیِ آنلاینِ حکم', style: TextStyle(color: Colors.white54, fontSize: 13), ), ], ); } } /// اکشنِ اصلی: بازیِ سریع (میزِ عمومی) — کارتِ بزرگِ برجسته. class _PrimaryPlay extends StatelessWidget { final VoidCallback onTap; const _PrimaryPlay({required this.onTap}); @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: Container( padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 18), decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [AppColors.lapis, AppColors.lapisHi, AppColors.lapisLo], ), borderRadius: BorderRadius.circular(20), border: Border.all(color: AppColors.gold, width: 2), boxShadow: [ BoxShadow( color: AppColors.gold.withValues(alpha: 0.28), blurRadius: 16, ), const BoxShadow( color: Colors.black54, blurRadius: 10, offset: Offset(0, 5), ), ], ), child: Row( children: [ Container( width: 54, height: 54, decoration: const BoxDecoration( gradient: LinearGradient( colors: [AppColors.gold, AppColors.goldDark], ), shape: BoxShape.circle, ), child: const Icon( Icons.play_arrow_rounded, color: AppColors.lapisInk, size: 36, ), ), const SizedBox(width: 14), Column( crossAxisAlignment: CrossAxisAlignment.start, children: const [ Text( 'بازی سریع', style: TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold, ), ), SizedBox(height: 2), Text( 'ورود به میزِ عمومی', style: TextStyle(color: Colors.white70, fontSize: 13), ), ], ), const Spacer(), const Icon( Icons.arrow_forward_ios, color: AppColors.gold, size: 18, ), ], ), ), ); } } /// کاشیِ اکشنِ ثانویه در گرید (آیکن + عنوان + زیرعنوان). class _ActionTile extends StatelessWidget { final IconData icon; final String label; final String sub; final Color accent; final VoidCallback onTap; const _ActionTile({ required this.icon, required this.label, required this.sub, required this.accent, required this.onTap, }); @override Widget build(BuildContext context) { return Material( color: Colors.transparent, borderRadius: BorderRadius.circular(18), child: InkWell( borderRadius: BorderRadius.circular(18), onTap: onTap, child: Ink( padding: const EdgeInsets.all(14), decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [AppColors.lapisHi, AppColors.lapisLo], ), borderRadius: BorderRadius.circular(18), border: Border.all(color: AppColors.goldDark, width: 1.2), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(9), decoration: BoxDecoration( color: accent.withValues(alpha: 0.18), shape: BoxShape.circle, border: Border.all(color: accent.withValues(alpha: 0.6)), ), child: Icon(icon, color: accent, size: 22), ), const Spacer(), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( label, style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 2), Text( sub, style: const TextStyle(color: Colors.white54, fontSize: 11), ), ], ), ], ), ), ), ); } } /// کارتِ هدیه‌ی روزانه با استریک (مثلِ دولینگو): شعله + تعدادِ روزهای پیاپی و /// وضعیتِ قابلِ‌دریافت/دریافت‌شده. class _DailyCard extends StatelessWidget { final WalletEntity? wallet; final VoidCallback onTap; const _DailyCard({super.key, required this.wallet, required this.onTap}); @override Widget build(BuildContext context) { final w = wallet; final streak = w?.dailyStreak ?? 0; final ready = w?.dailyReady ?? true; final next = w?.nextDaily ?? 200; final colors = ready ? const [AppColors.success, AppColors.successDark] : const [AppColors.lapisHi, AppColors.lapisLo]; return Opacity( opacity: ready ? 1 : 0.75, child: Material( color: Colors.transparent, borderRadius: BorderRadius.circular(16), child: InkWell( borderRadius: BorderRadius.circular(16), onTap: onTap, // همیشه دیالوگِ استریک را باز می‌کند child: Ink( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 13), decoration: BoxDecoration( gradient: LinearGradient(colors: colors), borderRadius: BorderRadius.circular(16), border: Border.all(color: AppColors.gold, width: 1.4), ), child: Row( children: [ // شعله‌ی استریک با عددِ روز. Stack( alignment: Alignment.center, children: [ Icon( Icons.local_fire_department, color: streak > 0 ? const Color(0xFFFF7A1A) : Colors.white54, size: 40, ), if (streak > 0) Padding( padding: const EdgeInsets.only(top: 6), child: Text( '$streak', style: const TextStyle( color: Colors.white, fontSize: 13, fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(width: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'هدیه‌ی روزانه', style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), Text( streak > 0 ? '$streak روز پیاپی 🔥' : 'زنجیره‌ات رو شروع کن!', style: const TextStyle( color: Colors.white70, fontSize: 12, ), ), ], ), const Spacer(), if (ready) Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Row( mainAxisSize: MainAxisSize.min, children: [ const Icon( Icons.monetization_on, color: AppColors.gold, size: 16, ), const SizedBox(width: 3), Text( '+$next', style: const TextStyle( color: AppColors.gold, fontWeight: FontWeight.bold, ), ), ], ), const Text( 'دریافت', style: TextStyle(color: Colors.white70, fontSize: 11), ), ], ) else const Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.check_circle, color: AppColors.gold, size: 18), SizedBox(width: 4), Text( 'امروز گرفتی', style: TextStyle(color: Colors.white70, fontSize: 12), ), ], ), ], ), ), ), ), ); } } class _TopBar extends StatelessWidget { final WalletEntity? wallet; final VoidCallback onCoinTap; final Key? coinKey; const _TopBar({required this.wallet, required this.onCoinTap, this.coinKey}); @override Widget build(BuildContext context) { final w = wallet; return Container( margin: const EdgeInsets.all(8), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), decoration: BoxDecoration( gradient: const LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [AppColors.bg, AppColors.bgDark], ), borderRadius: BorderRadius.circular(16), border: Border.all(color: AppColors.goldDark), boxShadow: const [BoxShadow(color: Colors.black54, blurRadius: 8)], ), child: Row( children: [ GestureDetector( onTap: () async { await context.push('/profile'); if (context.mounted) { context.read().add(LoadWalletEvent()); } }, child: Container( width: 48, height: 48, padding: const EdgeInsets.all(2), decoration: BoxDecoration( shape: BoxShape.circle, color: AppColors.panel, border: Border.all(color: AppColors.gold, width: 2), ), child: (w == null || w.avatar.isEmpty) ? const Icon(Icons.person, color: AppColors.gold) : ClipOval(child: RandomAvatar(w.avatar)), ), ), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Row( children: [ if (w != null && w.name.isNotEmpty) ...[ Text( w.name, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, ), ), const SizedBox(width: 6), ], if (w?.vip == true) const _VipTag(), ], ), const SizedBox(height: 2), Row( children: [ const Icon(Icons.star, color: AppColors.gold, size: 16), const SizedBox(width: 4), Text( 'سطح ${w?.level ?? '-'}', style: const TextStyle( color: AppColors.gold, fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 4), ClipRRect( borderRadius: BorderRadius.circular(4), child: SizedBox( width: 96, height: 7, child: LinearProgressIndicator( value: (w == null || w.xpForNext == 0) ? 0 : w.xpIntoLevel / w.xpForNext, backgroundColor: Colors.white10, valueColor: const AlwaysStoppedAnimation(AppColors.gold), ), ), ), ], ), const Spacer(), GestureDetector( onTap: onCoinTap, child: StatChip( icon: Icons.confirmation_number, value: '${w?.tickets ?? 0}', ), ), const SizedBox(width: 8), GestureDetector( key: coinKey, onTap: onCoinTap, child: StatChip( icon: Icons.monetization_on, value: '${w?.coins ?? 0}', ), ), ], ), ); } } class _VipTag extends StatelessWidget { const _VipTag(); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 1), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFFFFD54F), AppColors.goldDark], ), borderRadius: BorderRadius.circular(6), ), child: const Text( 'VIP', style: TextStyle( color: AppColors.bg, fontWeight: FontWeight.bold, fontSize: 10, ), ), ); } }