Source: screens/Home.js

/**
 * @file Home.js
 * @description Écran d'accueil de l'application.
 * Affiche deux sections de produits récupérées en parallèle depuis l'API :
 * les articles en vedette et les articles en promotion, sous forme de listes horizontales défilantes.
 */

import React, {Component, useEffect, useState} from 'react';
import {EXPO_PUBLIC_API_URL} from "../config";
import {
    ActivityIndicator,
    FlatList,
    Image,
    ScrollView,
    StyleSheet,
    Text,
    TouchableOpacity,
    View,
    Dimensions
} from 'react-native';
import {useNavigation} from "@react-navigation/native";
import {GlobalStyles} from "../styles/GlobalStyles";
import ProtectedRoute from "../components/ProtectedRoute";

/** Largeur de l'écran du device, utilisée pour le calcul de la largeur des cartes. */
const { width: screenWidth } = Dimensions.get('window');

/**
 * Écran d'accueil affichant les produits en vedette et en promotion.
 *
 * @component
 * @returns {React.JSX.Element} L'interface de la page d'accueil avec les listes de produits.
 */
export default function Home() {
    /** @type {[Array<Object>, Function]} Liste des produits en vedette. */
    const [featuredData, setFeaturedData] = useState([]);

    /** @type {[Array<Object>, Function]} Liste des produits en promotion. */
    const [promoData, setPromoData] = useState([]);

    /** @type {[boolean, Function]} Indicateur de chargement des données. */
    const [loading, setLoading] = useState(true);

    /** @type {[string|null, Function]} Message d'erreur en cas d'échec de fetch. */
    const [error, setError] = useState(null);

    const navigation = useNavigation();

    useEffect(() => {
        const abortController = new AbortController();
        const signal = abortController.signal;

        /**
         * Récupère en parallèle les produits en vedette et en promotion depuis l'API.
         * Utilise Promise.all pour optimiser les temps de chargement.
         * En cas d'erreur réseau ou API, met à jour l'état d'erreur.
         *
         * @async
         * @returns {Promise<void>}
         */
        const fetchAllData = async () => {
            setLoading(true);
            setError(null);
            try {
                // 1. On prépare les deux requêtes
                const featuredPromise = fetch(
                    `${EXPO_PUBLIC_API_URL}/produits/vedette`,
                    { signal }
                );
                const promoPromise = fetch(
                    `${EXPO_PUBLIC_API_URL}/produits/promotion`,
                    { signal }
                );

                // 2. On attend les DEUX
                const [featuredResponse, promoResponse] = await Promise.all([
                    featuredPromise,
                    promoPromise
                ]);

                // 3. On vérifie les DEUX
                if (!featuredResponse.ok) {
                    const errorData = await featuredResponse.json().catch(() => ({}));
                    throw new Error(errorData.message || "Erreur lors de la récupération des produits vedette.");
                }
                if (!promoResponse.ok) {
                    const errorData = await promoResponse.json().catch(() => ({}));
                    throw new Error(errorData.message || "Erreur lors de la récupération des promotions.");
                }

                // 4. On récupère le JSON des DEUX
                const [featuredList, promoList] = await Promise.all([
                    featuredResponse.json(),
                    promoResponse.json()
                ]);

                setFeaturedData(featuredList);
                setPromoData(promoList);

            } catch(error) {
                if (error.name !== 'AbortError') {
                    console.error("Erreur de fetch produits:", error.message);
                    setError(error.message || "Impossible de charger les produits. Veuillez réessayer.");
                }
            } finally {
                setLoading(false);
            }
        };

        fetchAllData();
        return () => abortController.abort();

    }, []);


    if (loading) {
        return (
            <View style={GlobalStyles.loadingContainer}>
                <ActivityIndicator size="large" color="#1e3c72" />
                <Text style={GlobalStyles.loadingText}>Chargement des produits...</Text>
            </View>
        );
    }

    if (error) {
        return (
            <View style={GlobalStyles.container}>
                <Text style={GlobalStyles.errorText}>{error}</Text>
            </View>
        );
    }

    if (featuredData.length === 0 && promoData.length === 0) {
        return (
            <View style={GlobalStyles.container}>
                <Text style={GlobalStyles.emptyText}>Aucun produit disponible pour le moment.</Text>
            </View>
        );
    }

    /**
     * Navigue vers l'écran de détail d'un produit.
     *
     * @param {Object} item - Le produit sélectionné.
     */
    const handleConsult = (item) => {
        navigation.navigate('ProductDetail', { product: item });
    };

    /**
     * Déclenche l'ajout d'un produit au panier.
     * (Logique à implémenter via le store.)
     *
     * @param {Object} item - Le produit à ajouter au panier.
     */
    const handleAddToCart = (item) => {
        console.log("Ajout au panier:", item.designation);
        // Logique d'ajout au panier ici
    };

    /**
     * Largeur d'une carte produit, calculée à 85% de la largeur de l'écran.
     * @type {number}
     */
    const cardWidth = screenWidth * 0.85;

    /**
     * Intervalle de snap pour la FlatList horizontale, égal à la largeur d'une carte + sa marge.
     * @type {number}
     */
    const snapInterval = cardWidth + (styles.cardWrapper.marginRight || 0);

    return (

            <ScrollView style={GlobalStyles.profileScreen}>

                {/* Articles en Vedette — section affichée uniquement s'il y a des données */}
                {featuredData.length > 0 && (
                    <View>
                        <Text style={styles.sectionTitle}>Les articles en Vedette ✨</Text>
                        <FlatList
                            data={featuredData}
                            keyExtractor={(item) => 'feat-' + item.reference.toString()}
                            horizontal={true}
                            showsHorizontalScrollIndicator={false}
                            contentContainerStyle={styles.horizontalFlatListContainer}
                            snapToInterval={snapInterval}
                            decelerationRate="fast"
                            renderItem={({ item }) => (
                                <View style={[styles.cardWrapper, { width: cardWidth }]}>
                                    <TouchableOpacity onPress={() => navigation.navigate("ProductsCard", item)}>
                                        <View style={styles.productCardHorizontal}>
                                            <Image
                                                source={{ uri:`${EXPO_PUBLIC_API_URL}` + "/images/produits/" +  item.imageUrl }}
                                                style={styles.productImageHorizontal}
                                            />
                                        </View>
                                    </TouchableOpacity>
                                    <Text style={styles.productNameHorizontal}>{item.designation}</Text>
                                    <Text style={styles.productPriceHorizontal}>{item.prix_unitaire_HT} €</Text>
                                </View>
                            )}
                        />
                    </View>
                )}

                {/* Articles en Promotion — section affichée uniquement s'il y a des données */}
                {promoData.length > 0 && (
                    <View>
                        <Text style={styles.sectionTitle}>Les articles en PROMOTION ✨</Text>
                        <FlatList
                            data={promoData}
                            keyExtractor={(item) => 'promo-' + item.reference.toString()}
                            horizontal={true}
                            showsHorizontalScrollIndicator={false}
                            contentContainerStyle={styles.horizontalFlatListContainer}
                            snapToInterval={snapInterval}
                            decelerationRate="fast"
                            renderItem={({ item }) => (

                                <View style={[styles.cardWrapper, { width: cardWidth }]}>
                                    <TouchableOpacity onPress={() => navigation.navigate("ProductsCard", item)}>
                                        <View style={styles.productCardHorizontal}>
                                            <Image
                                                source={{ uri:`${EXPO_PUBLIC_API_URL}`+"/images/produits/" + item.imageUrl }}
                                                style={styles.productImageHorizontal}
                                            />
                                        </View>
                                    </TouchableOpacity>
                                    <Text style={styles.productNameHorizontal}>{item.designation}</Text>
                                    {/* Prix barré (ancien prix) et nouveau prix promotion */}
                                    <View style={styles.promoPriceContainer}>
                                        <Text style={styles.oldPrice}>{item.prix_initiale} €</Text>
                                        <Text style={styles.newPrice}>{item.nouveau_prix} €</Text>
                                    </View>
                                </View>
                            )}
                        />
                    </View>
                )}
            </ScrollView>

    );
};

