package com.example.boidelov3.games.boideloclassic;

import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Html;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import com.google.android.material.appbar.MaterialToolbar;
import com.example.boidelov3.BoideloAnimationUtils;
import com.example.boidelov3.EndGameActivity;
import com.example.boidelov3.R;
import com.example.boidelov3.data.PlayerStats;
import com.example.boidelov3.data.QuestionCategory;
import com.example.boidelov3.data.QuestionRepository;
import com.example.boidelov3.game.GameEngine;
import com.example.boidelov3.Question;
import com.example.boidelov3.Questions;
import com.example.boidelov3.utils.ErrorHandler;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

/**
 * BoideloClassicGameActivity - Activité principale du jeu Boidelo Classic
 * 
 * Cette activité gère le déroulement du jeu avec les questions, les défis,
 * les manches et les statistiques des joueurs.
 * 
 * C'est une version refactorisée de l'ancienne Jeux.java
 */
public class BoideloClassicGameActivity extends AppCompatActivity {

    // UI Components
    private MaterialToolbar toolbar;
    private TextView questionTextView;
    private TextView progressTextView;
    private TextView mancheCounterTextView;
    private TextView mancheQuestionText;
    private ProgressBar progressBar;
    private com.google.android.material.button.MaterialButton suivantButton;
    private View skipButton;
    private View questionIndicator;
    private View indicatorIcon;
    private TextView indicatorText;
    private View rootLayout;

    // Bulle pour les défis
    private PopupWindow defiBubble;

    // Data
    private List<Question> questions;
    private ArrayList<String> toutlesjoueurs;
    private List<Question> questionsAvecManches;
    private Map<String, PlayerStats> playerStatsMap;

    // Services
    private com.example.boidelov3.utils.SoundManager soundManager;
    private GameEngine gameEngine;
    private QuestionRepository questionRepository;

    // Random
    private final Random random = new Random();

    // Track asked question indices to avoid repeats
    private Set<Integer> askedQuestionIndices = new HashSet<>();

    // Game Settings
    private int nombreQuestions = 20;
    private int ajoutGorgees = 1;
    private boolean openAI = false;
    private int ratiOpenai = 5;
    private String keyOpenai = "";
    private int durationDefis = 10;

    // Game State
    private int currentQuestionIndex = 0;
    private String currentQuestionText = "";
    private boolean isMancheActive = false;
    private boolean isFinishingGame = false;
    private int questionsSinceLastAI = 0;

