import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Main {
    public static void main(String[] args) {
        // Définition de l'URL de la base de données MySQL à laquelle on veut se connecter
        String url = "jdbc:mysql://localhost:3306/alimentations";
        // Nom d'utilisateur pour se connecter à la base de données
        String utilisateur = "root";
        // Mot de passe pour se connecter à la base de données
        String motDePasse = "";
        Connection connexion = null; // Initialise la connexion à null

        // Le bloc "try" est utilisé pour encapsuler le code qui peut générer des exceptions.
        try {
            // Dans ce cas, nous essayons d'établir une connexion à la base de données et d'exécuter une requête SQL.
            connexion = DriverManager.getConnection(url, utilisateur, motDePasse);
            // Création d'un objet Statement pour exécuter des requêtes SQL
            Statement statement = connexion.createStatement();
            // Exécution de la requête SQL pour sélectionner toutes les lignes de la table "aliments"
            ResultSet resultSet = statement.executeQuery("SELECT * FROM aliments");
                        
            // Boucle pour parcourir les résultats
            while (resultSet.next()) {
                // Extraction des valeurs des colonnes 'nom' et 'poids_moyen' de la ligne actuelle
                String nom = resultSet.getString("nom");
                float poids_moyen = resultSet.getFloat("poids_moyen");
        
                // Affichage des données récupérées
                System.out.println("Nom: " + nom + ", Poids_moyen: " + poids_moyen);
            };

            // Execution d'une 2ème requête qui va afficher le nom des aliments ayant une couleur en BDD
            // par défaut le tri va se faire par l'ID de la couleur
            // On SELECT toutes les colonnes de la table aliments
            // On INNER JOIN la table couleur, en liant l'id de la couleur de la table aliments
            // avec l'id de la couleur de la table couleur
            // Le fait d'avoir SELECT ALL (*), ça permet d'avoir tout SELECT dans la table couleur aussi et ainsi afficher le nom.
            ResultSet resultSet2 = statement.executeQuery(
                "SELECT * FROM aliments " +
                "INNER JOIN couleur ON aliments.couleur_id = couleur.id "
            );
            while (resultSet2.next()) {
                String nom2 = resultSet2.getString("aliments.nom");
                float poids_moyen2 = resultSet2.getFloat("aliments.poids_moyen");
                String couleur = resultSet2.getString("couleur.nom");

                System.out.println("Nom: " + nom2 + ", Poids_moyen: " + poids_moyen2 + ", Couleur:" + couleur);
            };

            // Execution d'une 3ème requête qui va afficher le nom des aliments ayant une couleur ou un type dans la BDD
            // par défaut le tri va se faire par l'ID du type d'aliment
            // On SELECT toutes les colonnes de la table aliments
            // On LEFT JOIN la table couleur, en liant l'id de la couleur de la table aliments
            // avec l'id de la couleur de la table couleur
            // On LEFT JOIN la table type_aliment, en liant l'id du type d'aliment de la table aliments
            // avec l'id du type d'aliment de la table type_aliment
            // Le fait de faire LEFT JOIN permet d'afficher les aliments ayant l'un ou l'autre (soit la couleur, soit le type)
            // Pour gérer l'affichage, on met la condition WHERE pour afficher ceux qui ont au moins un des deux champs en NOT NULL
            // Le fait d'avoir SELECT ALL (*), ça permet d'avoir tout SELECT dans la table couleur aussi et ainsi afficher le nom.
            ResultSet resultSet3 = statement.executeQuery(
                "SELECT * FROM aliments " +
                "LEFT JOIN couleur ON aliments.couleur_id = couleur.id " +
                "LEFT JOIN type_aliment ON aliments.type_id = type_aliment.id " +
                "WHERE couleur.nom IS NOT NULL OR type_aliment.nom IS NOT NULL "
            );
            while (resultSet3.next()) {
                String nom3 = resultSet3.getString("aliments.nom");
                float poids_moyen3 = resultSet3.getFloat("aliments.poids_moyen");
                String couleur3 = resultSet3.getString("couleur.nom");
                String type3 = resultSet3.getString("type_aliment.nom");

                System.out.println("Nom: " + nom3 + ", Poids_moyen: " + poids_moyen3 + ", Couleur:" + couleur3 + ", Type:" + type3);
            };

        } catch (SQLException e) { // Le bloc "catch" est utilisé pour gérer les exceptions qui peuvent être levées dans le bloc "try".
            // Ici, nous gérons les erreurs SQL, par exemple, si la connexion à la base de données échoue ou si la requête SQL est incorrecte.
            System.out.println("Une erreur est survenue lors de l'exécution de la requête SQL.");
            e.printStackTrace(); // Affiche les détails de l'erreur
        } finally { // Le bloc "finally" est utilisé pour contenir du code qui sera exécuté, que des exceptions soient levées ou non.
            // C'est utile pour effectuer des opérations de nettoyage, comme la fermeture de la connexion à la base de données.
            if (connexion != null) { // Le bloc "if" vérifie si la connexion est non nulle avant de tenter de la fermer.
                try {
                    // Fermeture de la connexion à la base de données dans le bloc "finally"
                    connexion.close();
                } catch (SQLException e) {
                    // Gestion des erreurs lors de la fermeture de la connexion
                    System.out.println("Échec de la déconnexion de la base de données");
                    e.printStackTrace(); // Affiche les détails de l'erreur de fermeture
                }
            }
        } 
    }
}