/**
 * Styles locaux de l'écran Home.
 * @type {import('react-native').StyleSheet.NamedStyles<any>}
 */
const styles = StyleSheet.create({
    cardScreen: {
        flex: 1,
        backgroundColor: '#f0f2f5',
    },
    cardContainer: {
        backgroundColor: '#ffffff',
        margin: 15,
        borderRadius: 12,
        padding: 20,
        alignItems: 'center',
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.1,
        shadowRadius: 4,
        elevation: 5,
    },
    productDetailImage: {
        width: '100%',
        height: 250,
        resizeMode: 'contain',
        borderRadius: 10,
        marginBottom: 20,
    },
    productDetailName: {
        fontSize: 24,
        fontWeight: 'bold',
        color: '#333',
        marginBottom: 10,
        textAlign: 'center',
    },
    productDetailPrice: {
        fontSize: 28,
        fontWeight: 'bold',
        color: '#1e3c72',
        marginBottom: 20,
        textAlign: 'center',
    },
    productDetailDescription: {
        fontSize: 16,
        color: '#555',
        textAlign: 'left',
        marginBottom: 20,
        lineHeight: 24,
    },
    addToCartButton: {
        backgroundColor: '#28a745',
        paddingVertical: 15,
        paddingHorizontal: 30,
        borderRadius: 8,
        marginTop: 20,
    },
    addToCartButtonText: {
        color: '#ffffff',
        fontSize: 18,
        fontWeight: 'bold',
    },
    descriptionContainer: {
        width: '100%',
        marginBottom: 20,
    },
    descriptionText: {
        fontSize: 16,
        color: '#555',
        textAlign: 'left',
        lineHeight: 24,
    },
    descriptionTitle: {
        fontWeight: 'bold',
        color: '#333',
        fontSize: 17,
    },
    descriptionBold: {
        fontWeight: 'bold',
        color: '#555',
    },

    // --- STYLES POUR LA FLATLIST HORIZONTALE ---
    sectionTitle: {
        fontSize: 22,
        fontWeight: 'bold',
        color: '#333',
        marginLeft: 15,
        marginTop: 20,
        marginBottom: 15,
    },
    horizontalFlatListContainer: {
        paddingHorizontal: 15,
        paddingBottom: 20,
    },
    cardWrapper: {
        height: 280,
        marginRight: 10,
    },
    productCardHorizontal: {
        backgroundColor: '#ffffff',
        borderRadius: 12,
        height: 220,
        width: '100%',
        justifyContent: 'center',
        alignItems: 'center',
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.1,
        shadowRadius: 4,
        elevation: 5,
        position: 'relative',
        overflow: 'hidden',
    },
    productImageHorizontal: {
        width: '80%',
        height: '80%',
        resizeMode: 'contain',
    },
    productNameHorizontal: {
        fontSize: 16,
        fontWeight: 'bold',
        color: '#333',
        marginTop: 10,
        textAlign: 'left',
        paddingHorizontal: 5,
    },
    productPriceHorizontal: {
        fontSize: 18,
        fontWeight: 'bold',
        color: '#1e3c72',
        marginTop: 5,
        textAlign: 'left',
        paddingHorizontal: 5,
    },
    promoTag: {
        position: 'absolute',
        top: 15,
        left: 15,
        backgroundColor: 'white',
        borderRadius: 20,
        paddingHorizontal: 12,
        paddingVertical: 6,
        zIndex: 1,
        flexDirection: 'row',
        alignItems: 'center',
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 1 },
        shadowOpacity: 0.1,
        shadowRadius: 2,
        elevation: 3,
    },
    promoTagText: {
        color: 'black',
        fontSize: 12,
        fontWeight: 'bold',
        marginLeft: 4,
    },
    addToCartIcon: {
        position: 'absolute',
        bottom: 15,
        right: 15,
        backgroundColor: '#007bff',
        borderRadius: 20,
        width: 40,
        height: 40,
        justifyContent: 'center',
        alignItems: 'center',
        zIndex: 1,
    },
    addToCartIconText: {
        color: 'white',
        fontSize: 24,
        lineHeight: 24,
        fontWeight: 'bold',
    },
    promoCard: {
        flex: 1,
        margin: 5,
        backgroundColor: 'white',
        borderRadius: 8,
        padding: 10,
        alignItems: 'center',
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 1 },
        shadowOpacity: 0.1,
        shadowRadius: 3,
        elevation: 3,
        maxWidth: '48%',
    },

    // Styles pour les boutons
    buttonContainer: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        width: '100%',
        marginTop: 8,
        marginBottom: 8,
    },
    consultButton: {
        backgroundColor: '#6c757d',
        paddingVertical: 6,
        paddingHorizontal: 8,
        borderRadius: 5,
        flex: 1,
        marginRight: 4,
        alignItems: 'center',
    },
    addButton: {
        backgroundColor: '#28a745',
        paddingVertical: 6,
        paddingHorizontal: 8,
        borderRadius: 5,
        flex: 1,
        marginLeft: 4,
        alignItems: 'center',
    },
    buttonText: {
        color: '#ffffff',
        fontSize: 12,
        fontWeight: 'bold',
    },

    // Styles pour les prix barrés
    promoPriceContainer: {
        flexDirection: 'row',
        alignItems: 'center',
        marginTop: 5,
        paddingHorizontal: 5,
    },
    oldPrice: {
        fontSize: 14,
        color: '#6c757d',
        textDecorationLine: 'line-through',
        marginRight: 8,
    },
    newPrice: {
        fontSize: 18,
        fontWeight: 'bold',
        color: '#D90429',
    },

});