package legion.muyue.best2048;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.concurrent.TimeUnit;

/**
 * Gère le suivi, le stockage et la récupération des statistiques de jeu
 * pour les modes solo et multijoueur du jeu Best2048.
 * Utilise {@link SharedPreferences} pour la persistance des données.
 * Nécessite un {@link Context} Android pour l'initialisation.
 *
 * Cette classe suit diverses métriques telles que le nombre de parties jouées,
 * les scores, le temps de jeu, les mouvements, les fusions, les séries de victoires, etc.
 */
public class GameStats {

    // --- Constantes pour SharedPreferences ---
    /** Nom du fichier de préférences partagées utilisé pour stocker les statistiques. */
    private static final String PREFS_NAME = "Best2048_Prefs";
    /** Clé pour stocker le meilleur score global (principalement solo). */
    private static final String HIGH_SCORE_KEY = "high_score";
    // Clés pour les statistiques Solo
    /** Clé pour le nombre total de parties solo terminées (victoire ou défaite). */
    private static final String STATS_TOTAL_GAMES_PLAYED = "totalGamesPlayed";
    /** Clé pour le nombre total de parties solo démarrées. */
    private static final String STATS_TOTAL_GAMES_STARTED = "totalGamesStarted";
    /** Clé pour le nombre total de mouvements effectués en mode solo. */
    private static final String STATS_TOTAL_MOVES = "totalMoves";
    /** Clé pour le temps de jeu total cumulé en mode solo (en millisecondes). */
    private static final String STATS_TOTAL_PLAY_TIME_MS = "totalPlayTimeMs";
    /** Clé pour le nombre total de fusions de tuiles en mode solo. */
    private static final String STATS_TOTAL_MERGES = "totalMerges";
    /** Clé pour la valeur de la plus haute tuile jamais atteinte en mode solo. */
    private static final String STATS_HIGHEST_TILE = "highestTile";
    /** Clé pour le nombre de fois où l'objectif (ex: tuile 2048) a été atteint en mode solo. */
    private static final String STATS_OBJECTIVE_REACHED_COUNT = "numberOfTimesObjectiveReached";
    /** Clé pour le meilleur temps pour atteindre l'objectif en mode solo (en millisecondes). */
    private static final String STATS_BEST_WINNING_TIME_MS = "bestWinningTimeMs";
    /** Clé pour le pire (plus long) temps pour atteindre l'objectif en mode solo (en millisecondes). */
    private static final String STATS_WORST_WINNING_TIME_MS = "worstWinningTimeMs";
    // Clés pour les statistiques Multijoueur (persistées)
    /** Clé pour le nombre total de parties multijoueur gagnées. */
    private static final String STATS_MP_GAMES_WON = "multiplayerGamesWon";
    /** Clé pour le nombre total de parties multijoueur jouées (terminées). */
    private static final String STATS_MP_GAMES_PLAYED = "multiplayerGamesPlayed";
    /** Clé pour la meilleure série de victoires consécutives en multijoueur. */
    private static final String STATS_MP_BEST_WINNING_STREAK = "multiplayerBestWinningStreak";
    /** Clé pour le score total cumulé en multijoueur. */
    private static final String STATS_MP_TOTAL_SCORE = "multiplayerTotalScore";
    /** Clé pour le temps de jeu total cumulé en multijoueur (en millisecondes). */
    private static final String STATS_MP_TOTAL_TIME_MS = "multiplayerTotalTimeMs";
    /** Clé pour le nombre total de parties multijoueur perdues. */
    private static final String STATS_MP_LOSSES = "totalMultiplayerLosses";
    /** Clé pour le meilleur score obtenu dans une seule partie multijoueur. */
    private static final String STATS_MP_HIGH_SCORE = "multiplayerHighScore";

