package com.example.boidelov3.games.papelito;

import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.GridLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import com.example.boidelov3.R;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * Activité principale du jeu Papelito (Undercover)
 *
 * Gère le déroulement complet du jeu :
 * - Affichage du mot secret à chaque joueur
 * - Phase de discussion avec timer
 * - Phase de vote
 * - Affichage des résultats
 * - Condition de victoire
 */
public class PapelitoGameActivity extends AppCompatActivity {

    // UI Components
    private MaterialToolbar toolbar;
    private TextView phaseTextView;
    private TextView infoTextView;
    private TextView timerTextView;
    private MaterialCardView wordCard;
    private TextView wordTextView;
    private TextView currentWordPlayerTextView;
    private MaterialButton showWordButton;
    private MaterialButton startDiscussionButton;
    private MaterialButton startVotingButton;
    private MaterialButton nextPlayerButton;
    private MaterialButton endGameButton;
    private View mainContent;

    // Game Logic
    private PapelitoGame game;
    private List<String> playerNames;
    private int undercoverCount;
    private int discussionTimeSeconds;
    private CountDownTimer discussionTimer;
    private int currentPlayerViewIndex;
    private boolean hasShownWordToPlayer;
    private List<String> playersWhoVoted;
    private int currentVoterIndex = 0;
    private int totalRoundsPlayed = 0;

    // Constants
    private static final int DEFAULT_DISCUSSION_TIME = 60; // 60 secondes
    private static final int DEFAULT_UNDERCOVER_COUNT = 1;

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

        // Get intent data with validation
        playerNames = getIntent().getStringArrayListExtra("PLAYERS");
        undercoverCount = getIntent().getIntExtra("UNDERCOVER_COUNT", DEFAULT_UNDERCOVER_COUNT);
        discussionTimeSeconds = getIntent().getIntExtra("DISCUSSION_TIME", DEFAULT_DISCUSSION_TIME);

