import 'dart:async';

import 'package:flame/game.dart';
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/locator/locator.dart';
import '../../../../core/network/ws_client.dart';
import '../../../../core/service/app_sounds.dart';
import '../../../../core/theme/app_theme.dart';
import '../../../tournament/data/data_source/remote/tournament_api_provider.dart';
import '../../../tournament/domain/entities/tournament.dart';
import '../../../wallet/presentation/bloc/wallet_bloc.dart';
import '../../../wallet/presentation/bloc/wallet_event.dart';
import '../../../wallet/presentation/bloc/wallet_state.dart';
import '../../../wallet/presentation/bloc/wallet_status.dart';
import '../../domain/entities/game_entities.dart';
import '../bloc/game_bloc.dart';
import '../bloc/game_state.dart';
import '../../../chat/presentation/widgets/chat_panel.dart';
import '../widgets/flame/hokm_game.dart';
import '../widgets/table_hud.dart';

/// صفحه‌ی میز بازی: صحنه‌ی Flame + اوورلی‌های وضعیت.
class GameScreen extends StatefulWidget {
  final int prize;
  const GameScreen({super.key, this.prize = 0});

  @override
  State<GameScreen> createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  late final HokmGame _game;
  String _carpet = 'classic'; // فرشِ انتخابی (برای پس‌زمینه‌ی پشتِ صحنه)
  Timer? _introTimer;
  bool _introHidden = false;
  int _countdown = 0; // شمارشِ معکوسِ شروعِ بازی پس از یافتنِ حریفان (۳…۲…۱)
  Tournament? _tournament; // تورنومنتِ فعالِ ثبت‌نام‌شده (اگر باشد) — برای نشانِ درون‌بازی

  @override
  void initState() {
    super.initState();
    final ws = context.read<WalletBloc>().state.walletStatus;
    final skin = ws is WalletLoaded ? ws.wallet.selectedCard : 'simple';
    _carpet = ws is WalletLoaded ? ws.wallet.selectedCarpet : 'classic';
    _game = HokmGame(
      context.read<GameBloc>(),
      skin: skin.isEmpty ? 'simple' : skin,
      carpet: _carpet.isEmpty ? 'classic' : _carpet,
    );
    _loadTournament();
  }

  /// بررسی می‌کند آیا کاربر در تورنومنتِ فعالی ثبت‌نام کرده تا نشانِ درون‌بازی و
  /// امتیازِ پایانِ بازی نمایش داده شود (این بازیِ عمومی به تورنومنت امتیاز می‌دهد).
  Future<void> _loadTournament() async {
    try {
      final list = await locator<TournamentApiProvider>().getTournaments();
      final active = list.where((t) => t.joined && t.isActive).toList();
      if (mounted && active.isNotEmpty) {
        setState(() => _tournament = active.first);
      }
    } catch (_) {/* بی‌اهمیت */}
  }

  @override
  void dispose() {
    _introTimer?.cancel();
    super.dispose();
  }