    // --- Champs Solo & Général (persistés via SharedPreferences) ---
    /** Nombre total de parties solo terminées (victoires + défaites). Persisté. */
    private int totalGamesPlayed;
    /** Nombre total de parties solo commencées. Persisté. */
    private int totalGamesStarted;
    /** Nombre total de mouvements effectués dans toutes les parties solo. Persisté. */
    private int totalMoves;
    /** Temps de jeu total cumulé pour toutes les parties solo (en millisecondes). Persisté. */
    private long totalPlayTimeMs;
    /** Nombre total de fusions effectuées dans toutes les parties solo. Persisté. */
    private int totalMerges;
    /** Valeur de la plus haute tuile jamais atteinte en mode solo. Persisté. */
    private int highestTile;
    /** Nombre de fois où l'objectif (ex: 2048) a été atteint en solo. Persisté. */
    private int numberOfTimesObjectiveReached;
    /** Meilleur temps (le plus court) pour atteindre l'objectif en solo (en millisecondes). Persisté. */
    private long bestWinningTimeMs;
    /** Pire temps (le plus long) pour atteindre l'objectif en solo (en millisecondes). Persisté. */
    private long worstWinningTimeMs;
    /** Meilleur score global atteint (principalement en mode solo). Persisté. */
    private int overallHighScore;

    // --- Champs Partie en cours (Solo - transitoires, non persistés) ---
    /** Nombre de mouvements effectués dans la partie solo actuelle. Non persisté. */
    private int currentMoves;
    /** Timestamp (millisecondes) du début de la partie solo actuelle. Non persisté. */
    private long currentGameStartTimeMs;
    /** Nombre de fusions effectuées dans la partie solo actuelle. Non persisté. */
    private int mergesThisGame;

    // --- Champs Multijoueur (persistés via SharedPreferences) ---
    /** Nombre total de parties multijoueur gagnées. Persisté. */
    private int multiplayerGamesWon;
    /** Nombre total de parties multijoueur jouées (terminées). Persisté. */
    private int multiplayerGamesPlayed;
    /** Meilleure série de victoires consécutives en multijoueur jamais atteinte. Persisté. */
    private int multiplayerBestWinningStreak;
    /** Score total cumulé sur toutes les parties multijoueur. Persisté. */
    private long multiplayerTotalScore;
    /** Temps de jeu total cumulé pour toutes les parties multijoueur (en millisecondes). Persisté. */
    private long multiplayerTotalTimeMs;
    /** Nombre total de parties multijoueur perdues. Persisté. */
    private int totalMultiplayerLosses;
    /** Meilleur score obtenu dans une seule partie multijoueur. Persisté. */
    private int multiplayerHighestScore;

    // --- Champs Transitoires (non persistés) ---
    /** Série de victoires consécutives actuelle en multijoueur. Non persisté. */
    private int currentMultiplayerWinningStreak = 0;

    /** Contexte Android nécessaire pour accéder aux SharedPreferences. */
    private final Context context;

    // --- Constructeur & Persistance ---

    /**
     * Construit une nouvelle instance de GameStats.
     * Charge immédiatement les statistiques persistées depuis les SharedPreferences.
     *
     * @param context Le contexte de l'application Android, nécessaire pour accéder aux SharedPreferences. Ne doit pas être null.
     */
    public GameStats(Context context) {
        this.context = context.getApplicationContext(); // Utilise le contexte d'application pour éviter les fuites de mémoire
        loadStats(); // Charge les statistiques au moment de la création
    }

    /**
     * Charge toutes les statistiques persistées depuis le fichier SharedPreferences défini par {@link #PREFS_NAME}.
     * Si une clé n'est pas trouvée, une valeur par défaut est utilisée (généralement 0 ou Long.MAX_VALUE pour best time).
     */
    public void loadStats() {
        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        overallHighScore = prefs.getInt(HIGH_SCORE_KEY, 0);
        totalGamesPlayed = prefs.getInt(STATS_TOTAL_GAMES_PLAYED, 0);
        totalGamesStarted = prefs.getInt(STATS_TOTAL_GAMES_STARTED, 0);
        totalMoves = prefs.getInt(STATS_TOTAL_MOVES, 0);
        totalPlayTimeMs = prefs.getLong(STATS_TOTAL_PLAY_TIME_MS, 0L);
        totalMerges = prefs.getInt(STATS_TOTAL_MERGES, 0);
        highestTile = prefs.getInt(STATS_HIGHEST_TILE, 0);
        numberOfTimesObjectiveReached = prefs.getInt(STATS_OBJECTIVE_REACHED_COUNT, 0);
        bestWinningTimeMs = prefs.getLong(STATS_BEST_WINNING_TIME_MS, Long.MAX_VALUE);
        worstWinningTimeMs = prefs.getLong(STATS_WORST_WINNING_TIME_MS, 0L); // 0 est ok pour le pire temps
        // Chargement des stats Multi
        multiplayerGamesWon = prefs.getInt(STATS_MP_GAMES_WON, 0);
        multiplayerGamesPlayed = prefs.getInt(STATS_MP_GAMES_PLAYED, 0);
        multiplayerBestWinningStreak = prefs.getInt(STATS_MP_BEST_WINNING_STREAK, 0);
        multiplayerTotalScore = prefs.getLong(STATS_MP_TOTAL_SCORE, 0L);
        multiplayerTotalTimeMs = prefs.getLong(STATS_MP_TOTAL_TIME_MS, 0L);
        totalMultiplayerLosses = prefs.getInt(STATS_MP_LOSSES, 0);
        multiplayerHighestScore = prefs.getInt(STATS_MP_HIGH_SCORE, 0);
    }

