Source: screens/store.js

/**
 * @file store.js
 * @description Contexte global du panier d'achat (PanierContext).
 * Fournit les fonctions pour ajouter, modifier, supprimer et vider le panier,
 * ainsi qu'un hook personnalisé pour y accéder depuis n'importe quel composant.
 */

import React, { createContext, useState, useContext } from 'react';

/**
 * Contexte React interne du panier.
 * Ne pas utiliser directement — préférer le hook {@link usePanier}.
 * @type {React.Context}
 */
const PanierContext = createContext();

/**
 * Fournisseur du contexte panier.
 * Doit envelopper tous les composants qui ont besoin d'accéder au panier.
 *
 * @component
 * @param {Object} props
 * @param {React.ReactNode} props.children - Les composants enfants à envelopper.
 * @returns {React.JSX.Element} Le Provider exposant le panier et ses actions.
 */
export const PanierProvider = ({ children }) => {
    const [panier, setPanier] = useState([]);
    //console.log(panier);

    /**
     * Ajoute un produit au panier ou incrémente sa quantité s'il est déjà présent.
     * Refuse l'ajout si le produit ne possède pas d'identifiant.
     *
     * @param {Object} produit - Le produit à ajouter.
     * @param {number|string} produit.id - L'identifiant unique du produit (obligatoire).
     * @param {string} produit.designation - Le nom du produit.
     * @param {number} produit.prix - Le prix unitaire HT.
     * @param {string} [produit.imageUrl] - L'URL relative de l'image.
     * @param {number} [produit.quantite=1] - La quantité à ajouter (défaut : 1).
     */
    const ajouterAuPanier = (produit) => {
        if (!produit?.id) {
            console.error("Tentative d'ajout d'un produit sans ID :", produit);
            return; // On bloque l'ajout silencieux
        }
        setPanier((prevPanier) => {
            const existe = prevPanier.find(item => item.id === produit.id);
            if (existe) {
                return prevPanier.map(item =>
                    item.id === produit.id
                        ? { ...item, quantite: item.quantite + (produit.quantite || 1) }
                        : item
                );
            }
            return [...prevPanier, { ...produit, quantite: produit.quantite || 1 }];
        });
    };

    /**
     * Modifie la quantité d'un article du panier par un delta positif ou négatif.
     * La quantité minimale est 1 (ne peut pas descendre en dessous).
     *
     * @param {number|string} id - L'identifiant de l'article à modifier.
     * @param {number} delta - La variation de quantité (ex. : +1 ou -1).
     */
    const modifierQuantite = (id, delta) => {
        setPanier((prevPanier) =>
            prevPanier.map((item) => {
                if (item.id === id) {
                    const nouvelleQuantite = item.quantite + delta;
                    // On retourne l'item avec la nouvelle quantité (minimum 1)
                    return { ...item, quantite: nouvelleQuantite < 1 ? 1 : nouvelleQuantite };
                }
                return item;
            })
        );
    };

    /**
     * Supprime définitivement un article du panier.
     *
     * @param {number|string} id - L'identifiant de l'article à supprimer.
     */
    const supprimerDuPanier = (id) => {
        setPanier(prevPanier => prevPanier.filter(item => item.id !== id));
    };

    /**
     * Vide intégralement le panier (remet le tableau à zéro).
     */
    const viderPanier = () => setPanier([]);

    return (
        <PanierContext.Provider value={{
            panier,
            ajouterAuPanier,
            modifierQuantite,
            supprimerDuPanier,
            viderPanier
        }}>
            {children}
        </PanierContext.Provider>
    );
};

/**
 * Hook personnalisé pour accéder au contexte du panier.
 * Doit être utilisé à l'intérieur d'un composant enveloppé par {@link PanierProvider}.
 *
 * @returns {{
 *   panier: Array<Object>,
 *   ajouterAuPanier: Function,
 *   modifierQuantite: Function,
 *   supprimerDuPanier: Function,
 *   viderPanier: Function
 * }} Les données et actions du panier.
 */
export const usePanier = () => useContext(PanierContext);