package fr.iutfbleau.papillon;

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

/**
 * La classe <code>RappelBD</code> gère les interactions entre le programme
 * et la table <b>rappel</b> dans la base de données.  
 * <p>
 * Elle permet d'ajouter, de modifier, de supprimer et de lister les rappels
 * associés à un utilisateur spécifique à travers son identifiant (<code>utilisateur_id</code>).
 * </p>
 *
 * @version 1.0
 * @author Seri-khane YOLOU, Aylane SEHL, Jenson VAL
 */
public class RappelBD {

    /**
     * Ajoute un nouveau rappel dans la base de données pour un utilisateur donné.
     *
     * @param r l'objet {@link Rappel} à insérer dans la base
     * @param utilisateurId l'identifiant de l'utilisateur propriétaire du rappel
     * @return l'identifiant du rappel nouvellement inséré, ou -1 en cas d'erreur
     * @throws SQLException si une erreur survient lors de la communication avec la base
     */
    protected static int ajouter(Rappel r, int utilisateurId) throws SQLException {
        Connection cnx = BaseDeDonnees.getConnexion();
        String sql = "INSERT INTO rappel (utilisateur_id, titre, contenu, theme, rang) VALUES (?, ?, ?, ?, ?)";

        PreparedStatement pst = cnx.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        pst.setInt(1, utilisateurId);
        pst.setString(2, r.getTitre());
        pst.setString(3, r.getContenu());
        pst.setString(4, r.getTheme());
        pst.setInt(5, r.getRang());
        pst.executeUpdate();

        ResultSet rs = pst.getGeneratedKeys();
        int id = -1;
        if (rs.next()) {
            id = rs.getInt(1);
        }

        rs.close();
        pst.close();
        cnx.close();

        return id;
    }

    /**
     * Récupère la liste complète des rappels appartenant à un utilisateur.
     *
     * @param utilisateurId l'identifiant de l'utilisateur
     * @return une liste d'objets {@link Rappel} appartenant à cet utilisateur
     * @throws SQLException si une erreur SQL survient lors de l'exécution
     */
    protected static List<Rappel> listerParUtilisateur(int utilisateurId) throws SQLException {
        String sql = "SELECT id, titre, contenu, theme, rang FROM rappel WHERE utilisateur_id = ? ORDER BY rang ASC, id ASC";
        List<Rappel> res = new ArrayList<>();

        Connection cnx = BaseDeDonnees.getConnexion();
        PreparedStatement pst = cnx.prepareStatement(sql);
        pst.setInt(1, utilisateurId);
        ResultSet rs = pst.executeQuery();

        while (rs.next()) {
            Rappel r = new Rappel(
                rs.getInt("id"),
                rs.getString("titre"),
                rs.getString("contenu"),
                rs.getString("theme"),
                rs.getInt("rang")
            );
            res.add(r);
        }

        rs.close();
        pst.close();
        cnx.close();

        return res;
    }

    /**
     * Modifie un rappel existant dans la base de données.
     *
     * @param id l'identifiant du rappel à modifier
     * @param r l'objet {@link Rappel} contenant les nouvelles données
     * @param utilisateurId l'identifiant de l'utilisateur propriétaire du rappel
     * @return le nombre de lignes modifiées (0 si aucun rappel n'a été trouvé)
     * @throws SQLException si une erreur SQL survient
     */
    protected static int modifier(int id, Rappel r, int utilisateurId) throws SQLException {
        Connection cnx = BaseDeDonnees.getConnexion();
        String sql = "UPDATE rappel SET titre = ?, contenu = ?, theme = ?, rang = ? WHERE id = ? AND utilisateur_id = ?";
        PreparedStatement pst = cnx.prepareStatement(sql);
        pst.setString(1, r.getTitre());
        pst.setString(2, r.getContenu());
        pst.setString(3, r.getTheme());
        pst.setInt(4, r.getRang());
        pst.setInt(5, id);
        pst.setInt(6, utilisateurId);

        int res = pst.executeUpdate();

        pst.close();
        cnx.close();

        return res;
    }

    /**
     * Supprime un rappel spécifique appartenant à un utilisateur.
     *
     * @param id l'identifiant du rappel à supprimer
     * @param utilisateurId l'identifiant de l'utilisateur propriétaire
     * @return le nombre de lignes supprimées (0 si aucun rappel correspondant)
     * @throws SQLException si une erreur SQL survient
     */
    protected static int supprimer(int id, int utilisateurId) throws SQLException {
        Connection cnx = BaseDeDonnees.getConnexion();
        String sql = "DELETE FROM rappel WHERE id = ? AND utilisateur_id = ?";
        PreparedStatement pst = cnx.prepareStatement(sql);
        pst.setInt(1, id);
        pst.setInt(2, utilisateurId);

        int res = pst.executeUpdate();

        pst.close();
        cnx.close();

        return res;
    }

    /**
     * Supprime tous les rappels appartenant à un utilisateur spécifique.
     *
     * @param utilisateurId l'identifiant de l'utilisateur dont les rappels doivent être supprimés
     * @return le nombre total de lignes supprimées
     * @throws SQLException si une erreur SQL survient
     */
    protected static int supprimerToutPourUtilisateur(int utilisateurId) throws SQLException {
        Connection cnx = BaseDeDonnees.getConnexion();
        String sql = "DELETE FROM rappel WHERE utilisateur_id = ?";
        PreparedStatement pst = cnx.prepareStatement(sql);
        pst.setInt(1, utilisateurId);
        int lignes = pst.executeUpdate();

        pst.close();
        cnx.close();
        return lignes;
    }
}