    /**
     * Sauvegarde l'état actuel de toutes les statistiques persistables dans le fichier SharedPreferences.
     * Utilise {@link SharedPreferences.Editor#apply()} pour une sauvegarde asynchrone en arrière-plan.
     * Les statistiques transitoires (partie en cours) ne sont pas sauvegardées.
     */
    public void saveStats() {
        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putInt(HIGH_SCORE_KEY, overallHighScore);
        editor.putInt(STATS_TOTAL_GAMES_PLAYED, totalGamesPlayed);
        editor.putInt(STATS_TOTAL_GAMES_STARTED, totalGamesStarted);
        editor.putInt(STATS_TOTAL_MOVES, totalMoves);
        editor.putLong(STATS_TOTAL_PLAY_TIME_MS, totalPlayTimeMs);
        editor.putInt(STATS_TOTAL_MERGES, totalMerges);
        editor.putInt(STATS_HIGHEST_TILE, highestTile);
        editor.putInt(STATS_OBJECTIVE_REACHED_COUNT, numberOfTimesObjectiveReached);
        editor.putLong(STATS_BEST_WINNING_TIME_MS, bestWinningTimeMs);
        editor.putLong(STATS_WORST_WINNING_TIME_MS, worstWinningTimeMs);
        // Sauvegarde des stats Multi
        editor.putInt(STATS_MP_GAMES_WON, multiplayerGamesWon);
        editor.putInt(STATS_MP_GAMES_PLAYED, multiplayerGamesPlayed);
        editor.putInt(STATS_MP_BEST_WINNING_STREAK, multiplayerBestWinningStreak);
        editor.putLong(STATS_MP_TOTAL_SCORE, multiplayerTotalScore);
        editor.putLong(STATS_MP_TOTAL_TIME_MS, multiplayerTotalTimeMs);
        editor.putInt(STATS_MP_LOSSES, totalMultiplayerLosses);
        editor.putInt(STATS_MP_HIGH_SCORE, multiplayerHighestScore);
        editor.apply(); // Sauvegarde asynchrone
    }

    // --- Méthodes de suivi pour le mode Solo ---

    /**
     * Enregistre le début d'une nouvelle partie solo.
     * Incrémente le compteur de parties démarrées, réinitialise les compteurs de la partie actuelle
     * (mouvements, fusions) et enregistre l'heure de début.
     */
    public void startGame() {
        totalGamesStarted++;
        currentMoves = 0;
        mergesThisGame = 0;
        currentGameStartTimeMs = System.currentTimeMillis(); // Enregistre l'heure de début
    }

    /**
     * Enregistre un mouvement effectué dans la partie solo actuelle.
     * Incrémente le compteur de mouvements pour la partie en cours et le compteur total de mouvements.
     */
    public void recordMove() {
        currentMoves++;
        totalMoves++;
    }

    /**
     * Enregistre une ou plusieurs fusions effectuées lors d'un mouvement en solo.
     * Incrémente le compteur de fusions pour la partie en cours et le compteur total de fusions.
     *
     * @param numberOfMerges Le nombre de fusions à ajouter (doit être > 0).
     */
    public void recordMerge(int numberOfMerges) {
        if (numberOfMerges > 0) {
            mergesThisGame += numberOfMerges;
            totalMerges += numberOfMerges;
        }
    }