  bool _showSearch(GameUiState s) => s.state == null || !_introHidden;

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      onPopInvokedWithResult: (didPop, _) {
        if (!didPop) _confirmLeave(context);
      },
      child: SafeArea(
        top: false,
        child: Scaffold(
          body: BlocConsumer<GameBloc, GameUiState>(
            listenWhen:
                (a, b) =>
                    (a.notice != b.notice && b.notice != null) ||
                    (a.gameOver == null && b.gameOver != null),
            listener: (context, state) {
              if (state.gameOver != null) {
                final won =
                    state.gameOver!.winnerTeam ==
                    (state.state?.yourSeat ?? 0) % 2;
                if (won) AppSounds.win();
              }
              if (state.notice != null) {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(
                    content: Text(state.notice!),
                    duration: const Duration(seconds: 2),
                  ),
                );
                context.read<GameBloc>().clearNotice();
                // خطا پیش از شروعِ بازی (مثلاً سکه‌ی ناکافی) ⇒ کاربر در دیالوگِ
                // «جستجوی حریف» گیر نکند؛ به لابی برگردد.
                if (state.state == null && state.gameOver == null) {
                  _exitToLobby(context);
                }
              }
            },
            builder: (context, state) {
              if (state.state != null && _introTimer == null) {
                // حریفان پیدا شدند ⇒ شمارشِ معکوسِ ۳…۲…۱ با صدا تا کاربر بداند
                // بازی در حالِ شروع است، سپس اوورلی کنار می‌رود و بُر زدن اجرا می‌شود.
                _countdown = 3; // داخلِ build هستیم؛ همین build مقدار را نشان می‌دهد
                AppSounds.tick();
                _introTimer = Timer.periodic(const Duration(seconds: 1), (t) {
                  if (!mounted) {
                    t.cancel();
                    return;
                  }
                  if (_countdown <= 1) {
                    t.cancel();
                    setState(() => _introHidden = true);
                    _game.endIntro();
                  } else {
                    setState(() => _countdown--);
                    AppSounds.tick();
                  }
                });
              }
              return Stack(
                children: [
                  // فرش به‌عنوانِ سطحِ میز داخلِ صحنه‌ی Flame (Felt) کشیده می‌شود.
                  GameWidget(game: _game),
                  if (!_showSearch(state) && state.state != null)
                    TableHud(
                      s: state.state!,
                      connection: state.connection,
                      chatBubbles: state.chatBubbles,
                      onExit: () => _confirmLeave(context),
                      onChat: () => _openChat(context),
                    ),
                  if (state.connection == WsStatus.disconnected) _connBanner(),
                  if (_tournament != null && !_showSearch(state))
                    _tournamentBadge(),
                  if (_showSearch(state)) _searchPanel(state),
                  // دیالوگِ انتخابِ حکم و بنرِ نوبت فقط پس از پایانِ انیمیشنِ
                  // پخشِ کارت نمایش داده می‌شوند (نه وسطِ بُر زدن/پخش).
                  if (!_showSearch(state))
                    ValueListenableBuilder<bool>(
                      valueListenable: _game.animating,
                      builder: (context, animating, _) {
                        if (animating) return const SizedBox.shrink();
                        return Stack(
                          children: [
                            if (_showTrumpPicker(state)) _trumpPicker(context),
                            if (_isMyPlayTurn(state)) _turnBanner(),
                          ],
                        );
                      },
                    ),
                  if (state.handResult != null && state.gameOver == null)
                    _handResult(state),
                  if (state.gameOver != null) _gameOver(context, state),
                ],
              );
            },
          ),
        ),
      ),
    );
  }

  void _openChat(BuildContext context) {
    final bloc = context.read<GameBloc>();
    final wallet = context.read<WalletBloc>();
    ChatPanel.show(
      context,
      onText: bloc.sendChatText,
      onEmoji: bloc.sendChatEmoji,
      onWalletChanged: () => wallet.add(LoadWalletEvent()),
    );
  }

  bool _isMyPlayTurn(GameUiState s) =>
      s.state != null &&
      s.gameOver == null &&
      s.state!.phase == 'playing' &&
      s.state!.isMyTurn &&
      !s.state!.trickDone;

  // بنرِ «نوبت شماست» وقتی کاربر باید کارت بیندازد.
  Widget _turnBanner() => Align(
    alignment: const Alignment(0, 0.3),
    child: IgnorePointer(
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 8),
        decoration: BoxDecoration(
          gradient: const LinearGradient(
            colors: [AppColors.gold, AppColors.goldDark],
          ),
          borderRadius: BorderRadius.circular(20),
          boxShadow: const [BoxShadow(color: Colors.black54, blurRadius: 8)],
        ),
        child: const Text(
          'نوبت شماست',
          style: TextStyle(
            color: AppColors.bg,
            fontWeight: FontWeight.bold,
            fontSize: 16,
          ),
        ),
      ),
    ),
  );

  bool _showTrumpPicker(GameUiState s) =>
      s.state != null &&
      s.state!.phase == 'choose_trump' &&
      s.state!.amHakem &&
      s.gameOver == null;

  Future<void> _confirmLeave(BuildContext context) async {
    if (context.read<GameBloc>().state.gameOver != null) {
      _exitToLobby(context);
      return;
    }
    final yes = await showDialog<bool>(
      context: context,
      builder:
          (_) => AlertDialog(
            backgroundColor: AppColors.panel,
            title: const Text('خروج از میز'),
            content: const Text(
              'از میز خارج می‌شوید؟ ورودی بازگردانده نمی‌شود.',
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context, false),
                child: const Text('ماندن'),
              ),
              TextButton(
                onPressed: () => Navigator.pop(context, true),
                child: const Text('خروج'),
              ),
            ],
          ),
    );
    if (yes == true && context.mounted) {
      context.read<GameBloc>().leave();
      _exitToLobby(context);
    }
  }

  void _exitToLobby(BuildContext context) {
    _game.silence(); // پس از خروج، صدای کارت‌های بات پخش نشود
    context.read<WalletBloc>().add(LoadWalletEvent());
    context.go('/lobby');
  }

  Widget _connBanner() => Positioned(
    top: 0,
    left: 0,
    right: 0,
    child: Material(
      color: Colors.orange.shade900,
      child: const SafeArea(
        bottom: false,
        child: Padding(
          padding: EdgeInsets.all(8),
          child: Text(
            'ارتباط با سرور قطع شد، در حال تلاش برای اتصال مجدد…',
            textAlign: TextAlign.center,
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    ),
  );

  Widget _searchPanel(GameUiState state) {
    final players = state.state?.players ?? const <GamePlayer>[];
    final mySeat = state.state?.yourSeat ?? -1;
    final searching = state.state == null;
    GamePlayer? at(int seat) {
      for (final p in players) {
        if (p.seat == seat) return p;
      }
      return null;
    }

    return Container(
      color: Colors.black.withValues(alpha: 0.78),
      alignment: Alignment.center,
      child: Container(
        margin: const EdgeInsets.symmetric(horizontal: 20),
        padding: const EdgeInsets.fromLTRB(16, 14, 16, 18),
        decoration: BoxDecoration(
          color: AppColors.panel,
          borderRadius: BorderRadius.circular(20),
          border: Border.all(color: AppColors.gold, width: 2.5),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text(
              'جستجوی حریف',
              style: TextStyle(
                color: AppColors.gold,
                fontSize: 22,
                fontWeight: FontWeight.bold,
              ),
            ),
            const SizedBox(height: 18),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                for (var seat = 0; seat < 4; seat++)
                  _searchSlot(at(seat), seat == mySeat, seat),
              ],
            ),
            if (searching) ...[
              const SizedBox(height: 16),
              const Text(
                'در حال یافتن حریفان…',
                style: TextStyle(color: Colors.white70, fontSize: 13),
              ),
            ] else if (_countdown > 0) ...[
              const SizedBox(height: 14),
              const Text(
                'شروع بازی',
                style: TextStyle(color: Colors.white70, fontSize: 13),
              ),
              const SizedBox(height: 6),
              TweenAnimationBuilder<double>(
                // هر عدد با یک «پاپ» ظاهر می‌شود تا واضح و جلب‌توجه باشد.
                key: ValueKey(_countdown),
                tween: Tween(begin: 1.6, end: 1.0),
                duration: const Duration(milliseconds: 400),
                curve: Curves.easeOut,
                builder: (_, scale, child) =>
                    Transform.scale(scale: scale, child: child),
                child: Container(
                  width: 54,
                  height: 54,
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    gradient: const LinearGradient(
                      colors: [AppColors.gold, AppColors.goldDark],
                    ),
                    border: Border.all(color: Colors.white, width: 2),
                  ),
                  child: Text(
                    '$_countdown',
                    style: const TextStyle(
                      color: AppColors.bg,
                      fontSize: 26,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              ),
            ],
          ],
        ),
      ),
    );
  }

  Widget _searchSlot(GamePlayer? p, bool isYou, int seat) {
    final found = p != null;
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 6),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Text(
            found ? p.name : '...',
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
            style: TextStyle(
              color: isYou ? AppColors.gold : Colors.white70,
              fontSize: 12,
            ),
          ),
          const SizedBox(height: 4),
          Container(
            width: 58,
            height: 58,
            padding: const EdgeInsets.all(3),
            decoration: BoxDecoration(
              color: AppColors.bgDark,
              borderRadius: BorderRadius.circular(10),
              border: Border.all(
                color: isYou ? AppColors.gold : AppColors.goldDark,
                width: 1.5,
              ),
            ),
            child:
                !found
                    ? _SearchingAvatar(slot: seat) // آواتارهای متغیر و متفاوت
                    : p.bot
                    ? const Icon(
                      Icons.smart_toy,
                      color: AppColors.gold,
                      size: 30,
                    )
                    : ClipRRect(
                      borderRadius: BorderRadius.circular(8),
                      child: RandomAvatar(p.avatarSeed),
                    ),
          ),
          const SizedBox(height: 2),
          Text(
            found ? (p.bot ? 'ربات' : (isYou ? 'شما' : 'حریف')) : '',
            style: const TextStyle(color: Colors.white38, fontSize: 10),
          ),
        ],
      ),
    );
  }

  Widget _trumpPicker(BuildContext context) {
    const suits = [
      ('spades', '♠', 'پیک', Colors.white),
      ('hearts', '♥', 'دل', AppColors.suitRed),
      ('diamonds', '♦', 'خشت', AppColors.suitRed),
      ('clubs', '♣', 'گشنیز', Colors.white),
    ];
    return Container(
      color: Colors.black54,
      alignment: Alignment.center,
      child: Container(
        margin: const EdgeInsets.all(24),
        padding: const EdgeInsets.all(20),
        decoration: BoxDecoration(
          color: AppColors.panel,
          borderRadius: BorderRadius.circular(16),
          border: Border.all(color: AppColors.gold, width: 2),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text(
              'حکم را انتخاب کن',
              style: TextStyle(color: AppColors.gold, fontSize: 20),
            ),
            const SizedBox(height: 16),
            Wrap(
              spacing: 12,
              runSpacing: 12,
              alignment: WrapAlignment.center,
              children: [
                for (final (id, sym, name, color) in suits)
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: AppColors.bgDark,
                      minimumSize: const Size(120, 64),
                    ),
                    onPressed: () => context.read<GameBloc>().chooseTrump(id),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Text(sym, style: TextStyle(fontSize: 26, color: color)),
                        const SizedBox(width: 8),
                        Text(
                          name,
                          style: const TextStyle(color: AppColors.text),
                        ),
                      ],
                    ),
                  ),
              ],
            ),
            const SizedBox(height: 16),
            const Divider(color: AppColors.goldFaint, height: 1),
            const SizedBox(height: 12),
            // بُرِ مجدد با مصرفِ یک بلیت (۵ کارتِ تازه، سپس باز هم انتخابِ حکم).
            BlocBuilder<WalletBloc, WalletBlocState>(
              builder: (context, ws) {
                final tickets = ws.walletStatus is WalletLoaded
                    ? (ws.walletStatus as WalletLoaded).wallet.tickets
                    : 0;
                final canReshuffle = tickets > 0;
                return Column(
                  children: [
                    ElevatedButton.icon(
                      style: ElevatedButton.styleFrom(
                        backgroundColor: const Color(0xFF8E1B7A),
                        disabledBackgroundColor: const Color(0xFF3A2233),
                        minimumSize: const Size(220, 48),
                      ),
                      onPressed: canReshuffle
                          ? () {
                              AppSounds.button();
                              context.read<GameBloc>().reshuffle();
                              // پس از مصرفِ بلیت، موجودی را تازه کن (بدون نگه‌داشتنِ context).
                              final wallet = context.read<WalletBloc>();
                              Future.delayed(const Duration(milliseconds: 500),
                                  () => wallet.add(LoadWalletEvent()));
                            }
                          : null,
                      icon: const Icon(Icons.casino, color: Colors.white),
                      label: const Text(
                        'بُر مجدد (۱ بلیت)',
                        style: TextStyle(
                            color: Colors.white, fontWeight: FontWeight.bold),
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      canReshuffle
                          ? 'بلیت‌های شما: $tickets'
                          : 'بلیت کافی ندارید',
                      style: const TextStyle(
                          color: Colors.white60, fontSize: 12),
                    ),
                  ],
                );
              },
            ),
          ],
        ),
      ),
    );
  }

  Widget _handResult(GameUiState s) {
    final r = s.handResult!;
    final mySeat = s.state?.yourSeat ?? 0;
    final myTeam = mySeat % 2;
    final won = r.winnerTeam == myTeam;
    return IgnorePointer(
      child: Center(
        child: Container(
          padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 18),
          decoration: BoxDecoration(
            color: Colors.black87,
            borderRadius: BorderRadius.circular(16),
            border: Border.all(color: AppColors.gold),
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(
                won ? 'این دست را بردید!' : 'این دست را باختید',
                style: TextStyle(
                  color: won ? AppColors.green : Colors.redAccent,
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
              ),
              if (r.kot)
                Padding(
                  padding: const EdgeInsets.only(top: 6),
                  child: Text(
                    r.hakemKot
                        ? 'حاکم‌کُت! (${r.points} امتیاز)'
                        : 'کُت! (${r.points} امتیاز)',
                    style: const TextStyle(color: AppColors.gold),
                  ),
                ),
              const SizedBox(height: 6),
              Text(
                'امتیاز: ${r.scores.isNotEmpty ? r.scores[0] : 0} - ${r.scores.length > 1 ? r.scores[1] : 0}',
                style: const TextStyle(color: Colors.white70),
              ),
            ],
          ),
        ),
      ),
    );
  }

  // نشانِ درون‌بازیِ تورنومنت: به کاربر می‌فهماند این بازیِ عمومی به تورنومنت
  // امتیاز می‌دهد (بالای صحنه، وسط).
  Widget _tournamentBadge() => Positioned(
        top: 6,
        left: 0,
        right: 0,
        child: IgnorePointer(
          child: Center(
            child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
              decoration: BoxDecoration(
                gradient: const LinearGradient(
                  colors: [Color(0xFF3A2A6E), AppColors.lapisInk],
                ),
                borderRadius: BorderRadius.circular(20),
                border: Border.all(color: AppColors.gold, width: 1.2),
                boxShadow: [
                  BoxShadow(
                      color: AppColors.gold.withValues(alpha: 0.3),
                      blurRadius: 8),
                ],
              ),
              child: Row(mainAxisSize: MainAxisSize.min, children: [
                const Icon(Icons.emoji_events, color: AppColors.gold, size: 15),
                const SizedBox(width: 5),
                Text(
                  'تورنومنت: ${_tournament!.title}',
                  style: const TextStyle(
                      color: AppColors.gold,
                      fontSize: 12,
                      fontWeight: FontWeight.bold),
                ),
              ]),
            ),
          ),
        ),
      );

  Widget _gameOver(BuildContext context, GameUiState s) {
    final g = s.gameOver!;
    final mySeat = s.state?.yourSeat ?? 0;
    final won = g.winnerTeam == mySeat % 2;
    return Container(
      color: Colors.black87,
      alignment: Alignment.center,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Text(
            won ? 'بردید! 🎉' : 'باختید',
            style: TextStyle(
              color: won ? AppColors.gold : Colors.redAccent,
              fontSize: 32,
              fontWeight: FontWeight.bold,
            ),
          ),
          const SizedBox(height: 12),
          Text(
            'نتیجه نهایی: ${g.scores.isNotEmpty ? g.scores[0] : 0} - ${g.scores.length > 1 ? g.scores[1] : 0}',
            style: const TextStyle(color: Colors.white70, fontSize: 18),
          ),
          // امتیازِ کسب‌شده‌ی تورنومنت (برد ۱۰۰، شرکت ۲۵ — قانونِ ثابتِ سرور).
          if (_tournament != null) ...[
            const SizedBox(height: 16),
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
              decoration: BoxDecoration(
                color: AppColors.gold.withValues(alpha: 0.12),
                borderRadius: BorderRadius.circular(14),
                border: Border.all(color: AppColors.gold),
              ),
              child: Row(mainAxisSize: MainAxisSize.min, children: [
                const Icon(Icons.emoji_events, color: AppColors.gold, size: 20),
                const SizedBox(width: 8),
                Text(
                  '+${won ? 100 : 25} امتیاز تورنومنت «${_tournament!.title}»',
                  style: const TextStyle(
                      color: AppColors.gold,
                      fontSize: 14,
                      fontWeight: FontWeight.bold),
                ),
              ]),
            ),
          ],
          const SizedBox(height: 28),
          SizedBox(
            width: 220,
            child: ElevatedButton(
              onPressed: () => _exitToLobby(context),
              child: const Text('بازگشت به لابی'),
            ),
          ),
        ],
      ),
    );
  }
}

/// آواتارِ در حالِ تغییر برای جایگاه‌های خالیِ پنل جستجو (حسِ «در حال یافتن»).
class _SearchingAvatar extends StatefulWidget {
  final int slot; // هر جایگاه دامنه‌ی seedِ متفاوت دارد تا یکسان نباشند
  const _SearchingAvatar({required this.slot});

  @override
  State<_SearchingAvatar> createState() => _SearchingAvatarState();
}

class _SearchingAvatarState extends State<_SearchingAvatar> {
  Timer? _timer;
  int _i = 0;

  @override
  void initState() {
    super.initState();
    _i = widget.slot * 13; // شروعِ متفاوت برای هر جایگاه
    _timer = Timer.periodic(const Duration(milliseconds: 240), (_) {
      if (mounted) setState(() => _i++);
    });
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // پیشوندِ مخصوصِ جایگاه ⇒ آواتارِ هر جایگاه با بقیه فرق دارد.
    return ClipRRect(
      borderRadius: BorderRadius.circular(8),
      child: RandomAvatar('s${widget.slot}-$_i'),
    );
  }
}
