Source: screens/screens/commandeContext.js

/**
 * @file commandeContext.js
 * @description Composant d'affichage du Panier.
 * Il permet de visualiser les articles ajoutés, de modifier les quantités,
 * de supprimer des articles et de consulter le récapitulatif financier (HT/TVA/TTC).
 */

import React from 'react';
import { Text, TouchableOpacity, View, ScrollView, Image, StyleSheet } from 'react-native';
import ProtectedRoute from "../components/ProtectedRoute";
import { usePanier } from './store';
import { EXPO_PUBLIC_API_URL } from "../config";
import { GlobalStyles } from '../styles/GlobalStyles';

/**
 * Composant principal de l'écran Panier.
 * * @component
 * @param {Object} props - Propriétés du composant.
 * @param {Object} props.navigation - Objet de navigation fourni par React Navigation pour la redirection vers la validation.
 * @returns {React.JSX.Element} L'interface utilisateur du panier avec la liste des articles et le récapitulatif.
 */
const CommandeContext = ({ navigation }) => {

    /** * Récupération des données et fonctions globales du panier depuis le Store.
     * @see {@link ./store.js} pour la logique de modification/suppression.
     */
    const { panier, supprimerDuPanier, modifierQuantite } = usePanier();

    /** * Calcul du montant total Hors Taxes (HT).
     * @type {number}
     */
    const totalGeneral = panier.reduce((sum, item) => sum + (item.prix * item.quantite), 0);

    /** * Calcul du montant de la TVA (basé sur un taux de 20%).
     * @type {number}
     */
    const tva = totalGeneral * 0.20;

    return (
        <ProtectedRoute>
            <ScrollView style={styles.cardScreen}>
                <View style={{ paddingVertical: 20 }}>
                    <Text style={styles.mainTitle}>
                        Mon Panier ({panier.length})
                    </Text>

                    {panier.length === 0 ? (
                        <View style={GlobalStyles.profileCard}>
                            <Text style={GlobalStyles.emptyText}>Votre panier est vide.</Text>
                        </View>
                    ) : (
                        <>
                            {panier.map((item, index) => (
                                /**
                                 * Rendu individuel de chaque article du panier.
                                 * Clé basée sur l'index (attention : privilégier l'id en production).
                                 */
                                <View key={index} style={styles.cartCard}>
                                    <View style={styles.cartItemContent}>

                                        {/* Image du produit récupérée depuis le serveur distant */}
                                        <Image
                                            source={{ uri: `${EXPO_PUBLIC_API_URL}/images/produits/${item.imageUrl}` }}
                                            style={styles.productImage}
                                        />

                                        {/* Informations textuelles du produit */}
                                        <View style={styles.productInfo}>
                                            <Text style={styles.designationText} numberOfLines={1}>
                                                {item.designation}
                                            </Text>
                                            <Text style={styles.unitPriceText}>{item.prix.toFixed(2)} € / unité</Text>
                                            <Text style={styles.totalItemPrice}>
                                                {(item.prix * item.quantite).toFixed(2)} €
                                            </Text>
                                        </View>

                                        {/* Actions : Augmenter, Diminuer, Supprimer */}
                                        <View style={styles.actionColumn}>
                                            <View style={styles.stepper}>

                                                {/* Diminuer la quantité (limité à 1 minimum par le store) */}
                                                <TouchableOpacity
                                                    style={styles.stepBtn}
                                                    onPress={() => modifierQuantite(item.id, -1)}
                                                >
                                                    <Image
                                                        source={require('../assets/bouttonDiminuer.jpg')}
                                                        style={styles.imageIcon}
                                                    />
                                                </TouchableOpacity>

                                                <Text style={styles.quantityValue}>{item.quantite}</Text>

                                                {/* Augmenter la quantité */}
                                                <TouchableOpacity
                                                    style={styles.stepBtn}
                                                    onPress={() => modifierQuantite(item.id, 1)}
                                                >
                                                    <Image
                                                        source={require('../assets/bouttonAjouter.jpg')}
                                                        style={styles.imageIcon}
                                                    />
                                                </TouchableOpacity>
                                            </View>

                                            {/* Suppression définitive de la ligne */}
                                            <TouchableOpacity
                                                onPress={() => supprimerDuPanier(item.id)}
                                                style={styles.trashBtn}
                                            >
                                                <Image
                                                    source={require('../assets/poubelle.jpg')}
                                                    style={styles.imageIconTrash}
                                                />
                                            </TouchableOpacity>
                                        </View>
                                    </View>
                                </View>
                            ))}

                            {/* Carte récapitulative finale avant paiement/validation */}
                            <View style={styles.summaryCard}>
                                <Text style={styles.summaryTitle}>Récapitulatif</Text>

                                <View style={styles.summaryRow}>
                                    <Text style={styles.summaryLabel}>Sous-total HT</Text>
                                    <Text style={styles.summaryValue}>{totalGeneral.toFixed(2)} €</Text>
                                </View>

                                <View style={styles.summaryRow}>
                                    <Text style={styles.summaryLabel}>TVA (20%)</Text>
                                    <Text style={styles.summaryValue}>{tva.toFixed(2)} €</Text>
                                </View>

                                <View style={[styles.summaryRow, styles.totalRow]}>
                                    <Text style={styles.totalLabel}>Total TTC</Text>
                                    <Text style={styles.totalAmount}>{(totalGeneral + tva).toFixed(2)} €</Text>
                                </View>

                                /**
                                * Navigation vers l'écran de validation.
                                * @param {string} "ValidationCommande" - Nom de la route.
                                * @param {Object} params - Données transmises (HT et TVA).
                                */
                                <TouchableOpacity
                                    onPress={() => navigation.navigate('ValidationCommande', { totalHT: totalGeneral, tva: tva })}
                                    style={styles.checkoutBtn}
                                >
                                    <Text style={styles.checkoutBtnText}>Valider la commande</Text>
                                </TouchableOpacity>
                            </View>
                        </>
                    )}
                </View>
            </ScrollView>
        </ProtectedRoute>
    );
};