    // Constants
    private static final int MIN_DEFI_ROUNDS = 4;  // Minimum 4 manches
    private static final int MAX_DEFI_ROUNDS_RANDOM = 6;  // Max 6 tours aléatoires (4-10 tours au total)
    private static final int MIN_MANCHES_COUNT = 4;  // Minimum 4 manches
    private static final int PREGENERATED_AI_QUESTIONS = 10;
    private static final int MIN_AI_QUESTION_STOCK = 3;
    private static final int MIN_AI_GORGEE = 1;
    private static final int MAX_AI_GORGEE_ADDITIONAL = 4;
    private static final int RANDOM_PLAYER_SELECTION_COUNT = 3;
    private static final int TWO_PLAYERS = 2;
    private static final int ONE_PLAYER = 1;
    private static final int ANIMATION_DURATION_SHORT_MS = 300;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_boidelo_classic_game);

        // Récupère les joueurs et les paramètres depuis l'intent
        Intent intent = getIntent();
        toutlesjoueurs = intent.getStringArrayListExtra("PLAYERS");

        // Vérifier que la liste des joueurs est valide
        if (toutlesjoueurs == null || toutlesjoueurs.isEmpty()) {
            Toast.makeText(this, "Erreur: liste des joueurs manquante", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

        // Récupérer les paramètres de jeu
        if (intent.hasExtra("EXTRA_NOMBRE_QUESTIONS")) {
            nombreQuestions = intent.getIntExtra("EXTRA_NOMBRE_QUESTIONS", 20);
        }
        if (intent.hasExtra("EXTRA_AJOUT_GORGEE")) {
            ajoutGorgees = intent.getIntExtra("EXTRA_AJOUT_GORGEE", 1);
        }
        if (intent.hasExtra("EXTRA_OPENAI")) {
            openAI = intent.getBooleanExtra("EXTRA_OPENAI", false);
        }
        if (intent.hasExtra("EXTRA_RATIO_OPENAI")) {
            ratiOpenai = intent.getIntExtra("EXTRA_RATIO_OPENAI", 5);
        }
        if (intent.hasExtra("EXTRA_KEY_OPENAI")) {
            keyOpenai = intent.getStringExtra("EXTRA_KEY_OPENAI");
        }
        if (intent.hasExtra("EXTRA_DURATION_DEFIS")) {
            durationDefis = intent.getIntExtra("EXTRA_DURATION_DEFIS", 0);
        }

        initViews();
        initServices();
        loadQuestions();
        initializePlayerStats();
        setupProgressBar();
        setupButtonListeners();

        // Affiche la première question
        displayNewQuestion();
    }

    /**
     * Initialise les vues de l'activité
     */
    private void initViews() {
        toolbar = findViewById(R.id.toolbar);
        toolbar.setNavigationOnClickListener(v -> finish());

        questionTextView = findViewById(R.id.questionTextView);
        progressTextView = findViewById(R.id.progressTextView);
        mancheCounterTextView = findViewById(R.id.mancheCounterTextView);
        mancheQuestionText = findViewById(R.id.mancheQuestionText);
        progressBar = findViewById(R.id.progressBar);
        suivantButton = findViewById(R.id.suivantButton);
        skipButton = findViewById(R.id.skipButton);
        questionIndicator = findViewById(R.id.questionIndicator);
        indicatorIcon = findViewById(R.id.indicatorIcon);
        indicatorText = findViewById(R.id.indicatorText);
        rootLayout = findViewById(R.id.rootLayout);
    }

    /**
     * Initialise les services
     */
    private void initServices() {
        soundManager = com.example.boidelov3.utils.SoundManager.getInstance(this);
        gameEngine = new GameEngine();
        questionRepository = new QuestionRepository(this);
    }

    /**
     * Charge les questions depuis le repository
     */
    private void loadQuestions() {
        com.example.boidelov3.data.Result<Questions, ?> result = questionRepository.loadQuestions();
        if (result.isSuccess()) {
            Questions q = result.getData();
            questions = q != null && q.getQuestions() != null ? q.getQuestions() : new ArrayList<>();
        } else {
            android.util.Log.e("BoideloClassicGame", "Erreur lors du chargement des questions: " + result.getError());
            questions = new ArrayList<>();
            
            // Afficher une erreur à l'utilisateur
            new androidx.appcompat.app.AlertDialog.Builder(this)
                .setTitle("Erreur de chargement")
                .setMessage("Impossible de charger les questions. Veuillez réinstaller l'application.")
                .setPositiveButton("Fermer", (dialog, which) -> finish())
                .setCancelable(false)
                .show();
        }
        questionsAvecManches = new ArrayList<>();
    }

    /**
     * Initialise les statistiques des joueurs
     */
    private void initializePlayerStats() {
        playerStatsMap = new HashMap<>();
        for (String player : toutlesjoueurs) {
            playerStatsMap.put(player, new PlayerStats(player));
        }
    }

    /**
     * Configure la barre de progression
     */
    private void setupProgressBar() {
        progressBar.setMax(nombreQuestions);
        progressBar.setProgress(0);
        updateProgressText();
    }

    /**
     * Configure les écouteurs de boutons
     */
    private void setupButtonListeners() {
        suivantButton.setOnClickListener(v -> OnClickButton1(null));
        skipButton.setOnClickListener(v -> onSkipClick(null));
    }

    /**
     * Met à jour le texte de progression
     */
    private void updateProgressText() {
        progressTextView.setText(String.format("%d / %d", currentQuestionIndex, nombreQuestions));
    }

    /**
     * Met à jour la barre de progression
     */
    private void updateProgressBar() {
        progressBar.setProgress(currentQuestionIndex);
        updateProgressText();
    }

    /**
     * Met à jour la question affichée
     */
    private void updateQuestion() {
        // Si un défi est en cours, diminuer le compteur
        if (!questionsAvecManches.isEmpty()) {
            boolean defiFinished = processActiveManches();
            if (defiFinished) {
                // Le défi vient de se terminer, ne pas afficher de nouvelle question
                return;
            }
            // Le défi continue, afficher une nouvelle question normalement
        }

        // Sinon, vérifier si le jeu doit se terminer
        if (currentQuestionIndex >= nombreQuestions || shouldEndGame()) {
            handleGameEnd();
        } else {
            displayNewQuestion();
        }
    }

    /**
     * Vérifie si le jeu doit se terminer
     */
    private boolean shouldEndGame() {
        return currentQuestionIndex >= nombreQuestions;
    }

    /**
     * Gère la fin du jeu
     */
    private void handleGameEnd() {
        isFinishingGame = true;
        
        // Sauvegarder les stats avant de terminer
        saveGameStats();

        // Prépare les stats pour l'activité de fin
        Intent intent = new Intent(this, EndGameActivity.class);
        intent.putExtra("PLAYER_STATS", new ArrayList<>(playerStatsMap.values()));
        startActivity(intent);
        finish();
    }

    /**
     * Traite les manches actives et retourne true si le défi vient de se terminer
     */
    private boolean processActiveManches() {
        if (questionsAvecManches.isEmpty()) {
            return false;
        }

        Question mancheQuestion = questionsAvecManches.get(0);
        int manchesRestantes = mancheQuestion.getManchesRestantes();

        if (manchesRestantes > 0) {
            // Diminuer le compteur
            mancheQuestion.setManchesRestantes(manchesRestantes - 1);

            if (manchesRestantes - 1 == 0) {
                // Fin du défi - sauvegarder la question avant de vider
                Question finishedDefi = mancheQuestion;
                questionsAvecManches.clear();
                
                // Cacher le compteur de manches et le bouton skip
                mancheCounterTextView.setVisibility(View.GONE);
                mancheQuestionText.setVisibility(View.GONE);
                updateSkipButtonVisibility();
                
                showFinalMancheEndMessage(finishedDefi);
                return true; // Le défi vient de se terminer
            } else {
                // Continuer le défi - juste mettre à jour le compteur
                updateMancheCounter(manchesRestantes - 1);
                return false; // Le défi continue, on affichera une nouvelle question
            }
        }

        return false;
    }

    /**
     * Affiche le message final de fin de manche
     */
    private void showFinalMancheEndMessage(Question finishedDefi) {
        // Afficher la question complète du défi qui vient de se terminer
        String questionText = finishedDefi.getQuestion();
        String fullMessage = "<b>🏆 Fin du défi !</b><br><br>" + questionText;
        displayQuestionText(fullMessage);

        // Masquer le compteur de manches
        mancheCounterTextView.setVisibility(View.GONE);

        // Terminer après un délai plus long pour laisser le temps de lire
        rootLayout.postDelayed(() -> {
            // Continuer avec une nouvelle question ou finir le jeu
            updateQuestion();
        }, 5000);
    }

    /**
     * Affiche une nouvelle question
     */
    private void displayNewQuestion() {
        if (questions == null || questions.isEmpty()) {
            android.util.Log.e("BoideloClassicGame", "Aucune question disponible - fin du jeu");
            handleGameEnd();
            return;
        }

        Question question = selectRandomQuestion();
        currentQuestionText = question.getQuestion();
        currentQuestionIndex++;

        // Traiter le texte de la question (remplace J1, variante, manches, etc.)
        processQuestionText(question);

        // Afficher la question avec couleurs et emojis
        displayQuestion(question);
        updateProgressBar();
    }

    /**
     * Sélectionne une question aléatoire en évitant les doublons de défis
     */
    private Question selectRandomQuestion() {
        boolean hasActiveDefi = !questionsAvecManches.isEmpty();
        int maxAttempts = questions.size(); // Éviter boucle infinie
        int attempts = 0;

        // Collect unasked indices
        List<Integer> availableIndices = new ArrayList<>();
        for (int i = 0; i < questions.size(); i++) {
            if (!askedQuestionIndices.contains(i)) {
                availableIndices.add(i);
            }
        }

        // If all questions have been asked, reset tracking
        if (availableIndices.isEmpty()) {
            askedQuestionIndices.clear();
            for (int i = 0; i < questions.size(); i++) {
                availableIndices.add(i);
            }
        }

        while (attempts < maxAttempts) {
            int idx = random.nextInt(availableIndices.size());
            int questionIndex = availableIndices.get(idx);
            Question question = questions.get(questionIndex);

            // Si un défi est en cours, éviter les questions avec <manches>
            if (hasActiveDefi && question.getQuestion().contains("<manches>")) {
                attempts++;
                continue;
            }

            askedQuestionIndices.add(questionIndex);
            return question;
        }

        // Si on ne trouve pas de question valide, retourner une question aléatoire
        return questions.get(random.nextInt(questions.size()));
    }

    /**
     * Affiche la notification de fin de manche
     */
    private void showMancheEndNotification() {
        if (soundManager != null) {
            soundManager.playManche();
        }
        
        // Vibration pour feedback haptique
        BoideloAnimationUtils.triggerErrorHaptic(this);
        
        // Afficher un message toast pour informer les joueurs
        android.widget.Toast.makeText(this, "⏱️ Manche terminée!", android.widget.Toast.LENGTH_SHORT).show();
    }

    /**
     * Affiche une question de manche en petit
     */
    private void displayMancheQuestionSmall(String question) {
        mancheQuestionText.setText(question);
        mancheQuestionText.setVisibility(View.VISIBLE);
    }

    /**
     * Affiche une question de manche
     */
    private void displayMancheQuestion(String question) {
        displayMancheQuestionSmall(question);
    }

    /**
     * Met à jour le compteur de manches (affiché pendant un défi)
     */
    private void updateMancheCounter(int manchesRestantes) {
        String tourWord = manchesRestantes <= 1 ? "tour" : "tours";
        String restantWord = manchesRestantes <= 1 ? "restant" : "restants";
        mancheCounterTextView.setText("Défis : " + manchesRestantes + " " + tourWord + " " + restantWord);
        mancheCounterTextView.setVisibility(View.VISIBLE);
        
        // Afficher le bouton skip pendant un défi
        updateSkipButtonVisibility();

        // Créer la bulle pour afficher le défi quand on maintient le clic
        mancheCounterTextView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (questionsAvecManches.isEmpty()) {
                    return false;
                }

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        // Quand on appuie, afficher la bulle
                        showDefiBubble(v);
                        return true;

                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        // Quand on relâche, cacher la bulle
                        hideDefiBubble();
                        return true;
                }
                return false;
            }
        });
    }

    /**
     * Affiche la bulle avec la question du défi
     */
    private void showDefiBubble(View anchorView) {
        if (questionsAvecManches.isEmpty()) {
            return;
        }

        Question defi = questionsAvecManches.get(0);

        // Créer le contenu de la bulle
        LinearLayout bubbleContent = new LinearLayout(this);
        bubbleContent.setOrientation(LinearLayout.VERTICAL);
        bubbleContent.setPadding(24, 16, 24, 16);
        bubbleContent.setBackgroundResource(R.drawable.bg_card);

        TextView bubbleText = new TextView(this);
        bubbleText.setText(Html.fromHtml(defi.getQuestion(), Html.FROM_HTML_MODE_LEGACY));
        bubbleText.setTextColor(getColor(R.color.text_primary));
        bubbleText.setTextSize(16);
        bubbleContent.addView(bubbleText);

        // Créer la PopupWindow
        defiBubble = new PopupWindow(bubbleContent, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        defiBubble.setOutsideTouchable(true);
        defiBubble.setFocusable(true);

        // Afficher la bulle au-dessus du compteur (plus haut que le doigt)
        defiBubble.showAsDropDown(anchorView, 0, -150, Gravity.CENTER);
    }

    /**
     * Cache la bulle du défi
     */
    private void hideDefiBubble() {
        if (defiBubble != null && defiBubble.isShowing()) {
            defiBubble.dismiss();
            defiBubble = null;
        }
    }

    /**
     * Affiche une question
     */
    private void displayQuestion(Question question) {
        displayQuestionText(question.getQuestion());
        handleMancheQuestionVisibility(question);
        applyCategoryStyle(question); // Applique la couleur de fond et l'emoji
    }

    /**
     * Affiche le texte de la question (supporte le HTML pour le gras)
     */
    private void displayQuestionText(String text) {
        questionTextView.setText(Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY));
    }

    /**
     * Gère la visibilité de la question de manche
     */
    private void handleMancheQuestionVisibility(Question question) {
        if (question.isManches()) {
            mancheQuestionText.setVisibility(View.VISIBLE);
        } else {
            mancheQuestionText.setVisibility(View.GONE);
        }
    }

    /**
     * Applique le style de catégorie (couleur de fond et emojis)
     */
    private void applyCategoryStyle(Question question) {
        QuestionCategory.Category category = QuestionCategory.detectCategory(question);

        // Réinitialiser les indicateurs
        questionIndicator.setVisibility(View.GONE);

        // Appliquer la couleur de fond
        int categoryColor = QuestionCategory.getColorForCategory(category);
        BoideloAnimationUtils.animateBackgroundColor(rootLayout, categoryColor, 300);

        // Harmoniser les couleurs de la toolbar et du bouton
        harmonizeUiColors(categoryColor);

        // Afficher l'indicateur pour toutes les questions (y compris pendant les défis)
        String indicatorText = getCategoryQuestionIndicator(category, question);
        if (!indicatorText.isEmpty()) {
            showQuestionIndicatorWithEmoji(indicatorText);
        }
    }

    /**
     * Harmonise les couleurs de la toolbar et du bouton avec la couleur de fond
     */
    private void harmonizeUiColors(int baseColor) {
        // Créer une teinte plus foncée pour la toolbar (25% plus foncée pour plus de contraste)
        int toolbarColor = darkenColor(baseColor, 0.25f);

        // Créer une teinte plus foncée pour le bouton (15% plus foncée pour être plus visible)
        int buttonColor = darkenColor(baseColor, 0.15f);

        // Créer une teinte très foncée pour la progressBar et texte (30% plus foncée)
        int accentColor = darkenColor(baseColor, 0.3f);

        // Déterminer la couleur du texte selon la luminosité du fond
        int textColor = isColorDark(baseColor) ? Color.WHITE : Color.BLACK;
        int lighterTextColor = isColorDark(baseColor) ?
            lightenColor(Color.WHITE, 0.3f) :  // Gris clair pour fond sombre
            darkenColor(Color.BLACK, 0.3f);    // Gris foncé pour fond clair

        // Appliquer la couleur à la toolbar
        toolbar.setBackgroundColor(toolbarColor);

        // Appliquer la couleur au bouton suivant avec plus de contraste
        if (suivantButton != null) {
            suivantButton.setBackgroundTintList(
                ContextCompat.getColorStateList(this, android.R.color.transparent)
            );
            suivantButton.setBackgroundColor(buttonColor);
            // Texte toujours blanc pour le bouton pour plus de lisibilité
            suivantButton.setTextColor(Color.WHITE);
        }

        // Appliquer la couleur à la progressBar
        if (progressBar != null) {
            progressBar.setProgressTintList(
                android.content.res.ColorStateList.valueOf(accentColor)
            );
        }

        // Appliquer la couleur aux textes
        if (progressTextView != null) {
            progressTextView.setTextColor(lighterTextColor);
        }

        // Pour le compteur de manches, utiliser une couleur foncée car il est dans une carte (bg_card)
        if (mancheCounterTextView != null) {
            // Toujours utiliser du gris foncé pour le compteur (il est sur fond de carte)
            mancheCounterTextView.setTextColor(Color.parseColor("#424242"));
        }

        if (mancheQuestionText != null) {
            mancheQuestionText.setTextColor(textColor);
        }

        // Adapter aussi la couleur de l'indicateur (icône et texte)
        if (indicatorText != null) {
            indicatorText.setTextColor(textColor);
        }

        if (indicatorIcon != null && indicatorIcon instanceof android.widget.ImageView) {
            android.widget.ImageView imageView = (android.widget.ImageView) indicatorIcon;
            imageView.setColorFilter(textColor, android.graphics.PorterDuff.Mode.SRC_IN);
        }

        // NE PAS changer la couleur du texte de la question - garder la couleur par défaut
    }

    /**
     * Assombrit une couleur d'un certain pourcentage
     */
    private int darkenColor(int color, float percent) {
        int alpha = Color.alpha(color);
        int red = Color.red(color);
        int green = Color.green(color);
        int blue = Color.blue(color);

        red = Math.max((int) (red * (1 - percent)), 0);
        green = Math.max((int) (green * (1 - percent)), 0);
        blue = Math.max((int) (blue * (1 - percent)), 0);

        return Color.argb(alpha, red, green, blue);
    }

    /**
     * Éclaircit une couleur d'un certain pourcentage
     */
    private int lightenColor(int color, float percent) {
        int alpha = Color.alpha(color);
        int red = Color.red(color);
        int green = Color.green(color);
        int blue = Color.blue(color);

        red = Math.min((int) (red + (255 - red) * percent), 255);
        green = Math.min((int) (green + (255 - green) * percent), 255);
        blue = Math.min((int) (blue + (255 - blue) * percent), 255);

        return Color.argb(alpha, red, green, blue);
    }

    /**
     * Détermine si une couleur est foncée (pour choisir la couleur du texte)
     */
    private boolean isColorDark(int color) {
        double darkness = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
        return darkness >= 0.5;
    }

    /**
     * Retourne l'emoji associé à une catégorie
     */
    private String getCategoryEmoji(QuestionCategory.Category category) {
        switch (category) {
            case CIBLAGE:
                return "🎯";
            case CLASSEMENT:
                return "👑";
            case JUGEMENT:
                return "⚖️";
            case DUEL:
                return "🤝";
            case INTERACTIF:
                return "🎮";
            case DEFI_MANCHES:
                return "🔥";
            case VARIANTE:
                return "❓";
            case CALIENTE:
                return "😈";
            case VOTE:
                return "🗳️";
            case CLASSIQUE:
            default:
                return "⚪";
        }
    }

    /**
     * Détermine le texte de l'indicateur en fonction du nombre de joueurs et de la catégorie
     */
    private String getCategoryQuestionIndicator(QuestionCategory.Category category, Question question) {
        String categoryEmoji = getCategoryEmoji(category);
        String categoryName = QuestionCategory.getNameForCategory(category);
        int playerCount = toutlesjoueurs.size();

        // Pour les questions spéciales, on affiche juste l'emoji et la catégorie
        if (category == QuestionCategory.Category.CALIENTE ||
            category == QuestionCategory.Category.DEFI_MANCHES ||
            category == QuestionCategory.Category.INTERACTIF) {
            return categoryEmoji + " " + categoryName;
        }

        // Pour les autres, on affiche l'emoji + nombre de joueurs
        return categoryEmoji + " " + playerCount + " joueurs";
    }

    /**
     * Affiche l'indicateur avec le texte spécifié et animation
     */
    private void showQuestionIndicatorWithEmoji(String text) {
        indicatorText.setText(text);
        questionIndicator.setVisibility(View.VISIBLE);
        BoideloAnimationUtils.fadeIn(questionIndicator, 300);
    }

    /**
     * Détermine l'indicateur de nombre de joueurs
     */
    private String determinePlayerCountIndicator(Question question) {
        return String.format("%d joueurs", toutlesjoueurs.size());
    }

    /**
     * Affiche l'indicateur de texte
     */
    private void showIndicatorText(String text) {
        indicatorText.setText(text);
        questionIndicator.setVisibility(View.VISIBLE);
    }

    /**
     * Affiche l'indicateur de question
     */
    private void showQuestionIndicator(Question question) {
        showIndicatorText("❓ " + determinePlayerCountIndicator(question));
    }

    /**
     * Passe la question
     */
    private void skipQuestion() {
        updateQuestion();
    }

    /**
     * Termine le jeu
     */
    private void endGame() {
        handleGameEnd();
    }

    // ============================================================
    // TRAITEMENT DU TEXTE DES QUESTIONS
    // ============================================================

    /**
     * Traite le texte de la question pour remplacer tous les placeholders
     */
    private void processQuestionText(Question question) {
        String questionText = question.getQuestion();

        // Remplacer les variantes
        questionText = processVariantes(question, questionText);

        // Gérer les manches
        questionText = processManches(question, questionText);

        // Remplacer les joueurs et récupérer le nom du joueur J1 pour les stats
        PlayerSelectionResult playerResult = replacePlayers(questionText);
        questionText = playerResult.questionText;

        // Ajouter les gorgées et tracker les stats
        GorgeeResult gorgeeResult = processGorgees(question, questionText, playerResult.playerCount);
        questionText = gorgeeResult.questionText;

        // Mettre à jour les statistiques du joueur J1
        if (playerResult.j1Name != null) {
            updatePlayerStats(playerResult.j1Name, gorgeeResult);
        }

        question.setQuestion(questionText);
    }

    /**
     * Remplace les variantes dans la question
     */
    private String processVariantes(Question question, String questionText) {
        if (question.getVariante() != null && !question.getVariante().isEmpty()) {
            String chosenVariante = question.getVariante().get(random.nextInt(question.getVariante().size()));
            questionText = questionText.replace("<variante>", chosenVariante);
        }
        return questionText;
    }

    /**
     * Gère les manches pour les défis
     */
    private String processManches(Question question, String questionText) {
        if (questionText.contains("<manches>")) {
            int nbaleatoiremanches = calculateManchesCount();
            questionText = questionText.replace("<manches>", String.valueOf(nbaleatoiremanches));
            question.setManchesRestantes(nbaleatoiremanches);

            // Définir le message de fin de défi
            String stopMessage = "Fin de défi!\n" + questionText;
            question.setArretMessageManche(stopMessage);

            questionsAvecManches.add(question);

            // Afficher le compteur de manches initial
            updateMancheCounter(nbaleatoiremanches);
        }
        return questionText;
    }

    /**
     * Calcule le nombre de manches pour un défi
     */
    private int calculateManchesCount() {
        int nbaleatoiremanches = random.nextInt(MAX_DEFI_ROUNDS_RANDOM) + MIN_DEFI_ROUNDS + durationDefis;
        return Math.max(nbaleatoiremanches, MIN_MANCHES_COUNT);
    }

    /**
     * Résultat du remplacement des joueurs
     */
    private static class PlayerSelectionResult {
        String questionText;
        String j1Name;
        int playerCount;

        PlayerSelectionResult(String questionText, String j1Name, int playerCount) {
            this.questionText = questionText;
            this.j1Name = j1Name;
            this.playerCount = playerCount;
        }
    }

    /**
     * Remplace les placeholders de joueurs dans la question
     */
    private PlayerSelectionResult replacePlayers(String questionText) {
        boolean isJoueurs1 = questionText.contains("<J1>");
        boolean isJoueurs2 = questionText.contains("<J2>");
        boolean isJoueurs3 = questionText.contains("<J3>");

        String j1Name = null;
        int playerCount = 0;

        if (isJoueurs1 || isJoueurs2 || isJoueurs3) {
            List<String> aleatoirejoueurs = TroisJoueurAleatoire();

            if (isJoueurs1 && isJoueurs2 && isJoueurs3 && aleatoirejoueurs.size() >= RANDOM_PLAYER_SELECTION_COUNT) {
                playerCount = 3;
                j1Name = aleatoirejoueurs.get(0);
                questionText = questionText.replace("<J1>", ErrorHandler.escapeHtml(j1Name));
                questionText = questionText.replace("<J2>", ErrorHandler.escapeHtml(aleatoirejoueurs.get(1)));
                questionText = questionText.replace("<J3>", ErrorHandler.escapeHtml(aleatoirejoueurs.get(2)));
            } else if (isJoueurs1 && isJoueurs2 && aleatoirejoueurs.size() >= TWO_PLAYERS) {
                playerCount = 2;
                j1Name = aleatoirejoueurs.get(0);
                questionText = questionText.replace("<J1>", ErrorHandler.escapeHtml(j1Name));
                questionText = questionText.replace("<J2>", ErrorHandler.escapeHtml(aleatoirejoueurs.get(1)));
            } else if (isJoueurs1 && aleatoirejoueurs.size() >= ONE_PLAYER) {
                playerCount = 1;
                j1Name = aleatoirejoueurs.get(0);
                questionText = questionText.replace("<J1>", ErrorHandler.escapeHtml(j1Name));
            }
        }

        return new PlayerSelectionResult(questionText, j1Name, playerCount);
    }

    /**
     * Résultat du traitement des gorgées
     */
    private static class GorgeeResult {
        String questionText;
        int totalGorgees;
        boolean isBois;
        boolean isDistribue;

        GorgeeResult(String questionText, int totalGorgees, boolean isBois, boolean isDistribue) {
            this.questionText = questionText;
            this.totalGorgees = totalGorgees;
            this.isBois = isBois;
            this.isDistribue = isDistribue;
        }
    }

    /**
     * Résultat du choix d'action (bois/distribue)
     */
    private static class ActionChoiceResult {
        String questionText;
        boolean isBois;
        boolean isDistribue;

        ActionChoiceResult(String questionText, boolean isBois, boolean isDistribue) {
            this.questionText = questionText;
            this.isBois = isBois;
            this.isDistribue = isDistribue;
        }
    }

    /**
     * Traite les gorgées pour une question
     */
    private GorgeeResult processGorgees(Question question, String questionText, int playerCount) {
        int totalGorgees = 0;
        boolean isBois = false;
        boolean isDistribue = false;

        if (question.isDistribution() || question.isRecois()) {
            totalGorgees = question.getGorger() + ajoutGorgees;

            ActionChoiceResult actionResult = determineActionChoice(question, questionText, playerCount);
            questionText = actionResult.questionText;
            isBois = actionResult.isBois;
            isDistribue = actionResult.isDistribue;

            questionText = appendGorgeeCount(questionText, totalGorgees);
        }

        return new GorgeeResult(questionText, totalGorgees, isBois, isDistribue);
    }

    /**
     * Détermine l'action (boit/boivent ou distribue/distribuent) selon le nombre de joueurs
     */
    private ActionChoiceResult determineActionChoice(Question question, String questionText, int playerCount) {
        boolean isBois = false;
        boolean isDistribue = false;

        // Accord du verbe selon le nombre de joueurs
        String boisVerb = (playerCount > 1) ? "boivent" : "boit";
        String distribueVerb = (playerCount > 1) ? "distribuent" : "distribue";

        if (question.isRecois() && question.isDistribution()) {
            boolean rand = random.nextBoolean();
            if (rand) {
                questionText = questionText + " <b>" + boisVerb + "</b>";
                isBois = true;
            } else {
                questionText = questionText + " <b>" + distribueVerb + "</b>";
                isDistribue = true;
            }
        } else if (question.isRecois()) {
            questionText = questionText + " <b>" + boisVerb + "</b>";
            isBois = true;
        } else if (question.isDistribution()) {
            questionText = questionText + " <b>" + distribueVerb + "</b>";
            isDistribue = true;
        }

        return new ActionChoiceResult(questionText, isBois, isDistribue);
    }

    /**
     * Ajoute le nombre de gorgées au texte de la question
     */
    private String appendGorgeeCount(String questionText, int totalGorgees) {
        String plural = totalGorgees > 1 ? "s" : "";
        return questionText + " " + totalGorgees + " gorgée" + plural + ".";
    }

    /**
     * Met à jour les statistiques du joueur J1
     */
    private void updatePlayerStats(String j1Name, GorgeeResult gorgeeResult) {
        if (j1Name == null) return;

        PlayerStats stats = playerStatsMap.get(j1Name);
        if (stats == null) {
            stats = new PlayerStats(j1Name);
            playerStatsMap.put(j1Name, stats);
        }

        if (gorgeeResult.isBois) {
            stats.addGorgeesBuves(gorgeeResult.totalGorgees);
        }

        if (gorgeeResult.isDistribue) {
            stats.addGorgeesDistribuees(gorgeeResult.totalGorgees);
        }
    }

    /**
     * Sauvegarde les stats du jeu
     */
    private void saveGameStats() {
        if (questionRepository != null && playerStatsMap != null) {
            // Calculer le total des questions posées
            int totalQuestionsPlayed = currentQuestionIndex;
            int playersCount = toutlesjoueurs != null ? toutlesjoueurs.size() : 0;
            
            // Sauvegarder dans SharedPreferences via le repository
            questionRepository.saveGameStats(totalQuestionsPlayed, playersCount);
            
            android.util.Log.d("BoideloClassicGame", 
                "Stats sauvegardées: " + totalQuestionsPlayed + " questions, " + 
                playersCount + " joueurs");
        }
    }

    /**
     * Réinitialise les questions demandées
     */
    private void resetAskedQuestions() {
        currentQuestionIndex = 0;
        askedQuestionIndices.clear();
    }

    /**
     * Sélectionne 3 joueurs aléatoires
     */
    private ArrayList<String> TroisJoueurAleatoire() {
        ArrayList<String> selection = new ArrayList<>();
        if (toutlesjoueurs.size() <= 3) {
            return new ArrayList<>(toutlesjoueurs);
        }
        
        while (selection.size() < 3) {
            String player = toutlesjoueurs.get(random.nextInt(toutlesjoueurs.size()));
            if (!selection.contains(player)) {
                selection.add(player);
            }
        }
        return selection;
    }

    /**
     * Gère le clic sur le bouton suivant
     */
    public void OnClickButton1(View view) {
        updateQuestion();
    }

    /**
     * Gère le clic sur le bouton skip (Abandonner le défi)
     */
    public void onSkipClick(View view) {
        // Si un défi est en cours, l'abandonner complètement
        if (!questionsAvecManches.isEmpty()) {
            abandonDefi();
        }
        
        // Continuer normalement
        skipQuestion();
    }
    
    /**
     * Abandonne complètement le défi en cours
     */
    private void abandonDefi() {
        // Supprimer le défi en cours
        questionsAvecManches.clear();
        
        // Cacher le compteur de manches
        mancheCounterTextView.setVisibility(View.GONE);
        mancheQuestionText.setVisibility(View.GONE);
        
        // Cacher le bouton skip
        updateSkipButtonVisibility();
    }
    
    /**
     * Met à jour la visibilité du bouton skip (affiché seulement pendant un défi)
     */
    private void updateSkipButtonVisibility() {
        if (!questionsAvecManches.isEmpty()) {
            skipButton.setVisibility(View.VISIBLE);
        } else {
            skipButton.setVisibility(View.GONE);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Fermer la bulle si elle est ouverte
        hideDefiBubble();
        // if (soundManager != null) {
        //     soundManager.release();
        // }
    }
}