        // Validate all intent extras
        if (playerNames == null || playerNames.isEmpty()) {
            Toast.makeText(this, "Erreur: Aucun joueur spécifié pour la partie", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        if (undercoverCount <= 0) {
            Toast.makeText(this, "Erreur: Le nombre d'undercovers doit être au moins de 1", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        if (undercoverCount >= playerNames.size()) {
            Toast.makeText(this, "Erreur: Il doit y avoir plus de joueurs que d'undercovers", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        if (discussionTimeSeconds <= 0) {
            Toast.makeText(this, "Erreur: La durée de discussion doit être positive", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        initViews();
        setupToolbar();
        setupGame();
        setupListeners();

        // Commencer par afficher le mot au premier joueur
        startWordRevealPhase();
    }

    private void initViews() {
        toolbar = findViewById(R.id.toolbar);
        phaseTextView = findViewById(R.id.phaseTextView);
        infoTextView = findViewById(R.id.infoTextView);
        timerTextView = findViewById(R.id.timerTextView);
        wordCard = findViewById(R.id.wordCard);
        wordTextView = findViewById(R.id.wordTextView);
        currentWordPlayerTextView = findViewById(R.id.currentWordPlayerTextView);
        showWordButton = findViewById(R.id.showWordButton);
        startDiscussionButton = findViewById(R.id.startDiscussionButton);
        startVotingButton = findViewById(R.id.startVotingButton);
        nextPlayerButton = findViewById(R.id.nextPlayerButton);
        endGameButton = findViewById(R.id.endGameButton);
        mainContent = findViewById(R.id.mainContent);
    }

    private void setupToolbar() {
        toolbar.setNavigationOnClickListener(v -> showExitConfirmationDialog());
    }

    private void setupGame() {
        game = new PapelitoGame();
        game.setupGame(playerNames, undercoverCount);
        currentPlayerViewIndex = 0;
        hasShownWordToPlayer = false;
        playersWhoVoted = new ArrayList<>();
    }

    private void setupListeners() {
        showWordButton.setOnClickListener(v -> showSecretWord());
        nextPlayerButton.setOnClickListener(v -> moveToNextPlayer());
        startDiscussionButton.setOnClickListener(v -> startDiscussionPhase());
        startVotingButton.setOnClickListener(v -> startVotingPhase());
        endGameButton.setOnClickListener(v -> showGameOverDialog());
    }

    // ============================================================
    // PHASE 1: RÉVÉLATION DES MOTS
    // ============================================================

    private void startWordRevealPhase() {
        game.setGameState(PapelitoGame.GameState.SETUP);
        // Reset game's currentPlayerIndex to prevent wrong player start
        currentPlayerViewIndex = 0;
        hasShownWordToPlayer = false;

        updateUIForWordReveal();
        showCurrentPlayerPrompt();
    }

    private void updateUIForWordReveal() {
        phaseTextView.setText("Phase 1: Révélation des mots");
        timerTextView.setVisibility(View.GONE);

        // Cacher la carte du mot
        wordCard.setVisibility(View.GONE);
        wordTextView.setText("");

        // Afficher le bouton pour montrer le mot
        showWordButton.setVisibility(View.VISIBLE);
        nextPlayerButton.setVisibility(View.VISIBLE);

        // Cacher les boutons de phase suivante
        startDiscussionButton.setVisibility(View.GONE);
        startVotingButton.setVisibility(View.GONE);
        endGameButton.setVisibility(View.GONE);
    }

    private void showCurrentPlayerPrompt() {
        PapelitoPlayer player = game.getPlayers().get(currentPlayerViewIndex);
        currentWordPlayerTextView.setText(
            String.format("Tour de %s", player.getName())
        );
        infoTextView.setText(
            "Passe le téléphone à " + player.getName() + "\n\n" +
            "Appuie sur 'Voir mon mot' pour découvrir ton mot secret."
        );
        hasShownWordToPlayer = false;
        showWordButton.setEnabled(true);
    }

    private void showSecretWord() {
        PapelitoPlayer player = game.getPlayers().get(currentPlayerViewIndex);
        String secretWord = player.getSecretWord();

        wordTextView.setText(secretWord);
        wordCard.setVisibility(View.VISIBLE);
        showWordButton.setEnabled(false);
        hasShownWordToPlayer = true;

        infoTextView.setText(
            "Ton mot est: " + secretWord + "\n\n" +
            "Mémorise-le bien et appuie sur 'Joueur suivant' " +
            "quand tu es prêt."
        );
    }

    private void moveToNextPlayer() {
        if (!hasShownWordToPlayer) {
            Toast.makeText(this,
                "Tu dois d'abord voir ton mot!",
                Toast.LENGTH_SHORT).show();
            return;
        }

        currentPlayerViewIndex++;

        if (currentPlayerViewIndex >= game.getPlayers().size()) {
            // Tous les joueurs ont vu leur mot
            showReadyForDiscussionDialog();
        } else {
            showCurrentPlayerPrompt();
            wordCard.setVisibility(View.GONE);
        }
    }

    private void showReadyForDiscussionDialog() {
        currentWordPlayerTextView.setText("Prêts!");
        infoTextView.setText(
            "Tous les joueurs ont vu leur mot.\n\n" +
            "Préparez-vous pour la phase de discussion!"
        );
        wordCard.setVisibility(View.GONE);
        showWordButton.setVisibility(View.GONE);
        nextPlayerButton.setVisibility(View.GONE);
        startDiscussionButton.setVisibility(View.VISIBLE);
    }

    // ============================================================
    // PHASE 2: DISCUSSION
    // ============================================================

    private void startDiscussionPhase() {
        game.setGameState(PapelitoGame.GameState.DISCUSSION);
        updateUIForDiscussion();
        startDiscussionTimer();
    }

    private void updateUIForDiscussion() {
        phaseTextView.setText("Phase 2: Discussion");
        currentWordPlayerTextView.setText("Discutez!");

        wordCard.setVisibility(View.GONE);
        showWordButton.setVisibility(View.GONE);
        nextPlayerButton.setVisibility(View.GONE);
        startDiscussionButton.setVisibility(View.GONE);

        timerTextView.setVisibility(View.VISIBLE);
        startVotingButton.setVisibility(View.VISIBLE);

        infoTextView.setText(
            "Chaque joueur décrit son mot tour à tour.\n\n" +
            "Les Undercovers doivent essayer de deviner le mot des civils " +
            "sans se faire repérer.\n\n" +
            "Les civils doivent essayer d'identifier les Undercovers."
        );
    }

    private void startDiscussionTimer() {
        discussionTimer = new CountDownTimer(
            discussionTimeSeconds * 1000L, 1000
        ) {
            @Override
            public void onTick(long millisUntilFinished) {
                long minutes = millisUntilFinished / 60000;
                long seconds = (millisUntilFinished % 60000) / 1000;
                timerTextView.setText(
                    String.format(Locale.getDefault(),
                        "%d:%02d", minutes, seconds)
                );
            }

            @Override
            public void onFinish() {
                timerTextView.setText("0:00");
                Toast.makeText(PapelitoGameActivity.this,
                    "Temps écoulé! Passez au vote.",
                    Toast.LENGTH_LONG).show();
            }
        }.start();
    }

    // ============================================================
    // PHASE 3: VOTE
    // ============================================================

    private void startVotingPhase() {
        // Arrêter le timer de discussion
        if (discussionTimer != null) {
            discussionTimer.cancel();
        }

        game.setGameState(PapelitoGame.GameState.VOTING);
        game.resetVotes();
        playersWhoVoted.clear();
        currentVoterIndex = 0;
        totalRoundsPlayed++;

        updateUIForVoting();
        showVotingDialog();
    }

    private void updateUIForVoting() {
        phaseTextView.setText("Phase 3: Vote");
        timerTextView.setVisibility(View.GONE);
        startVotingButton.setVisibility(View.GONE);
        endGameButton.setVisibility(View.VISIBLE);

        infoTextView.setText(
            "Chaque joueur vivant vote pour éliminer quelqu'un.\n\n" +
            "Le joueur avec le plus de votes est éliminé."
        );
    }

    private void showVotingDialog() {
        List<PapelitoPlayer> alivePlayers = game.getAlivePlayers();

        if (alivePlayers.isEmpty()) {
            checkGameEnd();
            return;
        }

        MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
        // Determine current voter name for dialog title
        String currentVoterName = alivePlayers.get(currentVoterIndex).getName();
        builder.setTitle("Vote de " + currentVoterName + " - Qui voulez-vous éliminer?");

        // Créer le layout personnalisé
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.setPadding(50, 40, 50, 10);

        TextView label = new TextView(this);
        label.setText("Qui voulez-vous éliminer?");
        label.setPadding(0, 0, 0, 20);
        layout.addView(label);

        // Créer une grille de boutons pour chaque joueur vivant
        GridLayout playerGrid = new GridLayout(this);
        playerGrid.setColumnCount(2);

        for (int i = 0; i < alivePlayers.size(); i++) {
            PapelitoPlayer player = alivePlayers.get(i);
            // Skip the current voter so they can't vote for themselves
            if (i == currentVoterIndex) {
                continue;
            }

            MaterialButton playerButton = new MaterialButton(this);
            playerButton.setText(player.getName());
            playerButton.setLayoutParams(new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
            ));

            GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            params.setMargins(8, 8, 8, 8);
            playerButton.setLayoutParams(params);

            playerButton.setOnClickListener(v -> {
                recordVote(player);
            });

            playerGrid.addView(playerButton);
        }

        layout.addView(playerGrid);

        builder.setView(layout);
        builder.setCancelable(false);
        builder.show();
    }

    private void recordVote(PapelitoPlayer votedPlayer) {
        if (playersWhoVoted.size() >= game.getAlivePlayers().size()) {
            // Tous ont voté
            return;
        }

        // Enregistrer le vote (simplifié : on ne track pas QUI a voté)
        votedPlayer.addVote();
        playersWhoVoted.add("vote");
        currentVoterIndex++;

        Toast.makeText(this,
            "Vote enregistré pour " + votedPlayer.getName(),
            Toast.LENGTH_SHORT).show();

        // Vérifier si tous les joueurs vivants ont voté
        if (playersWhoVoted.size() >= game.getAlivePlayers().size()) {
            // Tous les votes sont en, afficher le résultat
            showVotingResult();
        } else {
            // Continuer avec le prochain voteur
            showNextVoterDialog();
        }
    }

    private void showNextVoterDialog() {
        int votesRemaining = game.getAlivePlayers().size() - playersWhoVoted.size();

        MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
        builder.setTitle("Vote en cours");
        builder.setMessage(
            "Joueurs ayant voté: " + playersWhoVoted.size() + " / " +
            game.getAlivePlayers().size() + "\n\n" +
            "Passe le téléphone au prochain joueur."
        );
        builder.setPositiveButton("Continuer", (dialog, which) -> {
            showVotingDialog();
        });
        builder.setCancelable(false);
        builder.show();
    }

    private void showVotingResult() {
        PapelitoPlayer eliminated = game.eliminateMostVoted();

        if (eliminated == null) {
            // Personne n'a été éliminé (pas de votes ou égalité)
            MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
            builder.setTitle("Vote nul!");
            builder.setMessage(
                "Aucun joueur n'a été éliminé.\n\n" +
                "Soit il n'y avait pas de votes, soit il y a une égalité.\n\n" +
                "La partie continue!"
            );
            builder.setPositiveButton("Continuer", (dialog, which) -> {
                checkGameEnd();
            });
            builder.setCancelable(false);
            builder.show();
            return;
        }

        // Afficher le résultat de l'élimination
        showEliminationResult(eliminated);
    }

    private void showEliminationResult(PapelitoPlayer eliminated) {
        game.setGameState(PapelitoGame.GameState.RESULT);

        MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
        builder.setTitle("Joueur éliminé!");

        String message = String.format(
            "%s a été éliminé!\n\n" +
            "Son rôle était: %s\n\n" +
            "Son mot était: %s",
            eliminated.getName(),
            eliminated.getRole().getDisplayName(),
            eliminated.getSecretWord()
        );

        builder.setMessage(message);

        builder.setPositiveButton("Continuer", (dialog, which) -> {
            checkGameEnd();
        });

        builder.setCancelable(false);
        builder.show();
    }

    // ============================================================
    // VÉRIFICATION DE FIN DE JEU
    // ============================================================

    private void checkGameEnd() {
        boolean gameOver = game.checkGameOver();

        if (gameOver) {
            showGameOverDialog();
        } else {
            // Continuer avec un nouveau tour
            showNextRoundDialog();
        }
    }

    private void showNextRoundDialog() {
        MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
        builder.setTitle("Nouveau tour");

        StringBuilder status = new StringBuilder();
        status.append("Joueurs vivants:\n\n");

        for (PapelitoPlayer player : game.getAlivePlayers()) {
            status.append("• ").append(player.getName()).append("\n");
        }

        status.append("\nCivils: ").append(game.getAliveCivilsCount());
        status.append("\nUndercovers: ").append(game.getAliveUndercoversCount());

        builder.setMessage(status.toString());

        builder.setPositiveButton("Commencer", (dialog, which) -> {
            startWordRevealPhase();
        });

        builder.setCancelable(false);
        builder.show();
    }

    private void showGameOverDialog() {
        game.setGameState(PapelitoGame.GameState.GAME_OVER);

        // Lancer l'activité de résultat
        Intent intent = new Intent(this, PapelitoResultActivity.class);
        intent.putExtra(PapelitoResultActivity.EXTRA_PLAYERS, new ArrayList<>(game.getPlayers()));
        intent.putExtra(PapelitoResultActivity.EXTRA_WINNING_TEAM, game.getWinningTeam());
        intent.putExtra(PapelitoResultActivity.EXTRA_CIVIL_WORD, game.getCurrentCivilWord());
        intent.putExtra(PapelitoResultActivity.EXTRA_UNDERCOVER_WORD, game.getCurrentUndercoverWord());
        intent.putExtra(PapelitoResultActivity.EXTRA_TOTAL_ROUNDS, totalRoundsPlayed);
        startActivity(intent);
        finish();
    }

    // ============================================================
    // DIVERS
    // ============================================================

    private void showExitConfirmationDialog() {
        MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
        builder.setTitle("Quitter la partie?");
        builder.setMessage(
            "La partie sera perdue si vous quittez.\n\n" +
            "Voulez-vous vraiment quitter?"
        );

        builder.setPositiveButton("Quitter", (dialog, which) -> {
            finish();
        });

        builder.setNegativeButton("Continuer", null);
        builder.show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (discussionTimer != null) {
            discussionTimer.cancel();
            discussionTimer = null;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (discussionTimer != null) {
            discussionTimer.cancel();
        }
    }

    @Override
    public void onBackPressed() {
        showExitConfirmationDialog();
    }
}