export default CommandeContext;

/** * Styles locaux spécifiques à la mise en page du panier et du stepper.
 * @type {StyleSheet}
 */


const styles = StyleSheet.create({
    cardScreen: { flex: 1, backgroundColor: '#F8F9FB' },
    mainTitle: {
        fontSize: 22,
        fontWeight: '800',
        color: '#1A1A1A',
        marginHorizontal: 20,
        marginBottom: 15,
    },
    cartCard: {
        backgroundColor: '#FFF',
        marginHorizontal: 20,
        marginVertical: 8,
        borderRadius: 16,
        padding: 12,
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.05,
        shadowRadius: 8,
        elevation: 3,
    },
    cartItemContent: { flexDirection: 'row', alignItems: 'center' },
    productImage: { width: 85, height: 85, borderRadius: 12, backgroundColor: '#F0F0F0' },
    productInfo: { flex: 1, paddingHorizontal: 15 },
    designationText: { fontSize: 15, fontWeight: '700', color: '#2D3436', marginBottom: 4 },
    unitPriceText: { fontSize: 13, color: '#636E72', marginBottom: 8 },
    totalItemPrice: { fontSize: 17, fontWeight: '900', color: '#1E3C72' },

    // Design du Stepper
    actionColumn: { alignItems: 'flex-end', justifyContent: 'space-between', height: 85 },
    stepper: {
        flexDirection: 'row',
        alignItems: 'center',
        backgroundColor: '#F1F3F5',
        borderRadius: 10,
        padding: 4
    },
    stepBtn: {
        width: 30,
        height: 30,
        justifyContent: 'center',
        alignItems: 'center',
    },
    // Style pour tes images JPG/PNG dans les boutons
    imageIcon: {
        width: 24,
        height: 24,
        resizeMode: 'contain',
        borderRadius: 4
    },
    imageIconTrash: {
        width: 20,
        height: 20,
        resizeMode: 'contain',
    },
    quantityValue: { paddingHorizontal: 12, fontWeight: '700', fontSize: 14 },
    trashBtn: {
        padding: 8,
        backgroundColor: '#FFF5F5',
        borderRadius: 10,
        borderWidth: 1,
        borderColor: '#FFEBEB'
    },

    // Carte Récapitulatif
    summaryCard: {
        backgroundColor: '#FFF',
        margin: 20,
        padding: 20,
        borderRadius: 20,
        borderWidth: 1,
        borderColor: '#EEE',
    },
    summaryTitle: { fontSize: 18, fontWeight: '800', marginBottom: 15, color: '#1A1A1A' },
    summaryRow: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 10 },
    summaryLabel: { color: '#636E72', fontSize: 14 },
    summaryValue: { fontWeight: '600', color: '#2D3436' },
    totalRow: { marginTop: 10, paddingTop: 15, borderTopWidth: 1, borderTopColor: '#EEE' },
    totalLabel: { fontSize: 16, fontWeight: '800' },
    totalAmount: { fontSize: 20, fontWeight: '900', color: '#1E3C72' },

    checkoutBtn: {
        backgroundColor: '#1E3C72',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        marginTop: 20,
        paddingVertical: 16,
        borderRadius: 14,
    },
    checkoutBtnText: { color: '#FFF', fontWeight: 'bold', fontSize: 16, textTransform: 'uppercase' }
});