/**
* @file ValidationCommande.js
* @description Écran de confirmation et validation d'une commande.
* Affiche le récapitulatif final (client, dates, articles, totaux HT/TVA/TTC)
* avant de soumettre la commande à l'API. En cas de succès, vide le panier
* et redirige vers l'historique des commandes.
*/
import React, { useState } from 'react';
import { Text, TouchableOpacity, View, ScrollView, StyleSheet, Alert, ActivityIndicator } from 'react-native';
import ProtectedRoute from "../components/ProtectedRoute";
import { usePanier } from './store';
import useAuth from "../hooks/useAuth";
import { EXPO_PUBLIC_API_URL } from "../config";
/**
* Écran de validation finale de la commande.
* Reçoit les totaux HT et TVA via les paramètres de route, calculés par l'écran Panier.
*
* @component
* @param {Object} props
* @param {Object} props.navigation - Objet de navigation React Navigation.
* @param {Object} props.route - Objet de route contenant les paramètres transmis.
* @param {number} props.route.params.totalHT - Montant total hors taxes.
* @param {number} props.route.params.tva - Montant de la TVA (20%).
* @returns {React.JSX.Element} Le récapitulatif de commande avec les boutons Retour et Confirmer.
*/
const ValidationCommande = ({ navigation, route }) => {
const { panier, viderPanier } = usePanier();
const { token, user } = useAuth();
/** @type {[boolean, Function]} Indicateur d'envoi en cours pour désactiver le bouton de confirmation. */
const [isSubmitting, setIsSubmitting] = useState(false);
/**
* Montant total hors taxes transmis depuis l'écran Panier.
* @type {number}
*/
const totalHT = route.params?.totalHT || 0;
/**
* Montant de la TVA transmis depuis l'écran Panier.
* @type {number}
*/
const tva = route.params?.tva || 0;
/**
* Montant total TTC calculé à partir du HT et de la TVA.
* @type {number}
*/
const totalTTC = totalHT + tva;
/**
* Date de la commande (aujourd'hui).
* @type {Date}
*/
const dateCommande = new Date();
/**
* Date de livraison estimée (J+3).
* @type {Date}
*/
const dateLivraison = new Date();
dateLivraison.setDate(dateCommande.getDate() + 3);
/**
* Envoie la commande à l'API avec le contenu du panier et les totaux financiers.
* En cas de succès, vide le panier local et redirige vers l'historique des commandes.
* En cas d'erreur, affiche une alerte avec le message de l'API.
*
* @async
* @returns {Promise<void>}
*/
const handleValiderCommande = async () => {
if (panier.length === 0) return;
setIsSubmitting(true);
try {
const response = await fetch(`${EXPO_PUBLIC_API_URL}/commande/valider`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
panier: panier,
totalHT: totalHT,
totalTVA: tva,
dateLivraison: dateLivraison.toISOString().split('T')[0] // Format YYYY-MM-DD pour MySQL
})
});
const result = await response.json();
if (response.ok) {
Alert.alert("Succès", `Commande n°${result.numero} validée !`);
viderPanier();
navigation.navigate('HistoriqueCommande');
} else {
throw new Error(result.message || "Erreur lors de la validation");
}
} catch (error) {
Alert.alert("Erreur", error.message);
} finally {
setIsSubmitting(false);
}
};
return (
<ProtectedRoute>
<ScrollView style={styles.container}>
<View style={styles.card}>
<Text style={styles.title}>Récapitulatif Final</Text>
{/* Section Client et Dates */}
<View style={styles.section}>
<Text style={styles.label}>Client : <Text style={styles.value}>{user.nom}</Text></Text>
<Text style={styles.label}>Date : <Text style={styles.value}>{dateCommande.toLocaleDateString('fr-FR')}</Text></Text>
<Text style={styles.label}>Livraison estimée : <Text style={styles.value}>{dateLivraison.toLocaleDateString('fr-FR')}</Text></Text>
</View>
{/* Détails des articles du panier */}
<View style={styles.section}>
<Text style={styles.subTitle}>Détails de la commande :</Text>
{panier.map((item,index) => (
<View key={index} style={styles.itemRow}>
<Text style={styles.itemName}>{item.designation} (x{item.quantite})</Text>
<Text style={styles.itemPrice}>{(item.prix * item.quantite).toFixed(2)} €</Text>
</View>
))}
</View>
{/* Totaux financiers HT / TVA / TTC */}
<View style={styles.totalSection}>
<View style={styles.row}>
<Text>Total HT :</Text>
<Text>{totalHT.toFixed(2)} €</Text>
</View>
<View style={styles.row}>
<Text>TVA (20%) :</Text>
<Text>{tva.toFixed(2)} €</Text>
</View>
<View style={[styles.row, styles.borderTop]}>
<Text style={styles.totalLabel}>Total TTC :</Text>
<Text style={styles.totalValue}>{totalTTC.toFixed(2)} €</Text>
</View>
</View>
{/* Boutons de navigation : retour ou confirmation */}
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.btnBack}
onPress={() => navigation.goBack()}
>
<Text style={styles.btnBackText}>Retour</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.btnConfirm}
onPress={handleValiderCommande}
disabled={isSubmitting}
>
{isSubmitting ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.btnConfirmText}>Confirmer ✅</Text>
)}
</TouchableOpacity>
</View>
</View>
</ScrollView>
</ProtectedRoute>
);
};
/**
* Styles locaux de l'écran ValidationCommande.
* @type {import('react-native').StyleSheet.NamedStyles<any>}
*/
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#F4F7F9', padding: 15 },
card: { backgroundColor: '#FFF', borderRadius: 15, padding: 20, elevation: 3 },
title: { fontSize: 22, fontWeight: 'bold', marginBottom: 20, color: '#1E3C72', textAlign: 'center' },
section: { marginBottom: 20, borderBottomWidth: 1, borderBottomColor: '#EEE', paddingBottom: 15 },
subTitle: { fontWeight: '700', marginBottom: 10, color: '#555' },
label: { fontSize: 14, color: '#666', marginBottom: 5 },
value: { fontWeight: 'bold', color: '#000' },
itemRow: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 5 },
itemName: { flex: 1, fontSize: 14 },
itemPrice: { fontWeight: '600' },
totalSection: { marginTop: 10 },
row: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 8 },
borderTop: { borderTopWidth: 1, borderTopColor: '#DDD', paddingTop: 10, marginTop: 5 },
totalLabel: { fontSize: 18, fontWeight: 'bold' },
totalValue: { fontSize: 20, fontWeight: 'bold', color: '#1E3C72' },
buttonContainer: { flexDirection: 'row', justifyContent: 'space-between', marginTop: 30 },
btnBack: { padding: 15, borderRadius: 10, backgroundColor: '#EEE', width: '45%', alignItems: 'center' },
btnBackText: { fontWeight: 'bold', color: '#333' },
btnConfirm: { padding: 15, borderRadius: 10, backgroundColor: '#1E3C72', width: '45%', alignItems: 'center' },
btnConfirmText: { fontWeight: 'bold', color: '#FFF' }
});
export default ValidationCommande;