    /**
     * Met à jour la valeur de la plus haute tuile jamais atteinte si la nouvelle valeur est supérieure.
     *
     * @param tileValue La valeur de la tuile potentiellement la plus haute.
     */
    public void updateHighestTile(int tileValue) {
        if (tileValue > highestTile) {
            highestTile = tileValue;
            saveStats();
        }
    }

    /**
     * Enregistre une victoire en mode solo (atteinte de l'objectif).
     * Incrémente le compteur de victoires, met à jour les meilleurs/pires temps de victoire si applicable,
     * et appelle {@link #endGame(long)} pour finaliser les statistiques de la partie.
     *
     * @param timeMs Le temps pris pour gagner cette partie (en millisecondes).
     */
    public void recordWin(long timeMs) {
        numberOfTimesObjectiveReached++;
        if (timeMs < bestWinningTimeMs) {
            bestWinningTimeMs = timeMs;
        }
        // Utilise >= pour worstWinningTimeMs pour s'assurer qu'il est mis à jour même si le premier temps est 0
        if (timeMs >= worstWinningTimeMs) {
            worstWinningTimeMs = timeMs;
        }
        endGame(timeMs); // Finalise la partie avec le temps enregistré
    }

    /**
     * Enregistre une défaite en mode solo.
     * Calcule le temps de jeu pour cette partie et appelle {@link #endGame(long)}.
     */
    public void recordLoss() {
        long timeMs = (currentGameStartTimeMs > 0) ? System.currentTimeMillis() - currentGameStartTimeMs : 0;
        endGame(timeMs); // Finalise la partie
    }

    /**
     * Méthode privée pour finaliser les statistiques communes à la fin d'une partie solo (victoire ou défaite).
     * Incrémente le compteur total de parties jouées et ajoute le temps de jeu de cette partie.
     *
     * @param timeMs Le temps de jeu pour la partie qui vient de se terminer (en millisecondes).
     */
    private void endGame(long timeMs) {
        totalGamesPlayed++;
        addPlayTime(timeMs);
        currentGameStartTimeMs = 0;
        saveStats();
    }

    /**
     * Ajoute une durée au temps de jeu total cumulé en mode solo.
     *
     * @param durationMs La durée à ajouter (en millisecondes, doit être > 0).
     */
    public void addPlayTime(long durationMs) {
        if (durationMs > 0) {
            totalPlayTimeMs += durationMs;
        }
    }

    // --- Méthodes de suivi pour le mode Multijoueur ---

    /**
     * Méthode privée pour mettre à jour les statistiques communes à la fin d'une partie multijoueur.
     * Met à jour le nombre de parties jouées, le score total, le temps total et le meilleur score multi.
     *
     * @param score Le score obtenu dans la partie multijoueur terminée.
     * @param durationMs La durée de la partie multijoueur (en millisecondes).
     */
    private void endMultiplayerGame(int score, long durationMs) {
        multiplayerGamesPlayed++;
        multiplayerTotalScore += score;
        if (durationMs > 0) {
            multiplayerTotalTimeMs += durationMs;
        }
        if (score > multiplayerHighestScore) {
            multiplayerHighestScore = score;
        }
        // Sauvegarde souvent après une partie multi pour ne pas perdre le résultat
        saveStats();
    }

    /**
     * Enregistre une victoire en multijoueur.
     * Incrémente le compteur de victoires multi, met à jour la série de victoires (actuelle et meilleure),
     * et appelle {@link #endMultiplayerGame(int, long)}.
     *
     * @param score Le score obtenu dans la partie gagnée.
     * @param durationMs La durée de la partie gagnée (en millisecondes).
     */
    public void recordMultiplayerWin(int score, long durationMs) {
        multiplayerGamesWon++;
        currentMultiplayerWinningStreak++; // Incrémente la série actuelle
        if (currentMultiplayerWinningStreak > multiplayerBestWinningStreak) {
            multiplayerBestWinningStreak = currentMultiplayerWinningStreak; // Met à jour la meilleure série si nécessaire
        }
        endMultiplayerGame(score, durationMs); // Finalise les stats communes
    }

    /**
     * Enregistre une défaite en multijoueur.
     * Incrémente le compteur de défaites multi, réinitialise la série de victoires actuelle,
     * et appelle {@link #endMultiplayerGame(int, long)}.
     *
     * @param score Le score obtenu dans la partie perdue.
     * @param durationMs La durée de la partie perdue (en millisecondes).
     */
    public void recordMultiplayerLoss(int score, long durationMs) {
        totalMultiplayerLosses++;
        currentMultiplayerWinningStreak = 0; // Réinitialise la série de victoires
        endMultiplayerGame(score, durationMs); // Finalise les stats communes
    }

