package com.example.boidelov3.data;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import com.example.boidelov3.Question;
import com.example.boidelov3.Questions;
import com.google.gson.Gson;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Repository pour gérer l'accès aux données des questions.
 * Sépare la logique de chargement et de stockage de l'UI.
 */
public class QuestionRepository {
    private static final String TAG = "QuestionRepository";
    private static final String PREFS_NAME = "app";
    private static final String KEY_ASKED_QUESTIONS = "askedQuestions";

    private final Context context;
    private final SharedPreferences prefs;
    private final Gson gson;
    private Questions cachedQuestions;

    public QuestionRepository(Context context) {
        this.context = context.getApplicationContext();
        this.prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        this.gson = new Gson();
    }

    /**
     * Charge toutes les questions depuis le fichier JSON.
     *
     * @return Result contenant les questions ou une erreur
     */
    public Result<Questions, QuestionLoadException> loadQuestions() {
        if (cachedQuestions != null) {
            return Result.success(cachedQuestions);
        }

        try {
            try (InputStream is = context.getAssets().open("question.json")) {
                byte[] buffer = new byte[is.available()];
                is.read(buffer);

                String json = new String(buffer, "UTF-8");
                cachedQuestions = gson.fromJson(json, Questions.class);

                if (cachedQuestions == null || cachedQuestions.getQuestions() == null) {
                    return Result.failure(new QuestionLoadException("Impossible de parser le JSON"));
                }

                Log.d(TAG, "Chargé " + cachedQuestions.getQuestions().size() + " questions");
                return Result.success(cachedQuestions);
            }

        } catch (IOException e) {
            Log.e(TAG, "Erreur de chargement des questions", e);
            return Result.failure(new QuestionLoadException("Erreur de lecture du fichier questions.json", e));
        }
    }

    /**
     * Obtient une question aléatoire qui n'a pas encore été posée.
     *
     * @param questions La liste complète des questions
     * @return Une question ou null si toutes ont été posées
     */
    public Result<Question, QuestionLoadException> getRandomUnaskedQuestion(List<Question> questions) {
        Set<String> askedQuestions = prefs.getStringSet(KEY_ASKED_QUESTIONS, new HashSet<>());

        List<Question> unaskedQuestions = new ArrayList<>();
        for (Question question : questions) {
            if (!askedQuestions.contains(String.valueOf(question.getId()))) {
                unaskedQuestions.add(question);
            }
        }

        if (unaskedQuestions.isEmpty()) {
            return Result.failure(new QuestionLoadException("Toutes les questions ont été posées"));
        }

        // Sélection aléatoire
        java.util.Random random = new java.util.Random();
        Question selected = unaskedQuestions.get(random.nextInt(unaskedQuestions.size()));

        // Marquer comme posée
        askedQuestions.add(String.valueOf(selected.getId()));
        prefs.edit().putStringSet(KEY_ASKED_QUESTIONS, askedQuestions).apply();

        return Result.success(selected);
    }

    /**
     * Marque une question comme étant posée.
     */
    public void markQuestionAsAsked(int questionId) {
        Set<String> askedQuestions = prefs.getStringSet(KEY_ASKED_QUESTIONS, new HashSet<>());
        askedQuestions.add(String.valueOf(questionId));
        prefs.edit().putStringSet(KEY_ASKED_QUESTIONS, askedQuestions).apply();
    }

    /**
     * Réinitialise la liste des questions posées.
     */
    public void resetAskedQuestions() {
        prefs.edit().remove(KEY_ASKED_QUESTIONS).apply();
        Log.d(TAG, "Questions posées réinitialisées");
    }

    /**
     * Sauvegarde les statistiques d'une partie.
     */
    public void saveGameStats(int questionsPlayed, int playersCount) {
        SharedPreferences statsPrefs = context.getSharedPreferences("game_stats", Context.MODE_PRIVATE);
        statsPrefs.edit()
                .putInt("questions_played", questionsPlayed)
                .putInt("players_count", playersCount)
                .apply();
        Log.d(TAG, "Stats sauvegardées: " + questionsPlayed + " questions, " + playersCount + " joueurs");
    }

    /**
     * Exception personnalisée pour les erreurs de chargement.
     */
    public static class QuestionLoadException extends Exception {
        public QuestionLoadException(String message) {
            super(message);
        }

        public QuestionLoadException(String message, Throwable cause) {
            super(message, cause);
        }
    }
}
