import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class GestionBDD {

    private static final String URL = "jdbc:sqlite:UserScoreBDD.db";

    // connexion BDD
    private static Connection connecter() throws SQLException {
        return DriverManager.getConnection(URL);
    }

    // Création table utilisateur
    public static void creerTableUtilisateurSiAbsente() {

        String sql = """
                CREATE TABLE IF NOT EXISTS utilisateur (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    username TEXT NOT NULL UNIQUE,
                    password TEXT NOT NULL
                );
                """;

        try (Connection conn = connecter();
             Statement stmt = conn.createStatement()) {

            stmt.execute(sql);

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // Création table score
    public static void creerTableScoreSiAbsente() {

        String sql = """
                CREATE TABLE IF NOT EXISTS score (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    valeur INTEGER NOT NULL,
                    utilisateur_id INTEGER,
                    FOREIGN KEY(utilisateur_id) REFERENCES utilisateur(id)
                );
                """;

        try (Connection conn = connecter();
             Statement stmt = conn.createStatement()) {

            stmt.execute(sql);

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // Créer un utilisateur
    public static boolean creerUtilisateur(String username, String password) {

        String sql = "INSERT INTO utilisateur(username, password) VALUES(?, ?)";

        try (Connection conn = connecter();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setString(1, username);
            stmt.setString(2, password);

            stmt.executeUpdate();
            return true;

        } catch (SQLException e) {
            System.out.println("Utilisateur déjà existant !");
            return false;
        }
    }

    // Vérifier connexion utilisateur
    public static int verifierConnexion(String username, String password) {

        String sql = "SELECT id FROM utilisateur WHERE username = ? AND password = ?";

        try (Connection conn = connecter();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setString(1, username);
            stmt.setString(2, password);

            ResultSet rs = stmt.executeQuery();

            if (rs.next()) {
                return rs.getInt("id");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return -1;
    }

    // Ajouter score
    public static void ajouterScore(int score, int utilisateurId) {

        String sql = "INSERT INTO score(valeur, utilisateur_id) VALUES(?, ?)";

        try (Connection conn = connecter();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setInt(1, score);
            stmt.setInt(2, utilisateurId);

            stmt.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // Récupérer scores d'un utilisateur
    public static List<Integer> recupererScoresUtilisateur(int utilisateurId) {

        List<Integer> scores = new ArrayList<>();

        String sql = "SELECT valeur FROM score WHERE utilisateur_id = ? ORDER BY valeur DESC";

        try (Connection conn = connecter();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setInt(1, utilisateurId);

            ResultSet rs = stmt.executeQuery();

            while (rs.next()) {
                scores.add(rs.getInt("valeur"));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return scores;
    }

    // Meilleur score d'un utilisateur
    public static int recupererMeilleurScoreUtilisateur(int utilisateurId) {

        String sql = "SELECT MAX(valeur) as meilleur FROM score WHERE utilisateur_id = ?";

        try (Connection conn = connecter();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setInt(1, utilisateurId);

            ResultSet rs = stmt.executeQuery();

            if (rs.next()) {
                return rs.getInt("meilleur");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return 0;
    }

    // Meilleur score global
    public static int recupererMeilleurScoreGlobal() {

        String sql = "SELECT MAX(valeur) as meilleur FROM score";

        try (Connection conn = connecter();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {

            if (rs.next()) {
                return rs.getInt("meilleur");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return 0;
    }

    // Vérifier si un utilisateur existe (par username)
    public static boolean utilisateurExiste(String username) {
        String sql = "SELECT 1 FROM utilisateur WHERE username = ?";

        try (Connection conn = connecter();
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.setString(1, username);

            ResultSet rs = stmt.executeQuery();
            return rs.next();

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return false;
    }

    // Créer un compte et retourner l'id de l'utilisateur créé, ou -1 en cas d'erreur
    public static int creerCompte(String username, String password) {
        if (username == null || username.isBlank() || password == null || password.isBlank()) {
            return -1;
        }

        if (utilisateurExiste(username)) {
            return -1; // déjà existant
        }

        String sql = "INSERT INTO utilisateur(username, password) VALUES(?, ?)";

        try (Connection conn = connecter();
             PreparedStatement stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {

            stmt.setString(1, username);
            stmt.setString(2, password);

            int affected = stmt.executeUpdate();
            if (affected == 0) {
                return -1;
            }

            try (ResultSet keys = stmt.getGeneratedKeys()) {
                if (keys.next()) {
                    return keys.getInt(1);
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return -1;
    }
}