    /**
     * Enregistre un match nul en multijoueur.
     * Réinitialise la série de victoires actuelle et appelle {@link #endMultiplayerGame(int, long)}.
     * Note: Un match nul compte comme une partie jouée mais n'affecte pas les victoires/défaites.
     *
     * @param score Le score obtenu dans le match nul.
     * @param durationMs La durée du match nul (en millisecondes).
     */
    public void recordMultiplayerDraw(int score, long durationMs) {
        currentMultiplayerWinningStreak = 0; // Réinitialise la série de victoires (convention)
        endMultiplayerGame(score, durationMs); // Finalise les stats communes
    }

    // --- Réinitialisation ---

    /**
     * Réinitialise toutes les statistiques (solo et multijoueur, persistées et transitoires)
     * à leurs valeurs par défaut.
     * Sauvegarde immédiatement l'état réinitialisé dans les SharedPreferences.
     */
    public void resetStats() {
        // Réinitialisation Solo & Général
        overallHighScore = 0;
        totalGamesPlayed = 0;
        totalGamesStarted = 0;
        totalMoves = 0;
        totalPlayTimeMs = 0L;
        totalMerges = 0;
        highestTile = 0;
        numberOfTimesObjectiveReached = 0;
        bestWinningTimeMs = Long.MAX_VALUE;
        worstWinningTimeMs = 0L;
        // Réinitialisation Multi
        multiplayerGamesWon = 0;
        multiplayerGamesPlayed = 0;
        multiplayerBestWinningStreak = 0;
        multiplayerTotalScore = 0L;
        multiplayerTotalTimeMs = 0L;
        totalMultiplayerLosses = 0;
        multiplayerHighestScore = 0;
        // Réinitialisation Transitoire
        currentMoves = 0;
        mergesThisGame = 0;
        currentGameStartTimeMs = 0L;
        currentMultiplayerWinningStreak = 0;

        saveStats(); // Sauvegarde l'état réinitialisé
    }

    // --- Getters (Accesseurs) ---

    /** @return Le nombre total de parties solo terminées. */
    public int getTotalGamesPlayed() { return totalGamesPlayed; }
    /** @return Le nombre total de parties solo démarrées. */
    public int getTotalGamesStarted() { return totalGamesStarted; }
    /** @return Le nombre total de mouvements effectués en solo. */
    public int getTotalMoves() { return totalMoves; }
    /** @return Le nombre de mouvements dans la partie solo actuelle. */
    public int getCurrentMoves() { return currentMoves; }
    /** @return Le temps de jeu total cumulé en solo (millisecondes). */
    public long getTotalPlayTimeMs() { return totalPlayTimeMs; }
    /** @return Le timestamp de début de la partie solo actuelle (millisecondes). */
    public long getCurrentGameStartTimeMs() { return currentGameStartTimeMs; }
    /** @return Le nombre de fusions dans la partie solo actuelle. */
    public int getMergesThisGame() { return mergesThisGame; }
    /** @return Le nombre total de fusions effectuées en solo. */
    public int getTotalMerges() { return totalMerges; }
    /** @return La valeur de la plus haute tuile jamais atteinte en solo. */
    public int getHighestTile() { return highestTile; }
    /** @return Le nombre de fois où l'objectif a été atteint en solo. */
    public int getNumberOfTimesObjectiveReached() { return numberOfTimesObjectiveReached; }
    /** @return Le meilleur temps pour atteindre l'objectif en solo (millisecondes), ou Long.MAX_VALUE si jamais atteint. */
    public long getBestWinningTimeMs() { return bestWinningTimeMs; }
    /** @return Le pire temps pour atteindre l'objectif en solo (millisecondes). */
    public long getWorstWinningTimeMs() { return worstWinningTimeMs; }
    /** @return Le meilleur score global atteint (principalement solo). */
    public int getOverallHighScore() { return overallHighScore; }

