import 'package:cabo_counter/core/custom_theme.dart';
import 'package:cabo_counter/data/game_manager.dart';
import 'package:cabo_counter/data/game_session.dart';
import 'package:cabo_counter/l10n/generated/app_localizations.dart';
import 'package:cabo_counter/presentation/views/create_game_view.dart';
import 'package:cabo_counter/presentation/views/graph_view.dart';
import 'package:cabo_counter/presentation/views/points_view.dart';
import 'package:cabo_counter/presentation/views/round_view.dart';
import 'package:cabo_counter/services/local_storage_service.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class ActiveGameView extends StatefulWidget {
  final GameSession gameSession;
  const ActiveGameView({super.key, required this.gameSession});

  @override
  // ignore: library_private_types_in_public_api
  _ActiveGameViewState createState() => _ActiveGameViewState();
}

class _ActiveGameViewState extends State<ActiveGameView> {
  late final GameSession gameSession;
  late List<int> denseRanks;
  late List<int> sortedPlayerIndices;

  @override
  void initState() {
    super.initState();
    gameSession = widget.gameSession;
  }

  @override
  Widget build(BuildContext context) {
    return ListenableBuilder(
        listenable: gameSession,
        builder: (context, _) {
          sortedPlayerIndices = _getSortedPlayerIndices();
          denseRanks = _calculateDenseRank(
              gameSession.playerScores, sortedPlayerIndices);
          return CupertinoPageScaffold(
              navigationBar: CupertinoNavigationBar(
                middle: Text(gameSession.gameTitle),
              ),
              child: SafeArea(
                child: SingleChildScrollView(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Padding(
                        padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Text(
                          AppLocalizations.of(context).players,
                          style: CustomTheme.rowTitle,
                        ),
                      ),
                      ListView.builder(
                        shrinkWrap: true,
                        physics: const NeverScrollableScrollPhysics(),
                        itemCount: gameSession.players.length,
                        itemBuilder: (BuildContext context, int index) {
                          int playerIndex = sortedPlayerIndices[index];
                          return CupertinoListTile(
                            title: Row(
                              children: [
                                _getPlacementTextWidget(index),
                                const SizedBox(width: 5),
                                Text(
                                  gameSession.players[playerIndex],
                                  style: const TextStyle(
                                      fontWeight: FontWeight.bold),
                                ),
                              ],
                            ),
                            trailing: Row(
                              children: [
                                const SizedBox(width: 5),
                                Text('${gameSession.playerScores[playerIndex]} '
                                    '${AppLocalizations.of(context).points}')
                              ],
                            ),
                          );
                        },
                      ),
                      Padding(
                        padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Text(
                          AppLocalizations.of(context).rounds,
                          style: CustomTheme.rowTitle,
                        ),
                      ),
                      ListView.builder(
                        shrinkWrap: true,
                        physics: const NeverScrollableScrollPhysics(),
                        itemCount: gameSession.roundNumber,
                        itemBuilder: (BuildContext context, int index) {
                          return Padding(
                              padding: const EdgeInsets.all(1),
                              child: CupertinoListTile(
                                backgroundColorActivated:
                                    CustomTheme.backgroundColor,
                                title: Text(
                                  '${AppLocalizations.of(context).round} ${index + 1}',
                                ),
                                trailing:
                                    index + 1 != gameSession.roundNumber ||
                                            gameSession.isGameFinished == true
                                        ? (const Text('\u{2705}',
                                            style: TextStyle(fontSize: 22)))
                                        : const Text('\u{23F3}',
                                            style: TextStyle(fontSize: 22)),
                                onTap: () async {
                                  _openRoundView(index + 1);
                                },
                              ));
                        },
                      ),
                      Padding(
                        padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Text(
                          AppLocalizations.of(context).statistics,
                          style: CustomTheme.rowTitle,
                        ),
                      ),
                      Column(
                        children: [
                          CupertinoListTile(
                              title: Text(
                                AppLocalizations.of(context).scoring_history,
                              ),
                              backgroundColorActivated:
                                  CustomTheme.backgroundColor,
                              onTap: () => Navigator.push(
                                  context,
                                  CupertinoPageRoute(
                                      builder: (_) => GraphView(
                                            gameSession: gameSession,
                                          )))),
                          CupertinoListTile(
                              title: Text(
                                AppLocalizations.of(context).point_overview,
                              ),
                              backgroundColorActivated:
                                  CustomTheme.backgroundColor,
                              onTap: () => Navigator.push(
                                  context,
                                  CupertinoPageRoute(
                                      builder: (_) => PointsView(
                                            gameSession: gameSession,
                                          )))),
                        ],
                      ),
                      Padding(
                        padding: const EdgeInsets.fromLTRB(10, 10, 0, 0),
                        child: Text(
                          AppLocalizations.of(context).game,
                          style: CustomTheme.rowTitle,
                        ),
                      ),
                      Column(
                        children: [
                          Visibility(
                            visible: !gameSession.isPointsLimitEnabled,
                            child: CupertinoListTile(
                                title: Text(
                                  AppLocalizations.of(context).end_game,
                                  style: gameSession.roundNumber > 1 &&
                                          !gameSession.isGameFinished
                                      ? const TextStyle(color: Colors.white)
                                      : const TextStyle(color: Colors.white30),
                                ),
                                backgroundColorActivated:
                                    CustomTheme.backgroundColor,
                                onTap: () {
                                  if (gameSession.roundNumber > 1 &&
                                      !gameSession.isGameFinished) {
                                    _showEndGameDialog();
                                  }
                                }),
                          ),
                          CupertinoListTile(
                            title: Text(
                              AppLocalizations.of(context).delete_game,
                            ),
                            backgroundColorActivated:
                                CustomTheme.backgroundColor,
                            onTap: () {
                              _showDeleteGameDialog().then((value) {
                                if (value) {
                                  _removeGameSession(gameSession);
                                }
                              });
                            },
                          ),
                          CupertinoListTile(
                            title: Text(
                              AppLocalizations.of(context)
                                  .new_game_same_settings,
                            ),
                            backgroundColorActivated:
                                CustomTheme.backgroundColor,
                            onTap: () {
                              Navigator.pushReplacement(
                                  context,
                                  CupertinoPageRoute(
                                      builder: (_) => CreateGameView(
                                            gameTitle: gameSession.gameTitle,
                                            isPointsLimitEnabled: widget
                                                .gameSession
                                                .isPointsLimitEnabled,
                                            players: gameSession.players,
                                          )));
                            },
                          ),
                          CupertinoListTile(
                              title: Text(
                                AppLocalizations.of(context).export_game,
                              ),
                              backgroundColorActivated:
                                  CustomTheme.backgroundColor,
                              onTap: () async {
                                final success = await LocalStorageService
                                    .exportSingleGameSession(
                                        widget.gameSession);
                                if (!success && context.mounted) {
                                  showCupertinoDialog(
                                    context: context,
                                    builder: (context) => CupertinoAlertDialog(
                                      title: Text(AppLocalizations.of(context)
                                          .export_error_title),
                                      content: Text(AppLocalizations.of(context)
                                          .export_error_message),
                                      actions: [
                                        CupertinoDialogAction(
                                          child: Text(
                                              AppLocalizations.of(context).ok),
                                          onPressed: () =>
                                              Navigator.pop(context),
                                        ),
                                      ],
                                    ),
                                  );
                                }
                              }),
                        ],
                      )
                    ],
                  ),
                ),
              ));
        });
  }

  /// Shows a dialog to confirm ending the game.
  /// If the user confirms, it calls the `endGame` method on the game manager
  void _showEndGameDialog() {
    showCupertinoDialog(
      context: context,
      builder: (BuildContext context) {
        return CupertinoAlertDialog(
          title: Text(AppLocalizations.of(context).end_game_title),
          content: Text(AppLocalizations.of(context).end_game_message),
          actions: [
            CupertinoDialogAction(
              child: Text(
                AppLocalizations.of(context).end_game,
                style: const TextStyle(
                    fontWeight: FontWeight.bold,
                    color: CupertinoColors.destructiveRed),
              ),
              onPressed: () {
                setState(() {
                  gameManager.endGame(gameSession.id);
                });
                Navigator.pop(context);
              },
            ),
            CupertinoDialogAction(
              child: Text(AppLocalizations.of(context).cancel),
              onPressed: () => Navigator.pop(context),
            ),
          ],
        );
      },
    );
  }

  /// Returns a list of player indices sorted by their scores in
  /// ascending order.
  List<int> _getSortedPlayerIndices() {
    List<int> playerIndices =
        List<int>.generate(gameSession.players.length, (index) => index);
    // Sort the indices based on the summed points
    playerIndices.sort((a, b) {
      int scoreA = gameSession.playerScores[a];
      int scoreB = gameSession.playerScores[b];
      if (scoreA != scoreB) {
        return scoreA.compareTo(scoreB);
      }
      return a.compareTo(b);
    });
    return playerIndices;
  }

  /// Calculates the dense rank for a player based on their index in the sorted list of players.
  List<int> _calculateDenseRank(
      List<int> playerScores, List<int> sortedIndices) {
    List<int> denseRanks = [];
    int rank = 1;
    for (int i = 0; i < sortedIndices.length; i++) {
      if (i > 0) {
        int prevScore = playerScores[sortedIndices[i - 1]];
        int currScore = playerScores[sortedIndices[i]];
        if (currScore != prevScore) {
          rank++;
        }
      }
      denseRanks.add(rank);
    }
    return denseRanks;
  }

  /// Returns a text widget representing the placement text based on the given placement number.
  /// [index] is the index of the player in [players] list,
  Text _getPlacementTextWidget(int index) {
    int placement = denseRanks[index];
    switch (placement) {
      case 1:
        return const Text('\u{1F947}', style: TextStyle(fontSize: 22)); // 🥇
      case 2:
        return const Text('\u{1F948}', style: TextStyle(fontSize: 22)); // 🥈
      case 3:
        return const Text('\u{1F949}', style: TextStyle(fontSize: 22)); // 🥉
      default:
        return Text(' $placement.',
            style: const TextStyle(fontWeight: FontWeight.bold));
    }
  }

  /// Shows a dialog to confirm deleting the game session.
  Future<bool> _showDeleteGameDialog() async {
    return await showCupertinoDialog<bool>(
          context: context,
          builder: (BuildContext context) {
            return CupertinoAlertDialog(
              title: Text(AppLocalizations.of(context).delete_game_title),
              content: Text(
                AppLocalizations.of(context)
                    .delete_game_message(gameSession.gameTitle),
              ),
              actions: [
                CupertinoDialogAction(
                  child: Text(AppLocalizations.of(context).cancel),
                  onPressed: () => Navigator.pop(context, false),
                ),
                CupertinoDialogAction(
                  child: Text(
                    AppLocalizations.of(context).delete,
                    style: const TextStyle(
                        fontWeight: FontWeight.bold, color: Colors.red),
                  ),
                  onPressed: () {
                    Navigator.pop(context, true);
                  },
                ),
              ],
            );
          },
        ) ??
        false;
  }

  /// Removes the game session in the game manager and navigates back to the previous screen.
  /// If the game session does not exist in the game list, it shows an error dialog.
  Future<void> _removeGameSession(GameSession gameSession) async {
    if (gameManager.gameExistsInGameList(gameSession.id)) {
      Navigator.pop(context);

      WidgetsBinding.instance.addPostFrameCallback((_) {
        gameManager.removeGameSessionById(gameSession.id);
      });
    } else {
      showCupertinoDialog(
          context: context,
          builder: (BuildContext context) {
            return CupertinoAlertDialog(
              title: Text(AppLocalizations.of(context).id_error_title),
              content: Text(AppLocalizations.of(context).id_error_message),
              actions: [
                CupertinoDialogAction(
                  child: Text(AppLocalizations.of(context).ok),
                  onPressed: () => Navigator.pop(context),
                ),
              ],
            );
          });
    }
  }

  /// Recursively opens the RoundView for the specified round number.
  /// It starts with the given [roundNumber] and continues to open the next round
  /// until the user navigates back or the round number is invalid.
  void _openRoundView(int roundNumber) async {
    final val = await Navigator.of(context, rootNavigator: true).push(
      CupertinoPageRoute(
        fullscreenDialog: true,
        builder: (context) => RoundView(
          gameSession: gameSession,
          roundNumber: roundNumber,
        ),
      ),
    );
    if (val != null && val >= 0) {
      WidgetsBinding.instance.addPostFrameCallback((_) async {
        await Future.delayed(const Duration(milliseconds: 600));
        _openRoundView(val);
      });
    }
  }
}
