"import React, { useState, useRef, useEffect } from 'react';
import { View, Text, TouchableOpacity, Image, Alert, Modal, TextInput, StyleSheet } from 'react-native';
import MapView, { Marker, Callout, Polyline, Polygon } from 'react-native-maps';
import haversine from 'haversine';
import { getAreaOfPolygon, convertArea } from 'geolib';
import { useNavigation, ParamListBase, NavigationProp } from '@react-navigation/native';
import { captureRef } from 'react-native-view-shot';
import { firebase } from '../../../config';
import styles from '../../components/styleMap2D'; // Assurez-vous que ce fichier de style existe
import Radiobox from 'react-native-vector-icons/MaterialCommunityIcons';
import ZoomIn from 'react-native-vector-icons/MaterialIcons';
import ZoomOut from 'react-native-vector-icons/MaterialIcons';
import Trash from 'react-native-vector-icons/FontAwesome';
import Check from 'react-native-vector-icons/Entypo';

export default function Map2D() {
    const navigation = useNavigation<NavigationProp<ParamListBase>>();
    const defaultRegion = {
        latitude: 41.592308,
        longitude: -6.361831,
        latitudeDelta: 0.01,
        longitudeDelta: 0.01,
    };

    const mapRef = useRef(null);
    const [currentRegion, setCurrentRegion] = useState(defaultRegion);
    const [markers, setMarkers] = useState([]);
    const [totalDistance, setTotalDistance] = useState<number>(0);
    const [polylines, setPolylines] = useState([]);
    const [addingMarker, setAddingMarker] = useState(false);
    const [loopClosed, setLoopClosed] = useState(false);
    const [loopArea, setLoopArea] = useState(0);
    const [closedLoopCoordinates, setClosedLoopCoordinates] = useState([]);
    const [draggingMarker, setDraggingMarker] = useState(null);
    const [polygonKey, setPolygonKey] = useState(0);
    const [capturedImageURI, setCapturedImageURI] = useState('');
    const [validateClicked, setValidateClicked] = useState(false);
    const [modalVisible, setModalVisible] = useState(false);
    const [landName, setLandName] = useState('');

    const minDistanceForLoop = 0.001;

    useEffect(() => {
        if (loopClosed && closedLoopCoordinates.length > 0) {
            const loopArea = calculatePolygonArea(closedLoopCoordinates);
            setLoopArea(loopArea);
        }
    }, [closedLoopCoordinates, loopClosed]);

    useEffect(() => {
        if (!addingMarker) {
            setTotalDistance(0);
            setLoopArea(0);
        }
    }, [addingMarker]);

    const calculateTotalDistance = (markerArray) => {
        let total = 0;
        for (let i = 1; i < markerArray.length; i++) {
            total += haversine(markerArray[i - 1], markerArray[i], { unit: 'meter' });
        }
        return total.toFixed(2);
    };


    const calculatePolygonArea = (vertices) => {
        const area = getAreaOfPolygon(vertices);
        const areaInSquareMeters = convertArea(area, 'm2');
        return areaInSquareMeters.toFixed(2);
    };

    const captureMap = async () => {
        try {
            const uri = await captureRef(mapRef, { format: 'jpg', quality: 1 });
            return uri;
        } catch (error) {
            console.error('Failed to capture map:', error);
        }
    };

    const handleMapPress = (event) => {
        const { coordinate } = event.nativeEvent;

        if (addingMarker && !loopClosed) {
            const newMarkers = [...markers, coordinate];
            setMarkers(newMarkers);

            if (newMarkers.length >= 2) {
                const newPolylines = [...polylines, [newMarkers[newMarkers.length - 2], coordinate]];
                setPolylines(newPolylines);

                if (newMarkers.length > 2 && haversine(newMarkers[0], coordinate, { unit: 'meter' }) < minDistanceForLoop) {
                    setLoopClosed(true);
                    setClosedLoopCoordinates(newMarkers);
                }
            }

            if (newMarkers.length >= 2) {
                const newTotalDistance = calculateTotalDistance(newMarkers);
                setTotalDistance(newTotalDistance);
            }
        } else if (!addingMarker) {
            const nearestSegment = findNearestSegment(coordinate);
            if (nearestSegment) {
                const { segment, index } = nearestSegment;
                const newMarkers = [
                    ...markers.slice(0, index + 1),
                    coordinate,
                    ...markers.slice(index + 1),
                ];
                setMarkers(newMarkers);
                updatePolylines(newMarkers);
                setTotalDistance(calculateTotalDistance(newMarkers));
            }
        }
    };

    const findNearestSegment = (point) => {
        let minDistance = Infinity;
        let nearestSegment = null;
        markers.forEach((marker, index) => {
            if (index < markers.length - 1) {
                const nextMarker = markers[index + 1];
                const distance = getDistanceToSegment(point, marker, nextMarker);
                if (distance < minDistance) {
                    minDistance = distance;
                    nearestSegment = { segment: [marker, nextMarker], index };
                }
            }
        });
        return nearestSegment;
    };

    const getDistanceToSegment = (point, segmentStart, segmentEnd) => {
        const x0 = point.latitude;
        const y0 = point.longitude;
        const x1 = segmentStart.latitude;
        const y1 = segmentStart.longitude;
        const x2 = segmentEnd.latitude;
        const y2 = segmentEnd.longitude;

        const A = x0 - x1;
        const B = y0 - y1;
        const C = x2 - x1;
        const D = y2 - y1;

        const dot = A * C + B * D;
        const len_sq = C * C + D * D;
        const param = len_sq !== 0 ? dot / len_sq : -1;

        let xx, yy;

        if (param < 0) {
            xx = x1;
            yy = y1;
        } else if (param > 1) {
            xx = x2;
            yy = y2;
        } else {
            xx = x1 + param * C;
            yy = y1 + param * D;
        }

        const dx = x0 - xx;
        const dy = y0 - yy;
        return Math.sqrt(dx * dx + dy * dy);
    };

    const handleMarkerDragStart = (marker, e) => {
        setDraggingMarker(marker);
    };

    const handleMarkerDragEnd = () => {
        setDraggingMarker(null);
    };

    const handleMarkerDrag = (e) => {
        if (draggingMarker) {
            const { coordinate } = e.nativeEvent;
            const index = markers.findIndex((marker) => marker === draggingMarker);
            if (index !== -1) {
                const newMarkers = [...markers];
                newMarkers[index] = coordinate;
                setMarkers(newMarkers);
                if (loopClosed) {
                    const newClosedLoopCoordinates = [...newMarkers];
                    setClosedLoopCoordinates(newClosedLoopCoordinates);
                    setPolygonKey(prevKey => prevKey + 1);
                }
                updatePolylines(newMarkers);
                setTotalDistance(calculateTotalDistance(newMarkers));
            }
        }
    };

    const toggleAddingMarker = () => {
        setAddingMarker(!addingMarker);
    };

    const handleClearMarkers = () => {
        setMarkers([]);
        setPolylines([]);
        setTotalDistance(0);
        setLoopClosed(false);
        setLoopArea(0);
        setClosedLoopCoordinates([]);
    };

    const adjustMapToFitMarkers = async () => {
        if (markers.length > 0) {
            mapRef.current.fitToCoordinates(markers, {
                edgePadding: { top: 50, right: 50, bottom: 50, left: 50 },
                animated: true,
            });
            await new Promise(resolve => setTimeout(resolve, 1000));
        }
    };

    const handleChangeText = (text) => {
        setLandName(text);
    };

    const handleValidate = () => {
        setModalVisible(true);
    };

    const handleSaveLandName = async () => {
        if (landName.trim() === '') {
            Alert.alert('Erreur', 'Veuillez entrez un nom')
        } else {
            setModalVisible(false);
            setValidateClicked(true);
            try {
                await adjustMapToFitMarkers();
                const uri = await captureMap();
                setCapturedImageURI(uri);
                // Récupérer l'utilisateur actuel
                const userId = firebase.auth().currentUser?.uid;
                if (userId) {
                    // Créer un nouveau document dans la collection 'lands' avec les données
                    const landData = {
                        coordinates: markers,
                        capturedImageURI: uri,
                        totalDistance: totalDistance,
                        Area: loopArea,
                        userId: userId,
                        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
                        landName: landName,
                    };
                    await firebase.firestore().collection('lands').add(landData);
                }
                navigation.navigate('EditMap', { coordinates: markers, capturedImageURI: uri, totalDistance: totalDistance, loopArea: loopArea, landName: landName });
            } catch (error) {
                console.error('Erreur lors de la validation :', error);
            }
        }
    };

    const handleRegionChangeComplete = (region) => {
        setCurrentRegion(region);
    };

    const updatePolylines = (markerArray) => {
        const newPolylines = [];
        for (let i = 1; i < markerArray.length; i++) {
            newPolylines.push([markerArray[i - 1], markerArray[i]]);
        }
        setPolylines(newPolylines);
    };

    return (
        <View style={styles.container}>
            <MapView
                showsUserLocation={true}
                provider={MapView.PROVIDER_GOOGLE}
                ref={mapRef}
                style={styles.map}
                initialRegion={defaultRegion}
                mapType='satellite'
                onPress={handleMapPress}
                zoomEnabled={true}
                scrollEnabled={!addingMarker}
                onRegionChangeComplete={handleRegionChangeComplete}
            >
                {markers.map((marker, index) => (
                    <Marker
                        key={index}
                        coordinate={marker}
                        draggable
                        onDragStart={(e) => handleMarkerDragStart(marker, e)}
                        onDragEnd={handleMarkerDragEnd}
                        onDrag={handleMarkerDrag}
                    >
                        <View style={styles.customMarker}>
                            <Radiobox name="radiobox-marked" size={20} color="white" />
                        </View>
                    </Marker>
                ))}

                {polylines.map((line, index) => (
                    <Polyline
                        key={index}
                        coordinates={line}
                        strokeColor={loopClosed ? "#FFF" : "#FFF"}
                        strokeWidth={loopClosed ? 2 : 2}
                    />
                ))}

                {closedLoopCoordinates.length > 0 && (
                    <Polygon
                        key={polygonKey}
                        coordinates={closedLoopCoordinates}
                        fillColor="rgba(255, 255, 255, 0.6)"
                    />
                )}
            </MapView>

            {/* Boutons */}
            <TouchableOpacity
                style={styles.zoomButtonTopRight}
                onPress={() =>
                    mapRef.current?.animateToRegion({
                        ...currentRegion,
                        latitudeDelta: currentRegion.latitudeDelta * 0.5,
                        longitudeDelta: currentRegion.longitudeDelta * 0.5,
                    })
                }
            >
                <ZoomIn name="zoom-in" size={24} color="black" />
            </TouchableOpacity>

            <TouchableOpacity
                style={styles.zoomButtonBottomRight}
                onPress={() =>
                    mapRef.current?.animateToRegion({
                        ...currentRegion,
                        latitudeDelta: currentRegion.latitudeDelta * 2,
                        longitudeDelta: currentRegion.longitudeDelta * 2,
                    })
                }
            >
                <ZoomOut name="zoom-out" size={24} color="black" />
            </TouchableOpacity>

            <TouchableOpacity
                style={[styles.addMarkerButton, { backgroundColor: addingMarker ? 'green' : 'white' }]}
                onPress={toggleAddingMarker}
            >
                <Text style={[styles.addMarkerButtonText, { color: addingMarker ? 'white' : 'black' }]}>
                    {addingMarker ? 'Valider mes Mesures' : 'Prendre des Mesures'}
                </Text>
            </TouchableOpacity>

            {markers.length > 0 && (
                <TouchableOpacity style={styles.validateButton} onPress={handleValidate}>
                    <Check name="check" size={20} color="black" />
                </TouchableOpacity>
            )}

            {markers.length > 0 && (
                <TouchableOpacity style={styles.clearButton} onPress={handleClearMarkers}>
                    <Trash name="trash-o" size={20} color="black" />
                </TouchableOpacity>
            )}

            {/* Informations */}
            {addingMarker && markers.length > 0 && (
                <View style={styles.infoContainer}>
                    <Text style={styles.infoText}>Distance totale: {totalDistance} m</Text>
                    {loopClosed && <Text style={styles.infoText}>Surface totale: {loopArea} m²</Text>}
                </View>
            )}

            {/* Pop-up */}
            <Modal
                animationType="slide"
                transparent={true}
                visible={modalVisible}
                onRequestClose={() => {
                    setModalVisible(!modalVisible);
                }}
            >
                <View style={styles.modalContainer}>
                    <View style={styles.modalContent}>
                        <Text style={styles.modalTitle}>Nom de la Terre</Text>
                        <TextInput
                            style={styles.input}
                            onChangeText={handleChangeText}
                            value={landName}
                            placeholder="Nom de la Terre"
                        />
                        <View style={styles.modalButtons}>
                            <TouchableOpacity
                                style={[styles.modalButton, styles.modalButtonCancel]}
                                onPress={() => setModalVisible(false)}
                            >
                                <Text style={styles.modalButtonText}>Annuler</Text>
                            </TouchableOpacity>
                            <TouchableOpacity
                                style={[styles.modalButton, styles.modalButtonValidate]}
                                onPress={handleSaveLandName}
                            >
                                <Text style={styles.modalButtonText}>Valider</Text>
                            </TouchableOpacity>
                        </View>
                    </View>
                </View>
            </Modal>
        </View>
    );
}
" est-ce qu'il est possible d'écouter les clics de l'utilisateur pour 'drag and drop' les repères qui sont sélectionné ? -> écouter les clics de l'utilisateur pour 'drag and drop' les repères sélectionnés dans votre application React Native. Vous avez déjà une bonne partie de la fonctionnalité en place avec les événements onDragStart, onDrag, et onDragEnd. Vous pouvez étendre cette logique pour permettre une meilleure interaction de 'drag and drop' avec les repères.

Voici comment vous pouvez le faire:

Ajouter la gestion de l'état pour le repère sélectionné: Vous devez suivre quel repère est actuellement sélectionné pour le 'drag and drop'.
Mettre à jour la position du repère sélectionné pendant le 'drag': Vous devez mettre à jour la position du repère sélectionné en temps réel pendant que l'utilisateur le déplace.
Finaliser la position du repère après le 'drop': Vous devez finaliser la nouvelle position du repère après que l'utilisateur ait relâché le repère.