    // --- Getters Multijoueur ---
    /** @return Le nombre total de parties multijoueur gagnées. */
    public int getMultiplayerGamesWon() { return multiplayerGamesWon; }
    /** @return Le nombre total de parties multijoueur jouées. */
    public int getMultiplayerGamesPlayed() { return multiplayerGamesPlayed; }
    /** @return La meilleure série de victoires consécutives en multijoueur. */
    public int getMultiplayerBestWinningStreak() { return multiplayerBestWinningStreak; }
    /** @return Le score total cumulé en multijoueur. */
    public long getMultiplayerTotalScore() { return multiplayerTotalScore; }
    /** @return Le temps de jeu total cumulé en multijoueur (millisecondes). */
    public long getMultiplayerTotalTimeMs() { return multiplayerTotalTimeMs; }
    /** @return Le nombre total de parties multijoueur perdues. */
    public int getTotalMultiplayerLosses() { return totalMultiplayerLosses; }
    /** @return Le meilleur score obtenu dans une seule partie multijoueur. */
    public int getMultiplayerHighestScore() { return multiplayerHighestScore; }
    /** @return La série de victoires consécutives actuelle en multijoueur (non persisté). */
    public int getCurrentMultiplayerWinningStreak() { return currentMultiplayerWinningStreak; }


    // --- Setters (Mutateurs) ---

    /**
     * Met à jour le meilleur score global si le score fourni est supérieur.
     * Utile pour enregistrer un nouveau record après une partie solo.
     * Ne sauvegarde pas automatiquement, appeler {@link #saveStats()} si nécessaire.
     *
     * @param score Le nouveau score potentiellement plus élevé.
     */
    public void setHighestScore(int score) {
        if (score > overallHighScore) {
            overallHighScore = score;
        }
    }

    /**
     * Définit manuellement l'heure de début de la partie en cours.
     * Peut être utile si l'état du jeu est restauré d'une source externe.
     *
     * @param timeMs Le timestamp de début en millisecondes.
     */
    public void setCurrentGameStartTimeMs(long timeMs) {
        currentGameStartTimeMs = timeMs;
    }

    // --- Méthodes Calculées ---

    /**
     * Calcule le temps de jeu moyen par partie solo terminée.
     *
     * @return Le temps moyen en millisecondes, ou 0 si aucune partie n'a été jouée.
     */
    public long getAverageGameTimeMs() {
        return (totalGamesPlayed > 0) ? totalPlayTimeMs / totalGamesPlayed : 0L;
    }

    /**
     * Calcule le score moyen par partie multijoueur terminée.
     *
     * @return Le score moyen, ou 0 si aucune partie multijoueur n'a été jouée.
     */
    public int getMultiplayerAverageScore() {
        return (multiplayerGamesPlayed > 0) ? (int)(multiplayerTotalScore / multiplayerGamesPlayed) : 0;
    }

    /**
     * Calcule le temps de jeu moyen par partie multijoueur terminée.
     *
     * @return Le temps moyen en millisecondes, ou 0 si aucune partie multijoueur n'a été jouée.
     */
    public long getMultiplayerAverageTimeMs() {
        return (multiplayerGamesPlayed > 0) ? multiplayerTotalTimeMs / multiplayerGamesPlayed : 0L;
    }

    /**
     * Formate une durée en millisecondes en une chaîne lisible "HH:MM:SS" ou "MM:SS".
     * Gère les durées négatives en les traitant comme 0.
     * Supprime le lint warning pour DefaultLocale car le format numérique est indépendant de la locale.
     *
     * @param ms La durée en millisecondes à formater.
     * @return Une chaîne formatée représentant la durée.
     */
    @SuppressLint("DefaultLocale") // Le format %02d est indépendant de la locale
    public static String formatTime(long ms) {
        if (ms < 0) {
            ms = 0; // Traite les durées négatives comme 0
        }
        long hours = TimeUnit.MILLISECONDS.toHours(ms);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(ms) % 60; // Minutes restantes après les heures
        long seconds = TimeUnit.MILLISECONDS.toSeconds(ms) % 60; // Secondes restantes après les minutes

        if (hours > 0) {
            // Format avec heures si la durée est >= 1 heure
            return String.format("%02d:%02d:%02d", hours, minutes, seconds);
        } else {
            // Format sans heures si la durée est < 1 heure
            return String.format("%02d:%02d", minutes, seconds);
        }
    }
}