package fr.iutfbleau.papillon;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * La classe <code>PanelRappel</code> représente l’affichage graphique
 * d’un rappel dans l’application <b>Papillon</b>.
 * <p>
 * Chaque panneau contient le titre, un aperçu du contenu, ainsi qu’une
 * couleur correspondant au thème du rappel.  
 * L’utilisateur peut interagir avec ce panneau (sélection, clic droit, etc.).
 * </p>
 *
 * @version 1.0
 * @author Seri-khane YOLOU, Aylane SEHL, Jenson VAL
 */
public class PanelRappel extends JPanel implements ActionListener, MouseListener {
    
    /** Indique si le rappel est actuellement sélectionné. */
    private boolean estSelectionne = false;

    /** Label affichant le titre du rappel. */
    private  JLabel lbtitre;

    /** Label affichant un aperçu du contenu du rappel. */
    private  JLabel lbcontenu;

    /** Référence vers le rappel associé à ce panneau. */
    private  Rappel r;

    /** Menu contextuel (clic droit). */
    private  JPopupMenu menu;

    /** Élément du menu permettant d’ouvrir le rappel. */
    private  JMenuItem itemOuvrir;

    /** Référence à la fenêtre principale. */
    private Main main;

    /** Liste des couleurs disponibles pour les thèmes. */
    private static CouleurList couleur = new CouleurList();

    /**
     * Constructeur du panneau associé à un rappel et à la fenêtre principale.
     *
     * @param r le rappel à afficher
     * @param main la fenêtre principale
     */
    public PanelRappel(Rappel r, Main main) {
        super(new BorderLayout(2, 0));
        this.main = main;
        createPanel(r);
    }

    /**
     * Constructeur du panneau associé à un rappel sans référence à la fenêtre principale.
     *
     * @param r le rappel à afficher
     */
    public PanelRappel(Rappel r) {
        super(new BorderLayout(2, 0));
        createPanel(r);
    }

    /**
     * Initialise et configure le panneau pour afficher les informations du rappel.
     *
     * @param r le rappel à afficher
     */
    public void createPanel(Rappel r){
        this.r = r;

        //  Titre et contenu raccourci 
        lbtitre = new JLabel("[" + r.getRang() + "] " + r.getTitre());
        lbcontenu = new JLabel(
            "<html>" + (r.getContenu().length() > 40 ? r.getContenu().substring(0, 40) + "..." : r.getContenu()) + "</html>"
        );

        // - Apparence de base 
        this.setPreferredSize(new Dimension(70, 50));
        this.setBackground(couleur.couleurDe(r.getTheme()));
        this.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 2));

        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.anchor = GridBagConstraints.NORTHWEST;

        // - Position du titre 
        c.gridx = 0; 
        c.gridy = 0; 
        c.weightx = 1;
        c.fill = GridBagConstraints.NONE;
        add(lbtitre, c);

        // -Position du contenu 
        c.gridx = 0; 
        c.gridy = 1; 
        c.weightx = 1;
        c.fill = GridBagConstraints.NONE;
        add(lbcontenu, c);

        // - Menu contextuel (clic droit) 
        menu = new JPopupMenu();
        itemOuvrir = new JMenuItem("Ouvrir");
        itemOuvrir.addActionListener(this);
        menu.add(itemOuvrir);

        // - Activation des clics 
        addMouseListener(this);
    }

    // GETTERS


    /**
     * Indique si le panneau est actuellement sélectionné.
     *
     * @return true si le panneau est sélectionné, false sinon
     */
    public boolean getSelection() {
        return estSelectionne;
    }

    /**
     * Renvoie l’identifiant du rappel affiché.
     *
     * @return l’identifiant unique du rappel
     */
    public int getId() {
        return r.getId();
    }

    /**
     * Renvoie le rappel associé à ce panneau.
     *
     * @return le rappel affiché dans ce panneau
     */
    public Rappel getRappel() {
        return r;
    }


    /**
     * Gère les actions déclenchées par les éléments du menu contextuel.
     * <p>
     * Si l’utilisateur clique sur "Ouvrir", la fenêtre détaillée du rappel est affichée.
     * </p>
     *
     * @param e l’événement d’action déclenché
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        Object src = e.getSource();

        if (src == itemOuvrir) {
            // ouverture complète depuis le menu clic droit
            new FenetreRappel(r, main);
        }
    }

    /**
     * Gère les clics de souris sur le panneau.
     * <p>
     * Un clic gauche sélectionne/désélectionne le panneau,  
     * tandis qu’un clic droit affiche le menu contextuel.
     * </p>
     *
     * @param e l’événement de souris détecté
     */
    @Override
    public void mousePressed(MouseEvent e) {
        if (e.isPopupTrigger()) {
            menu.show(e.getComponent(), e.getX(), e.getY());
        } else {
            // clic gauche = sélection / désélection
            estSelectionne = !estSelectionne;
            majApparence();
        }
    }


    /**
     * Gère la libération du clic de souris.
     * <p>
     * Si le clic est un clic droit, le menu contextuel s’affiche.
     * </p>
     *
     * @param e l’événement de souris
     */
    @Override
    public void mouseReleased(MouseEvent e) {
        if (e.isPopupTrigger()) {
            menu.show(e.getComponent(), e.getX(), e.getY());
        }
    }


    /**
     * Gère les clics simples ou doubles sur le panneau.
     * <p>
     * Un double clic gauche ouvre la fenêtre de rappel complète.
     * </p>
     *
     * @param e l’événement de souris
     */
    @Override
    public void mouseClicked(MouseEvent e) {
        // === Double clic pour ouvrir la vue complète ===
        if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) {
            new FenetreRappel(r, main);

        }
    }

    /**
     * Change l’apparence du panneau lorsque la souris entre dans sa zone.
     *
     * @param e l’événement de souris
     */
    @Override
    public void mouseEntered(MouseEvent e) {
        setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
    }

    /**
     * Restaure la bordure du panneau lorsque la souris quitte sa zone.
     *
     * @param e l’événement de souris
     */
    @Override
    public void mouseExited(MouseEvent e) {
        setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
        
    }

    /**
     * Met à jour l’apparence du panneau en fonction de son état de sélection.
     * <p>
     * Si le panneau est sélectionné, son fond devient gris clair
     * et une bordure noire est appliquée.  
     * Sinon, la couleur de fond correspond au thème du rappel.
     * </p>
     */
    private void majApparence() {
        if (estSelectionne) {
            setBackground(Color.LIGHT_GRAY);
            setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
        } else {
            setBackground(couleur.couleurDe(r.getTheme()));
        }
        
    }
}
