File "table_0016_debug008_change_001.php"

Full Path: /home/analogde/www/eliot/import_export/table_0016_debug008_change_001.php
File size: 178.55 KB
MIME-type: text/html
Charset: utf-8

<script>


function getWorkingDays(startDate, endDate, holidays = []) {
    const workingDays = [];
    const start = new Date(startDate);
    const end = new Date(endDate);

    // Ajouter un jour à la date de fin pour inclure le dernier jour
    end.setDate(end.getDate() + 1);

    for (let currentDate = new Date(start); currentDate < end; currentDate.setDate(currentDate.getDate() + 1)) {
        const dayOfWeek = currentDate.getDay(); // 0 (dimanche) à 6 (samedi)
        const dateStr = currentDate.toISOString().split('T')[0];

        if (dayOfWeek !== 0 && dayOfWeek !== 6 && !holidays.includes(dateStr)) {
            workingDays.push({
                day: currentDate.getDate(),
                day_of_week_initial: getDayInitial(currentDate),
                week_number: getWeekNumber(currentDate),
                full_date: dateStr
            });
        }
    }

    console.log(" Erreur : le dernier jour n'est pas inclus dans la plage ???. ")

    return workingDays;
}

function getFrenchHolidays(year) {
    const holidays = [];
    const easterDate = calculateEaster(year);

    // Jours fériés fixes
    holidays.push(`${year}-01-01`); // Jour de l'An
    holidays.push(`${year}-05-01`); // Fête du Travail
    holidays.push(`${year}-05-08`); // Victoire 1945
    holidays.push(`${year}-07-14`); // Fête Nationale
    holidays.push(`${year}-08-15`); // Assomption
    holidays.push(`${year}-11-01`); // Toussaint
    holidays.push(`${year}-11-11`); // Armistice
    holidays.push(`${year}-12-25`); // Noël

    // Jours fériés variables (calculés à partir de Pâques)
    const easter = new Date(easterDate);
    holidays.push(formatDate(easter)); // Pâques (non férié officiellement mais utile)
    holidays.push(formatDate(new Date(easter.setDate(easter.getDate() + 1)))); // Lundi de Pâques
    holidays.push(formatDate(new Date(easter.setDate(easter.getDate() + 38)))); // Ascension
    holidays.push(formatDate(new Date(easter.setDate(easter.getDate() + 11)))); // Lundi de Pentecôte

    return holidays;
}

function calculateEaster(year) {
    const a = year % 19;
    const b = Math.floor(year / 100);
    const c = year % 100;
    const d = Math.floor(b / 4);
    const e = b % 4;
    const f = Math.floor((b + 8) / 25);
    const g = Math.floor((b - f + 1) / 3);
    const h = (19 * a + b - d - g + 15) % 30;
    const i = Math.floor(c / 4);
    const k = c % 4;
    const l = (32 + 2 * e + 2 * i - h - k) % 7;
    const m = Math.floor((a + 11 * h + 22 * l) / 451);
    const month = Math.floor((h + l - 7 * m + 114) / 31);
    const day = ((h + l - 7 * m + 114) % 31) + 1;

    return new Date(year, month - 1, day);
}

function formatDate(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
}

function getDayInitial(date) {
    const days = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'];
    return days[date.getDay()][0];
}

function getWeekNumber(date) {
    const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
    const pastDaysOfYear = (date - firstDayOfYear) / 86400000;
    return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
}

// Exemple d'utilisation
const year = 2025;
const holidays = getFrenchHolidays(year);
const startDate = "2025-01-10";
const endDate = "2026-02-14";
let workingDays = getWorkingDays(startDate, endDate, holidays);

console.log(workingDays);
</script>




<?php

function getWorkingDays($startDate, $endDate, $holidays = []) {
    $start = strtotime($startDate);
    $end = strtotime($endDate);
    $workingDays = [];

    setlocale(LC_TIME, 'fr_FR.UTF-8');

    for ($currentDate = $start; $currentDate <= $end; $currentDate = strtotime("+1 day", $currentDate)) {
        $dayOfWeek = date("N", $currentDate);

        if ($dayOfWeek < 6 && !in_array(date("Y-m-d", $currentDate), $holidays)) {
            $workingDays[] = [
                'day' => date("d", $currentDate),
                'day_of_week_initial' => strtoupper(strftime("%A", $currentDate)[0]),
                'week_number' => date("W", $currentDate),
                'full_date' => date("Y-m-d", $currentDate) // Ajout de la date complète
            ];
        }
    }

    return $workingDays;
}



function getFrenchHolidays($year) {
    $easterDate = easter_date($year);
    $holidays = [];

    // Jours fériés fixes
    $holidays[] = "$year-01-01"; // Jour de l'An
    $holidays[] = "$year-05-01"; // Fête du Travail
    $holidays[] = "$year-05-08"; // Victoire 1945
    $holidays[] = "$year-07-14"; // Fête Nationale
    $holidays[] = "$year-08-15"; // Assomption
    $holidays[] = "$year-11-01"; // Toussaint
    $holidays[] = "$year-11-11"; // Armistice
    $holidays[] = "$year-12-25"; // Noël

    // Jours fériés variables (calculés à partir de Pâques)
    $easter = new DateTime("@$easterDate");
    $easter->setTimezone(new DateTimeZone(date_default_timezone_get()));

    $holidays[] = $easter->format("Y-m-d"); // Pâques (non férié officiellement mais utile)
    $holidays[] = $easter->modify('+1 day')->format("Y-m-d"); // Lundi de Pâques
    $holidays[] = $easter->modify('+38 days')->format("Y-m-d"); // Ascension
    $holidays[] = $easter->modify('+11 days')->format("Y-m-d"); // Lundi de Pentecôte

    return $holidays;
}

$year = 2025;
$holidays = [];

$holidays = getFrenchHolidays($year);

// Liste des jours fériés et fêtes religieuses à exclure (exemple pour la France, à compléter avec d'autres fêtes)
$old_holidays = [
    "2025-01-01", // Jour de l'An
    "2025-04-14", // Lundi de Pâques
    "2025-05-01", // Fête du Travail
    "2025-05-08", // Victoire 1945
    "2025-07-14", // Bastille
    "2025-08-15", // Assomption
    "2025-11-01", // Toussaint
    "2025-12-25", // Noël
    "2026-01-01", // Jour de l'An
    "2026-04-06", // Lundi de Pâques
    // Ajouter d'autres jours fériés ici...
];

// Définir la période de début et de fin
$startDate = "2025-01-10";
$endDate = "2026-02-14";

// Appeler la fonction pour obtenir les jours ouvrés entre les deux dates
$workingDays = getWorkingDays($startDate, $endDate, $holidays);

// Convertir le tableau en JSON
$workingDaysJson = json_encode($workingDays);

?>


<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tableau Sticky - 3 Lignes Fixes</title>
    <style>
        .table-wrapper {
            width: 100%;
            height: calc(100vh - 100px);
            overflow: auto;
            border: 1px solid #ccc;
            position: relative;
        }

        table {
            border-collapse: collapse;
            width: max-content;
            table-layout: fixed;
        }

        th, td {
            padding: 3px;
            text-align: center;
            height: 40px;
            border: 1px solid #ccc;
            white-space: nowrap;
            min-width: 120px;
            position: relative;
            background-color: white;
            box-sizing: border-box;
        }

        th {
            background-color: #f2f2f2;
            position: sticky;
            top: 0;
            z-index: 100;
        }

        th:first-child, td:first-child {
            position: sticky;
            left: 0;
            z-index: 101;
            background-color: white;
        }

        th:nth-child(2), td:nth-child(2) {
            position: sticky;
            left: 120px;
            z-index: 100;
            background-color: white;
        }

        th:nth-child(3), td:nth-child(3) {
            position: sticky;
            left: 240px;
            z-index: 99;
            background-color: white;
        }

        th:first-child::after, td:first-child::after,
        th:nth-child(2)::after, td:nth-child(2)::after,
        th:nth-child(3)::after, td:nth-child(3)::after {
            content: "";
            position: absolute;
            right: 0;
            top: 0;
            width: 2px;
            height: 100%;
            background-color: #ccc;
            z-index: 102;
        }

        tbody tr:nth-child(odd) {
            background-color: #f9f9f9;
        }

        th:nth-child(n+4), td:nth-child(n+4) {
            min-width: 40px;
            max-width: 40px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .second-header th {
            background-color: #f2f2f2;
            position: sticky;
            top: 40px;
            z-index: 99;
        }

        .third-header th {
            background-color: #f2f2f2;
            position: sticky;
            top: 80px;
            z-index: 98;
        }

        .second-header th:first-child, .third-header th:first-child {
            left: 0;
            z-index: 101;
            background-color: white;
        }

        .second-header th:nth-child(2), .third-header th:nth-child(2) {
            left: 120px;
            z-index: 100;
            background-color: white;
        }

        .second-header th:nth-child(3), .third-header th:nth-child(3) {
            left: 240px;
            z-index: 99;
            background-color: white;
        }

        thead tr:first-child th:first-child,
        thead tr:first-child th:nth-child(2),
        thead tr:first-child th:nth-child(3) {
            z-index: 105;
            background-color: #ddd;
        }

        .second-header th:first-child,
        .second-header th:nth-child(2),
        .second-header th:nth-child(3) {
            z-index: 104;
        }

        .third-header th:first-child,
        .third-header th:nth-child(2),
        .third-header th:nth-child(3) {
            z-index: 103;
        }

        thead tr:first-child th,
        .second-header th,
        .third-header th {
            box-shadow: inset 0 -2px #aaa;
            background-clip: padding-box;
            padding-bottom: 2px;
            margin-bottom: -2px;
            z-index: 100;
        }

        .second-header th {
            top: calc(40px + 2px);
            margin-top: 2px;
        }

        .third-header th {
            top: calc(80px + 2px);
            margin-top: 2px;
        }

        .even-week {
            background-color: #ffcc99 !important;
        }

        .odd-week {
            background-color: #e6b3ff !important;
        }

        .fourth-header th {
            background-color: #f2f2f2;
            position: sticky;
            top: 120px;
            z-index: 97;
        }

        .fourth-header th:first-child {
            left: 0;
            z-index: 101;
            background-color: white;
        }

        .fourth-header th:nth-child(2) {
            left: 120px;
            z-index: 100;
            background-color: white;
        }

        .fourth-header th:nth-child(3) {
            left: 240px;
            z-index: 99;
            background-color: white;
        }

        .fourth-header th:first-child,
        .fourth-header th:nth-child(2),
        .fourth-header th:nth-child(3) {
            z-index: 102;
        }

        .fourth-header th {
            top: calc(120px + 2px);
            margin-top: 2px;
        }

        .fourth-header th {
            box-shadow: inset 0 -2px #aaa;
            background-clip: padding-box;
            padding-bottom: 2px;
            margin-bottom: -2px;
            z-index: 97;
        }

        .month-even {
            background-color: #99ccff !important;
        }

        .month-odd {
            background-color: #ff9999 !important;
        }

        .btn {
            margin-bottom: 20px;
            padding: 10px;
            background-color: #4CAF50;
            color: white;
            border: none;
            cursor: pointer;
            font-size: 16px;
            border-radius: 5px;
            transition: background-color 0.3s ease;
        }

        .btn:hover {
            background-color: #45a049;
        }

        .btn-special {
            background-color: #2196F3;
        }

        .btn-special:hover {
            background-color: #1e88e5;
        }

        .btn-special:hover {
            background-color: #1e88e5;
        }

        #contextMenu {
            position: absolute;
            display: none;
            flex-direction: column;
            background: white;
            border: 1px solid #ccc;
            box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
            border-radius: 5px;
            z-index: 1000;
            min-width: 180px;
        }

        #contextMenu .dropdown-item {
            display: block;
            width: 100%;
            padding: 8px 12px;
            text-align: left;
            color: #333;
            cursor: pointer;
        }

        #contextMenu .dropdown-item:hover {
            background: #f8f9fa;
        }

        #specialContextMenu {
            position: absolute;
            display: none;
            flex-direction: column;
            background: white;
            border: 1px solid #ccc;
            box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
            border-radius: 5px;
            z-index: 1000;
            min-width: 180px;
        }

        #specialContextMenu .dropdown-item {
            display: block;
            width: 100%;
            padding: 8px 12px;
            text-align: left;
            color: #333;
            cursor: pointer;
        }

        #specialContextMenu .dropdown-item:hover {
            background: #f8f9fa;
        }

        #colorContextMenu {
            position: absolute;
            display: none;
            flex-direction: column;
            background: white;
            border: 1px solid #ccc;
            box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
            border-radius: 5px;
            z-index: 1000;
            min-width: 180px;
        }

        #colorContextMenu .dropdown-item {
            display: block;
            width: 100%;
            padding: 8px 12px;
            text-align: left;
            color: #333;
            cursor: pointer;
        }

        #colorContextMenu .dropdown-item:hover {
            background: #f8f9fa;
        }

        .add-button {
            background-color: orange;
            color: white;
            border: none;
            padding: 5px 10px;
            cursor: pointer;
            margin-left: 5px;

        }

        .editable-input {
            width: 65px;
            box-sizing: border-box;
        }

        .collapsed {
            display: none;
        }

        #jsonOutput {
            margin-top: 20px;
            padding: 10px;
            border: 1px solid #ccc;
            background-color: #f9f9f9;
            white-space: pre-wrap;
            word-wrap: break-word;
        }

        #logOutput {
            margin-top: 20px;
            padding: 10px;
            border: 1px solid #ccc;
            background-color: #f9f9f9;
            white-space: pre-wrap;
            word-wrap: break-word;
        }

        .no-click {
            pointer-events: none;
        }

        #debugOutput {
            margin-top: 20px;
            padding: 10px;
            border: 1px solid #ccc;
            background-color: #f9f9f9;
            white-space: pre-wrap;
            word-wrap: break-word;
        }

        .dropdown-item.disabled {
        pointer-events: none;
        color: #6c757d;
        font-style: italic;
    }

    .no-select {
        pointer-events: none;
    }

    </style>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>

<div class="modal fade" id="confirmationModal" tabindex="-1" aria-labelledby="confirmationModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="confirmationModalLabel">Confirmation</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                Voulez-vous vraiment supprimer cette ligne ?
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" id="cancelDelete">Annuler</button>
                <button type="button" class="btn btn-danger" id="confirmDelete">OK</button>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="successModal" tabindex="-1" aria-labelledby="successModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="successModalLabel">Succès</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                Données sauvegardées avec succès !
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" id="closeSuccessModal">OK</button>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="messageModal" tabindex="-1" aria-labelledby="messageModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="messageModalLabel">Message</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body" id="messageModalBody">
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" data-dismiss="modal">OK</button>
            </div>
        </div>
    </div>
</div>

<!-- Modal de confirmation de sauvegarde -->
<div class="modal fade" id="confirmSaveModal" tabindex="-1" aria-labelledby="confirmSaveModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="confirmSaveModalLabel">Confirmation</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                Voulez-vous vraiment sauvegarder les données ?
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" id="cancelSave">Annuler</button>
                <button type="button" class="btn btn-primary" id="confirmSave">OK</button>
            </div>
        </div>
    </div>
</div>

<div id="colorContextMenu" class="dropdown-menu" style="display: none;">
    <button class="dropdown-item" style="background-color: green;" data-color="green">Vert</button>
    <button class="dropdown-item" style="background-color: blue;" data-color="blue">Bleu</button>
    <button class="dropdown-item" style="background-color: red;" data-color="red">Rouge</button>
    <button class="dropdown-item" style="background-color: yellow;" data-color="yellow">Jaune</button>
    <button class="dropdown-item" style="background-color: orange;" data-color="orange">Orange</button>
    <button class="dropdown-item" style="background-color: purple;" data-color="purple">Violet</button>
    <button class="dropdown-item" style="background-color: pink;" data-color="pink">Rose</button>
    <button class="dropdown-item" style="background-color: brown;" data-color="brown">Marron</button>
    <button class="dropdown-item" style="background-color: cyan;" data-color="cyan">Cyan</button>
    <button class="dropdown-item" style="background-color: gray;" data-color="gray">Gris</button>
</div>

<div class="modal fade" id="rangeSelectionModal" tabindex="-1" aria-labelledby="rangeSelectionModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="rangeSelectionModalLabel">Sélection de Plage</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="startCellId">Cellule de Départ</label>
                    <input type="text" class="form-control" id="startCellId" disabled>
                </div>
                <div class="form-group">
                    <label for="endCellId">Cellule de Fin</label>
                    <input type="text" class="form-control" id="endCellId">
                </div>
                <div class="form-group">
                    <label for="rangeComboBox">Sélectionnez une valeur</label>
                    <select class="form-control" id="rangeComboBox">
                    </select>
                </div>
                <div id="rangeResult" class="form-group">
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" id="cancelRangeSelection">Annuler</button>
                <button type="button" class="btn btn-primary" id="confirmRangeSelection">Valider</button>
            </div>
        </div>
    </div>
</div>

<div class="table-wrapper">
    <table>
        <thead>
            <tr>
                <th></th>
                <th>plouf</th>
                <th>cretin</th>
                <?php foreach ($workingDays as $dateData): ?>
                    <th>
                        <?php echo $dateData['day']; ?> <br>
                    </th>
                <?php endforeach; ?>
            </tr>

            <tr class="second-header">
                <th></th>
                <th>Valeur 1</th>
                <th>Valeur 2</th>
                <?php
                $currentWeek = null;
                $weekClass = "";

                foreach ($workingDays as $dateData):
                    if ($currentWeek !== $dateData['week_number']) {
                        $currentWeek = $dateData['week_number'];
                        $weekClass = ($currentWeek % 2 === 0) ? 'even-week' : 'odd-week';
                    }
                    ?>
                    <th class="<?= $weekClass; ?>"><?php echo $dateData['day_of_week_initial']; ?></th>
                <?php endforeach; ?>
            </tr>

            <tr class="third-header">
                <th></th>
                <th>Info 1</th>
                <th>Info 2</th>
                <?php
                $currentWeek = null;
                $colspan = 0;
                foreach ($workingDays as $index => $dateData):
                    if ($currentWeek !== $dateData['week_number']) {
                        if ($currentWeek !== null) {
                            $weekClass = $currentWeek % 2 === 0 ? 'even-week' : 'odd-week';
                            echo '<th class="' . $weekClass . '" colspan="' . $colspan . '">' . $currentWeek . '</th>';
                        }
                        $currentWeek = $dateData['week_number'];
                        $colspan = 1;
                    } else {
                        $colspan++;
                    }
                endforeach;
                if ($currentWeek !== null) {
                    $weekClass = $currentWeek % 2 === 0 ? 'even-week' : 'odd-week';
                    echo '<th class="' . $weekClass . '" colspan="' . $colspan . '">' . $currentWeek . '</th>';
                }
                ?>
            </tr>

            <tr class="fourth-header">
                <th></th>
                <th>Label 1</th>
                <th>Label 2</th>
                <?php
                $currentMonthYear = null;
                $colspan = 0;
                $monthClass = "";
                $colorIndex = 0;
                $colors = ['month-even', 'month-odd'];

                foreach ($workingDays as $index => $dateData):
                    $monthYear = ucfirst(strftime("%B %Y", strtotime($dateData['full_date'])));

                    if ($currentMonthYear !== $monthYear) {
                        if ($currentMonthYear !== null) {
                            echo '<th class="' . $monthClass . '" colspan="' . $colspan . '">' . $currentMonthYear . '</th>';
                        }
                        $currentMonthYear = $monthYear;
                        $colspan = 1;
                        $monthClass = $colors[$colorIndex % 2];
                        $colorIndex++;
                    } else {
                        $colspan++;
                    }
                endforeach;

                if ($currentMonthYear !== null) {
                    echo '<th class="' . $monthClass . '" colspan="' . $colspan . '">' . $currentMonthYear . '</th>';
                }
                ?>
            </tr>
        </thead>

        <tbody>
        </tbody>
    </table>
</div>

<button id="addRowButton" class="btn">Ajouter une ligne</button>
<button id="addSpecialRowButton" class="btn btn-special">Ajouter une ligne spéciale</button>

<button id="SauveButton" class="btn">Sauver</button>

<input type="file" id="fileInput" accept=".json" style="display: none;">
<button id="loadJsonButton" class="btn">Charger</button>

<!--
<button id="ChargeButton" class="btn">Charger</button>
-->
<button id="GraphiqueButton" class="btn">Graphique</button>

<!--
<button id="logButton" class="btn">Log</button>
-->

<button id="queryButton" class="btn">Query</button>


<!--
<div id="jsonOutput"></div>
-->
<!--
<div id="debugOutput"></div>
-->

<script>
    // Intégrer le JSON PHP dans une variable JavaScript
    workingDays = <?php echo $workingDaysJson; ?>;

    // Fonction pour afficher les données dans la console
    function displayWorkingDays()
    {
        console.log(workingDays);
    }

    // Appeler la fonction pour afficher les données
    //displayWorkingDays();
    //const value = workingDays[27].full_date;
    //console.log(value);

    // Déclarez le tableau list_lignes en dehors des fonctions pour qu'il soit accessible globalement
    let list_lignes = [];

    document.addEventListener("DOMContentLoaded", function () {
        const tableBody = document.querySelector("tbody");
        let specialRowCounter = 1;
        let rowCounter = 1;
        let linkageCounter = 1;
        let standardRowsData = [];
        let estimationRowsData = [];
        let specialRowsData = []; // Tableau dédié pour stocker les objets des lignes spéciales
        let linkages = [];
        const specialRowStates = {};
        const associations = {};
        let currentCell = null;
        let keydownHandled = false;
        let alertShown = false;
        let selectedRow = null; // Variable to keep track of the selected row

        const contextMenu = document.createElement("div");
        contextMenu.id = "contextMenu";
        contextMenu.classList.add("dropdown-menu");
        contextMenu.style.display = "none";
        document.body.appendChild(contextMenu);

        const specialContextMenu = document.createElement("div");
        specialContextMenu.id = "specialContextMenu";
        specialContextMenu.classList.add("dropdown-menu");
        specialContextMenu.style.display = "none";
        document.body.appendChild(specialContextMenu);

        const colorContextMenu = document.getElementById("colorContextMenu");
        const colorButtons = colorContextMenu.querySelectorAll(".dropdown-item");

        colorButtons.forEach(button => {
            button.addEventListener("click", function () {
                const color = this.getAttribute("data-color");
                const cell = document.querySelector(".selected-cell");
                if (cell) {
                    cell.style.backgroundColor = color;
                    cell.dataset.cellColor = color;
                    hideColorContextMenu();
                    updateRowData(cell);
                }
            });
        });

        // Déclarez la variable selection_origine en dehors de la fonction pour qu'elle soit accessible globalement
        let selection_origine = null;

        // Déclarez l'objet objet_up en dehors de la fonction pour qu'il soit accessible globalement
        let objet_up = []; // Changez objet_up pour qu'il soit un tableau

        // Déclarez le tableau objet_selection en dehors de la fonction pour qu'il soit accessible globalement
        let objet_selection = [];

        function generateRandomId(length = 8) {
            const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            let result = '';
            for (let i = 0; i < length; i++) {
                result += characters.charAt(Math.floor(Math.random() * characters.length));
            }
            return result;
        }

        function addRow(afterRow = null) {
            const rowNumber = tableBody.rows.length + 1;
            const newRow = document.createElement("tr");
            newRow.setAttribute("draggable", "true");
            newRow.dataset.rowId = `standard-${generateRandomId()}`;
            newRow.title = newRow.dataset.rowId; // Ajoutez cette ligne

            const rowData = {
                id: newRow.dataset.rowId,
                name: `Row ${rowNumber}`,
                selectValue: "1",
                count: "0",
                cells: [],
                selection: "OFF" // TAG : SELECTION
            };

            // Ajoutez l'identifiant de la ligne dans le tableau list_lignes
            list_lignes.push(newRow.dataset.rowId);

            const firstCells = [`Row ${rowNumber}`, "", "0"];
            firstCells.forEach((text, index) => {
                const td = document.createElement("td");
                td.dataset.cellId = `cell-${rowData.id}-${index}`;
                if (index === 0) {
                    const input = document.createElement("input");
                    input.type = "text";
                    input.classList.add("editable-input");
                    input.value = rowData.name;
                    input.addEventListener("click", function (event) {
                        event.stopPropagation();
                        input.focus();
                        input.style.width = "130px";
                    });
                    input.addEventListener("blur", function () {
                        if (!keydownHandled && !alertShown) {
                            alertShown = true;
                            input.classList.remove("editing");
                            input.blur();
                            input.style.width = "65px";
                            console.clear;
                            updateRowData(input);
                        }
                        keydownHandled = false;
                        alertShown = false;
                    });
                    input.addEventListener("keydown", function (event) {
                        if (event.key === "Escape" || event.key === "Enter") {
                            keydownHandled = true;
                            if (!alertShown) {
                                alertShown = true;
                                input.classList.remove("editing");
                                input.blur();
                                input.style.width = "65px";
                                console.clear;
                                updateRowData(input);
                            }
                        }
                    });
                    td.appendChild(input);
                } else if (index === 1) {
                    const select = document.createElement("select");
                    for (let i = 1; i <= 10; i++) {
                        const option = document.createElement("option");
                        option.value = i;
                        option.textContent = `Option ${i}`;
                        select.appendChild(option);
                    }
                    select.value = rowData.selectValue;
                    select.addEventListener("change", function () {
                        updateRowData(select);
                    });
                    td.appendChild(select);
                } else {
                    td.textContent = text;
                }

                if (index === 0) {
                    td.classList.add("row-header");
                    td.addEventListener("click", function () {
                        handleRowClick(newRow, td); // TAG : SELECTION
                    });
                    td.addEventListener("contextmenu", function (event) {
                        event.preventDefault();
                        showContextMenu(event, newRow);
                    });
                }

                newRow.appendChild(td);
            });

            const headerCells = document.querySelectorAll("thead tr:nth-child(2) th:not(.weekend):not(.holiday)");
            const workingDaysCount = headerCells.length;

            for (let i = 0; i < workingDaysCount - 3; i++) {
                const td = document.createElement("td");
                td.dataset.cellId = `cell-${rowData.id}-${i}`;
                td.dataset.cellValue = "0";
                td.dataset.cellColor = "white";
                td.textContent = "0";
                td.style.backgroundColor = "white";

                td.addEventListener("click", function () {
                    const newValue = td.dataset.cellValue === "0" ? "1" : "0";
                    td.dataset.cellValue = newValue;
                    td.textContent = newValue;
                    td.style.backgroundColor = newValue === "1" ? "green" : "white";
                    td.dataset.cellColor = newValue === "1" ? "green" : "white";
                    updateCountCell(newRow);
                    updateRowData(td);
                });

                td.addEventListener("click", function (event) {
                    const fullDate = event.target.dataset.fullDate;
                    console.log("Date complète :", fullDate);
                    //alert(fullDate);
                    //  maintenant utiliser fullDate pour d'autres opérations
                });

                td.addEventListener("contextmenu", function (event) {
                    event.preventDefault();
                    if (td.dataset.cellValue === "1") {
                        showColorContextMenu(event, td);
                    }
                });

                td.title = `ID: ${td.dataset.cellId}`;

                newRow.appendChild(td);

                // $workingDays 555
                const value = workingDays[i].full_date;
                // Ajouter la clé full_date
                td.dataset.fullDate = workingDays[i].full_date;

                rowData.cells.push({
                    value: "0",
                    color: "white",
                    full_date: workingDays[i].full_date // Ajouter la clé full_date
                });
            }

            if (afterRow) {
                tableBody.insertBefore(newRow, afterRow.nextSibling);
            } else {
                tableBody.appendChild(newRow);
            }

            newRow.addEventListener("dragstart", dragStart);
            newRow.addEventListener("dragover", dragOver);
            newRow.addEventListener("drop", drop);

            rowCounter++;

            standardRowsData.push(rowData);

            const estimationRow = document.createElement("tr");
            estimationRow.setAttribute("draggable", "true");
            estimationRow.dataset.rowId = `estimation-${generateRandomId()}`;
            estimationRow.classList.add("estimation-row");
            estimationRow.title = estimationRow.dataset.rowId; // Ajoutez cette ligne

            const estimationRowData = {
                id: estimationRow.dataset.rowId,
                name: `Estimation ${rowNumber}`,
                selectValue: "1",
                estimationValue: "0",
                selection: "OFF" // TAG : SELECTION
            };

            // Ajoutez l'identifiant de la ligne d'estimation dans le tableau list_lignes
            list_lignes.push(estimationRow.dataset.rowId);

            const estimationFirstCells = [`Estimation ${rowNumber}`, "", "0"];
            estimationFirstCells.forEach((text, index) => {
                const td = document.createElement("td");
                td.dataset.cellId = `cell-${estimationRowData.id}-${index}`;
                if (index === 0) {
                    const input = document.createElement("input");
                    input.type = "text";
                    input.classList.add("editable-input");
                    input.value = estimationRowData.name;
                    input.addEventListener("click", function (event) {
                        event.stopPropagation();
                        input.focus();
                        input.style.width = "130px";
                    });
                    input.addEventListener("blur", function () {
                        if (!keydownHandled && !alertShown) {
                            alertShown = true;
                            input.classList.remove("editing");
                            input.blur();
                            input.style.width = "65px";
                            console.clear;
                            updateRowData(input);
                        }
                        keydownHandled = false;
                        alertShown = false;
                    });
                    input.addEventListener("keydown", function (event) {
                        if (event.key === "Escape" || event.key === "Enter") {
                            keydownHandled = true;
                            if (!alertShown) {
                                alertShown = true;
                                input.classList.remove("editing");
                                input.blur();
                                input.style.width = "65px";
                                console.clear;
                                updateRowData(input);
                            }
                        }
                    });
                    td.appendChild(input);
                } else if (index === 1) {
                    const select = document.createElement("select");
                    for (let i = 1; i <= 10; i++) {
                        const option = document.createElement("option");
                        option.value = i;
                        option.textContent = `Option ${i}`;
                        select.appendChild(option);
                    }
                    select.value = estimationRowData.selectValue;
                    select.addEventListener("change", function () {
                        updateRowData(select);
                    });
                    td.appendChild(select);
                } else {
                    const input = document.createElement("input");
                    input.type = "text";
                    input.classList.add("editable-input");
                    input.value = "1";
                    input.addEventListener("click", function (event) {
                        event.stopPropagation();
                        input.focus();
                        input.style.width = "130px";
                    });
                    input.addEventListener("blur", function () {
                        if (!keydownHandled && !alertShown) {
                            alertShown = true;
                            input.classList.remove("editing");
                            input.blur();
                            input.style.width = "65px";
                            console.clear;
                            const value = parseInt(input.value, 10);
                            if (isNaN(value) || value < 1 || value > 365) {
                                input.value = "1";
                                showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
                            } else {
                                updateRowData(input);
                            }
                        }
                        keydownHandled = false;
                        alertShown = false;
                    });
                    input.addEventListener("keydown", function (event) {
                        if (event.key === "Escape" || event.key === "Enter") {
                            keydownHandled = true;
                            if (!alertShown) {
                                alertShown = true;
                                input.classList.remove("editing");
                                input.blur();
                                input.style.width = "65px";
                                console.clear;
                                const value = parseInt(input.value, 10);
                                if (isNaN(value) || value < 1 || value > 365) {
                                    input.value = "1";
                                    showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
                                } else {
                                    updateRowData(input);
                                }
                            }
                        }
                    });
                    td.appendChild(input);
                }

                if (index === 0) {
                    td.classList.add("row-header");
                    td.addEventListener("click", function () {
                        handleRowClick(estimationRow, td); // TAG : SELECTION
                    });
                    td.addEventListener("contextmenu", function (event) {
                        event.preventDefault();
                        showContextMenu(event, estimationRow);
                    });
                }

                estimationRow.appendChild(td);
            });

            const mergedCell = document.createElement("td");
            mergedCell.colSpan = workingDaysCount - 3;
            mergedCell.textContent = "";
            mergedCell.classList.add("no-click");
            estimationRow.appendChild(mergedCell);

            if (afterRow) {
                tableBody.insertBefore(estimationRow, newRow.nextSibling);
            } else {
                tableBody.appendChild(estimationRow);
            }

            estimationRow.addEventListener("dragstart", dragStart);
            estimationRow.addEventListener("dragover", dragOver);
            estimationRow.addEventListener("drop", drop);

            const linkage = {
                id: `linkage-${generateRandomId()}`, // Remplacez linkageId par id
                standardRowId: newRow.dataset.rowId,
                estimationRowId: estimationRow.dataset.rowId
            };
            linkages.push(linkage);

            //displayLinkages();

            rowCounter++;

            estimationRowsData.push(estimationRowData);
        }

        function handleRowClick(row, td) {
            const rowId = row.dataset.rowId;
            selection_origine = rowId; // Mémorisez l'ID de la ligne cliquée
            console.log("Selection_origine :", selection_origine); // Affichez la valeur de selection_origine dans la console

            const tableBody = document.querySelector("tbody");
            const rowIds = [];

            /*if (objet_selection.length > 0 )
            {
                 // Afficher une fenêtre modale indiquant qu'une seule sélection est possible à la fois
                    showMessageModal("Une seule sélection est possible à la fois.");
                    return; // Empêcher la couleur de fond de changer
            }*/

            // Parcourir chaque ligne du tableau
            tableBody.querySelectorAll("tr").forEach(row => {
                const rowId = row.dataset.rowId;
                if (rowId) {
                    rowIds.push(rowId);
                }
            });

            console.log(rowIds);

            let linkedRowId = null;
            let linkedRow = null;

            if (rowId.startsWith("standard-")) {
                const linkage = linkages.find(link => link.standardRowId === rowId);
                if (linkage) {
                    linkedRowId = linkage.estimationRowId;
                    linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
                }
            } else if (rowId.startsWith("estimation-")) {
                const linkage = linkages.find(link => link.estimationRowId === rowId);
                if (linkage) {
                    linkedRowId = linkage.standardRowId;
                    linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
                }
            }

            // Vérifiez si l'identifiant de la ligne cliquée fait déjà partie de objet_selection
            if (objet_selection.includes(rowId)) {
                const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId);
                const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId);

                if (standardRowData && estimationRowData) {
                    standardRowData.selection = "OFF";
                    estimationRowData.selection = "OFF";

                    td.style.backgroundColor = "white";
                    linkedRow.cells[0].style.backgroundColor = "white";

                    // Supprimez les identifiants du tableau objet_selection
                    objet_selection = objet_selection.filter(id => id !== standardRowData.id && id !== estimationRowData.id);

                    // Réinitialisez les variables
                    selection_origine = null;
                    selectedRow = null;

                    console.log(" UNSELECT ");
                }
                return; // Empêcher la couleur de fond de changer
            }

            // Vérifiez si objet_selection contient déjà les identifiants d'une ligne standard et d'une ligne d'estimation
            if (objet_selection.length > 0)
            //if (objet_selection.length === 2)
            {
                showMessageModal("Une seule sélection est possible.");
                return; // Empêcher la couleur de fond de changer
            }

            if (linkedRow) {
                const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId);
                const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId);

                if (standardRowData.selection === "OFF" && estimationRowData.selection === "OFF") {
                    console.log(`ID standard : ${standardRowData.id}`);
                    console.log(`ID estimation : ${estimationRowData.id}`);

                    standardRowData.selection = "ON";
                    estimationRowData.selection = "ON";

                    td.style.backgroundColor = "red";
                    linkedRow.cells[0].style.backgroundColor = "red";

                    // Ajoutez les identifiants dans le tableau objet_selection
                    objet_selection.push(standardRowData.id, estimationRowData.id);

                    selectedRow = row; // Mettez à jour la ligne sélectionnée

                    console.log(`SELECT ${standardRowData.id} ${estimationRowData.id}`);
                    console.log(" ---- " + objet_selection);
                }
            }
        }

        function moveRowsUp() {
            console.log(" Move UP  ");

            // Vider le tableau
            list_lignes.length = 0;
            const allRows = Array.from(tableBody.querySelectorAll("tr"));
            allRows.forEach(row => {
                list_lignes.push(row.dataset.rowId);
            });

            displayListLignes();

            const id_ligne_standard = objet_selection[0];
            const id_ligne_estimation = objet_selection[1];

            let position_ligne_standard = list_lignes.indexOf(id_ligne_standard);
            let position_ligne_estimation = list_lignes.indexOf(id_ligne_estimation);

            console.log(" ------ position_ligne_standard " + position_ligne_standard);
            console.log(" ------ position_ligne_estimation" + position_ligne_estimation);

            // Vérifiez si la ligne au-dessus de la ligne standard est une ligne spéciale
            let is_speciale = position_ligne_standard > 0 && list_lignes[position_ligne_standard - 1].startsWith("special-");
            // Vérifiez si la ligne au-dessus de la ligne d'estimation est une ligne spéciale
            let is_standard = position_ligne_standard > 0 && list_lignes[position_ligne_standard - 1].startsWith("estimation-");

            if( is_speciale === true ) {
                console.log("Saut speciale "  );

                let save_identifiant_speciale = list_lignes[position_ligne_standard - 1];
                console.log(" TRACE identifiant " + save_identifiant_speciale);

                let index = list_lignes.indexOf(save_identifiant_speciale);
                list_lignes.splice(index, 1); // Supprime  élément à cet index

                console.log(" TRACE suppimer " + list_lignes);

                // recherche l'index de
                let new_position_speciale= list_lignes.indexOf(id_ligne_estimation);

                // on l'insére juste aprés
                list_lignes.splice( new_position_speciale + 1, 0, save_identifiant_speciale);

                console.log(" TRACE " + new_position_speciale + list_lignes);

                console.log("<<<<<<< Nouvel ordre >>>>>>>>");
                console.log(list_lignes);
                console.log("<<<<<<<>>>>>>>>");

                // Réorganiser les lignes du tableau en fonction de biduleArr
                reorderTableRows(list_lignes);
            }

            if( is_standard === true ) {
                console.log(" Saut de la liaison " );

                //  saut : standard <-> standard-2
                if (position_ligne_standard - 2 >= 0) {
                    let temp = list_lignes[position_ligne_standard];
                    list_lignes[position_ligne_standard] = list_lignes[position_ligne_standard - 2];
                    list_lignes[position_ligne_standard - 2] = temp;
                }

                // saut : estimation <-> estimation-2
                if (position_ligne_estimation - 2 >= 0) {
                    let temp = list_lignes[position_ligne_estimation];
                    list_lignes[position_ligne_estimation] = list_lignes[position_ligne_estimation - 2];
                    list_lignes[position_ligne_estimation - 2] = temp;
                }

                console.log("<<<<<<< Nouvel ordre >>>>>>>>");
                console.log(list_lignes);
                console.log("<<<<<<<>>>>>>>>");

                // Réorganiser les lignes du tableau en fonction de biduleArr
                reorderTableRows(list_lignes);
            }
        }

        function moveRowsDown() {
            console.log(" Move Down  ");

            // Vider le tableau
            list_lignes.length = 0;
            const allRows = Array.from(tableBody.querySelectorAll("tr"));
            allRows.forEach(row => {
                list_lignes.push(row.dataset.rowId);
            });

            displayListLignes();

            const id_ligne_standard = objet_selection[0];
            const id_ligne_estimation = objet_selection[1];

            let position_ligne_standard = list_lignes.indexOf(id_ligne_standard);
            let position_ligne_estimation = list_lignes.indexOf(id_ligne_estimation);

            console.log(" ------ position_ligne_standard " + position_ligne_standard);
            console.log(" ------ position_ligne_estimation" + position_ligne_estimation);

            // Vérifiez si une ligne existe sous la ligne estimation
            if (position_ligne_estimation + 1 < list_lignes.length) {
                console.log("yes");
            }
            // Arrêtez la fonction si aucune ligne n'existe sous position_ligne_estimation
            else {
                console.log("stop");
                return;
            }

            // Vérifiez si la ligne en dessous de la ligne estimation est une ligne spéciale
            let is_speciale = position_ligne_estimation > 0 && list_lignes[position_ligne_estimation + 1].startsWith("special-");
            // Vérifiez si la ligne en dessous de la ligne d'estimation est une ligne standard
            let is_estimation = position_ligne_estimation > 0 && list_lignes[position_ligne_estimation + 1].startsWith("standard-");

            if( is_speciale === true ) {
                // cette ligne speciale se trouve aprés la ligne estimation , c'est à dire +1
                console.log("Saut speciale " + list_lignes[position_ligne_estimation + 1]);

                // Étape 2 : Vérifier que e1 est juste avant v
                if (list_lignes[position_ligne_estimation + 1].startsWith("special-") ) {
                    let save_identifiant_speciale = list_lignes[position_ligne_estimation + 1];
                    console.log(" save_identifiant_speciale  " + save_identifiant_speciale);
                    let position_special = list_lignes.indexOf(save_identifiant_speciale);
                    console.log(" position_special  " + position_special);

                    // supprime l'élément qui se trouve à cette position
                    list_lignes.splice(list_lignes.indexOf(save_identifiant_speciale), 1);

                    // retourne l'index qui correspond à la valeur de l'id
                    let new_position_speciale = list_lignes.indexOf(id_ligne_standard);

                    console.log(" new_position_speciale   " + new_position_speciale);

                    // Insérer save_identifiant_speciale à l’indice new_position_speciale
                    list_lignes.splice( new_position_speciale, 0, save_identifiant_speciale);

                    console.log("<<<<<<< Nouvel ordre >>>>>>>>");
                    console.log(list_lignes);
                    console.log("<<<<<<<>>>>>>>>");

                    // Réorganiser les lignes du tableau en fonction de biduleArr
                    reorderTableRows(list_lignes);
                }
            }

            if( is_estimation === true ) {
                console.log(" Saut de la liaison  ");

                // saut : standard <-> standard+2
                if (position_ligne_standard + 2 >= 0) {
                    let temp = list_lignes[position_ligne_standard];
                    list_lignes[position_ligne_standard] = list_lignes[position_ligne_standard + 2];
                    list_lignes[position_ligne_standard + 2] = temp;
                }

                // saut estimation <-> estimation+2
                if (position_ligne_estimation + 2 >= 0) {
                    let temp = list_lignes[position_ligne_estimation];
                    list_lignes[position_ligne_estimation] = list_lignes[position_ligne_estimation + 2];
                    list_lignes[position_ligne_estimation + 2] = temp;
                }
                console.log("<<<<<<< Nouvel ordre >>>>>>>>");
                console.log(list_lignes);
                console.log("<<<<<<<>>>>>>>>");

                // Réorganiser les lignes du tableau en fonction de biduleArr
                reorderTableRows(list_lignes);
            }
        }

        function moveSpecialRowUp(row) {
            console.log("UP special");

            const rowId = row.dataset.rowId;
            const currentIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(row);

            if (currentIndex > 0) {
                const previousRow = tableBody.querySelectorAll("tr")[currentIndex - 1];
                const previousRowId = previousRow.dataset.rowId;

                if (previousRowId.startsWith("special-")) {

                    console.log("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");

                    let position_ligne_speciale = list_lignes.indexOf(previousRowId);
                    console.log(" TRACE position speciale " + position_ligne_speciale);
                    console.log(" TRACE identifiant speciale " + previousRowId);

                    // element à déplacer
                    console.log(" TRACE deplacer position current " + currentIndex);
                    console.log(" TRACE deplaced identifiant current " + rowId);

                    let save_identifiant_speciale = list_lignes[currentIndex];
                    console.log(" TRACE save identifiant  " + save_identifiant_speciale);

                    // Supprime  élément à cet index
                    list_lignes.splice(currentIndex, 1);

                    console.log("<<<<<<< Nouvel ordre >>>>>>>>");
                    console.log(list_lignes);
                    console.log("<<<<<<<>>>>>>>>");

                    list_lignes.splice( position_ligne_speciale , -1, save_identifiant_speciale);

                    console.log("<<<<<<< Nouvel ordre >>>>>>>>");
                    console.log(list_lignes);
                    console.log("<<<<<<<>>>>>>>>");

                    // Réorganiser les lignes du tableau en fonction de biduleArr
                    reorderTableRows(list_lignes);

                    return;
                }

                else if (previousRowId.startsWith("estimation-")) {
                    console.log(" Saut de la liaison " );

                    //alert("La ligne au-dessus est une ligne d'estimation.");
                    console.log(" +++ estimation " + rowId);
                    console.log(" +++ estimation " + previousRowId);

                    // Trouver l'objet de liaison qui contient previousRowId
                    const linkage = linkages.find(link => link.estimationRowId === previousRowId);
                    if (linkage) {
                        // Afficher les valeurs de l'objet de liaison dans la console
                        console.log("Objet de liaison trouvé :", linkage);
                        console.log("Identifiant de la ligne standard :", linkage.standardRowId);
                        console.log("Identifiant de la ligne d'estimation :", linkage.estimationRowId);

                        let position_ligne_speciale_selection = list_lignes.indexOf(rowId);
                        console.log("Position selection:", position_ligne_speciale_selection);

                        //aaa
                        list_lignes.splice(position_ligne_speciale_selection, 1); // Supprime  élément à cet index

                        console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
                        console.log(list_lignes);
                        console.log("<<<<<<<>>>>>>>>");

                        let position_ligne_standard = list_lignes.indexOf(linkage.standardRowId);
                        console.log("Position pour insertion:", position_ligne_standard);
                        // insérer rowId a

                        list_lignes.splice( position_ligne_standard , 0, rowId);

                        console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
                        console.log(list_lignes);
                        console.log("<<<<<<<>>>>>>>>");

                        // Réorganiser les lignes du tableau en fonction de biduleArr
                        reorderTableRows(list_lignes);

                    } else {
                        console.log("Aucun objet de liaison trouvé pour l'identifiant :", previousRowId);
                    }

                    // return;
                }

                // Si la ligne au-dessus n'est ni spéciale ni d'estimation, procédez au déplacement
                //tableBody.insertBefore(row, previousRow);
                //reorderTableRows(list_lignes);
            }
            else {
                alert("Aucune ligne au-dessus pour effectuer le déplacement.");
            }
        }

        function moveSpecialRowDown(row) {
            console.log("DOWN");

            const rowId = row.dataset.rowId;
            const currentIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(row);

            if (currentIndex >= 0 && currentIndex < tableBody.querySelectorAll("tr").length - 1) {
                const previousRow = tableBody.querySelectorAll("tr")[currentIndex + 1];
                const previousRowId = previousRow.dataset.rowId;

                console.log(" ------ " + rowId + " " + previousRowId);

                if (previousRowId.startsWith("special-")) {
                    console.log("Special detection");

                    // supprimer l'identifiant
                    let index_ligne_speciale = list_lignes.indexOf(rowId);
                    list_lignes.splice(index_ligne_speciale, 1); // Supprime  élément à cet index

                    console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
                    console.log(list_lignes);
                    console.log("<<<<<<<>>>>>>>>");

                    // rechrcher position de previousRowId
                    let bidule = list_lignes.indexOf(previousRowId);

                    // insérer   rowId aprés le position de   previousRowId
                    list_lignes.splice( bidule + 1 , 0, rowId);

                    console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
                    console.log(list_lignes);
                    console.log("<<<<<<<>>>>>>>>");

                    // Réorganiser les lignes du tableau en fonction de biduleArr
                    reorderTableRows(list_lignes);
                }

                else if (previousRowId.startsWith("standard-")) {
                    console.log("Saut de la liaison");

                    // Trouver l'objet de liaison qui contient previousRowId
                    const linkage = linkages.find(link => link.standardRowId === previousRowId);
                    if (linkage) {
                        // Afficher les valeurs de l'objet de liaison dans la console
                        console.log("Objet de liaison trouvé :", linkage);
                        console.log("Identifiant de la ligne standard :", linkage.standardRowId);
                        console.log("Identifiant de la ligne d'estimation :", linkage.estimationRowId);

                        // sauvegarder l'identifiant de la ligne speciale
                        let save_identifiant_speciale = list_lignes[currentIndex];
                        console.log(" TRACE sauve identifiant speciale " + save_identifiant_speciale);

                        // supprimer l'identifiant
                        let index_ligne_speciale = list_lignes.indexOf(save_identifiant_speciale);
                        list_lignes.splice(index_ligne_speciale, 1); // Supprime  élément à cet index

                        console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
                        console.log(list_lignes);
                        console.log("<<<<<<<>>>>>>>>");

                        // rechercher la position de linkage.estimationRowId
                        let index_ligne_estimation = list_lignes.indexOf(linkage.estimationRowId);

                        // insérer sous la ligne estimation
                        list_lignes.splice( index_ligne_estimation + 1 , 0, save_identifiant_speciale);

                        console.log("<<<<<<< Nouvel xxxx ordre >>>>>>>>");
                        console.log(list_lignes);
                        console.log("<<<<<<<>>>>>>>>");

                        // Réorganiser les lignes du tableau en fonction de biduleArr
                        reorderTableRows(list_lignes);
                    }
                } else {
                    console.log("Aucun objet de liaison trouvé pour l'identifiant :", previousRowId);
                }
            }
        }

        function reorderTableRows(biduleArr) {
            // Récupérer toutes les lignes du tableau
            const allRows = Array.from(tableBody.querySelectorAll("tr"));

            // Créer un mapping des lignes par leur identifiant
            const rowMap = new Map(allRows.map(row => [row.dataset.rowId, row]));

            // Réorganiser les lignes en fonction de biduleArr
            const orderedRows = biduleArr.map(id => rowMap.get(id)).filter(row => row !== undefined);

            // Vider le tableau actuel
            tableBody.innerHTML = "";

            // Ajouter les lignes réorganisées au tableau
            orderedRows.forEach(row => {
                tableBody.appendChild(row);
            });

            // Réattacher les événements de drag-and-drop aux lignes
            orderedRows.forEach(row => {
                row.addEventListener("dragstart", dragStart);
                row.addEventListener("dragover", dragOver);
                row.addEventListener("drop", drop);
            });
        }

        function updateRowData(element) {
            const row = element.closest("tr");
            const rowId = row.dataset.rowId;

            if (rowId.startsWith("standard-")) {
                let standardRowData = standardRowsData.find(data => data.id === rowId);
                if (!standardRowData) {
                    standardRowData = {
                        id: rowId,
                        name: "",
                        selectValue: "",
                        count: "",
                        cells: [],
                        selection: "OFF" // TAG : SELECTION
                    };
                    standardRowsData.push(standardRowData);
                }
                const cells = row.querySelectorAll("td");
                standardRowData.name = cells[0].querySelector("input").value;
                standardRowData.selectValue = cells[1].querySelector("select").value;
                standardRowData.count = cells[2].textContent.trim();
                standardRowData.cells = [];

                cells.forEach((cell, index) => {
                    if (index > 2) {
                        standardRowData.cells.push({
                            value: cell.dataset.cellValue,
                            color: cell.dataset.cellColor,
                            full_date: cell.dataset.fullDate // Ajouter la clé full_date
                        });
                    }
                });

                console.log(`Mise à jour de la ligne standard : ${rowId}`);
            } else if (rowId.startsWith("estimation-")) {
                let estimationRowData = estimationRowsData.find(data => data.id === rowId);
                if (!estimationRowData) {
                    estimationRowData = {
                        id: rowId,
                        name: "",
                        selectValue: "",
                        estimationValue: "",
                        selection: "OFF" // TAG : SELECTION
                    };
                    estimationRowsData.push(estimationRowData);
                }
                const cells = row.querySelectorAll("td");
                estimationRowData.name = cells[0].querySelector("input").value;
                estimationRowData.selectValue = cells[1].querySelector("select").value;
                estimationRowData.estimationValue = cells[2].querySelector("input").value;

                console.log(`Mise à jour de la ligne d'estimation : ${rowId}`);
            } else if (rowId.startsWith("special-")) {
                let specialRowData = specialRowsData.find(data => data.id === rowId);
                if (!specialRowData) {
                    specialRowData = {
                        id: rowId,
                        name: "",
                        selection: "OFF" // TAG : SELECTION
                    };
                    specialRowsData.push(specialRowData);
                }
                specialRowData.name = row.querySelector("input").value;

                console.log(`Mise à jour de la ligne spéciale : ${rowId}`);
            }
        }

        function updateCountCell(row) {
            const countCell = row.cells[2];
            const count = Array.from(row.cells).slice(3).filter(cell => cell.dataset.cellValue === "1").length;
            countCell.textContent = count;
        }

        function displayListLignes() {
            // Fonction pour afficher le contenu de list_lignes dans la console
            console.log("Contenu de list_lignes :", list_lignes);
        }

        function displaySpecialRowsData() {
            console.log("Contenu de specialRowsData :");
            specialRowsData.forEach((rowData, index) => {
                console.log(`Ligne spéciale ${index + 1} :`, rowData);
            });
        }

        function addSpecialRow(afterRow = null) {
            const newRow = document.createElement("tr");
            newRow.classList.add("special-row");
            newRow.setAttribute("draggable", "true");
            newRow.dataset.rowId = `special-${generateRandomId()}`;
            newRow.title = newRow.dataset.rowId; // Ajoutez cette ligne

            const specialRowData = {
                id: newRow.dataset.rowId,
                name: `Ligne spéciale ${specialRowCounter}`,
                selection: "OFF" // Ajouter la variable selection
            };

            // Ajoutez l'identifiant de la ligne spéciale dans le tableau list_lignes
            list_lignes.push(newRow.dataset.rowId);

            const firstCell = document.createElement("td");
            firstCell.classList.add("row-header");

            const input = document.createElement("input");
            input.type = "text";
            input.classList.add("editable-input");
            input.value = specialRowData.name;
            input.addEventListener("click", function (event) {
                event.stopPropagation();
                input.focus();
                input.style.width = "130px";
            });
            input.addEventListener("blur", function () {
                input.classList.remove("editing");
                input.style.width = "65px";
                updateRowData(input);
            });
            input.addEventListener("keydown", function (event) {
                if (event.key === "Escape" || event.key === "Enter") {
                    input.classList.remove("editing");
                    input.blur();
                    input.style.width = "65px";
                    updateRowData(input);
                }
            });
            input.addEventListener("input", function () {
                updateRowData(input);
            });

            const addButton = document.createElement("button");
            addButton.classList.add("add-button");
            addButton.textContent = "+";
            addButton.addEventListener("click", function () {
                toggleCollapse(newRow);
            });

            firstCell.appendChild(input);
            firstCell.appendChild(addButton);
            firstCell.addEventListener("contextmenu", function (event) {
                event.preventDefault();
                showSpecialContextMenu(event, newRow);
            });

            // Ajouter un gestionnaire de clic pour changer la couleur de fond
            firstCell.addEventListener("click", function () {
                handleSpecialRowClick(newRow, firstCell);
            });

            newRow.appendChild(firstCell);

            const mergedCell = document.createElement("td");
            mergedCell.colSpan = 2;
            mergedCell.textContent = "";
            newRow.appendChild(mergedCell);

            const td = document.createElement("td");
            td.textContent = `Ligne spéciale ${specialRowCounter} - Détails`;
            td.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
            newRow.appendChild(td);

            if (afterRow) {
                tableBody.insertBefore(newRow, afterRow.nextSibling);
            } else {
                tableBody.appendChild(newRow);
            }

            newRow.addEventListener("dragstart", dragStart);
            newRow.addEventListener("dragover", dragOver);
            newRow.addEventListener("drop", drop);

            specialRowsData.push(specialRowData); // Ajouter l'objet dans le tableau dédié
            specialRowCounter++;

            // Afficher le contenu du tableau specialRowsData après l'ajout
            displaySpecialRowsData();
        }

        function handleSpecialRowClick(row, td) {
            const rowId = row.dataset.rowId;
            const specialRowData = specialRowsData.find(data => data.id === rowId);

            if (specialRowData) {
                // Vérifiez si le clic est sur le bouton "+"
                if (event.target.classList.contains('add-button')) {
                    return; // Ignorer le clic sur le bouton "+"
                }

                if (objet_selection.length > 0 && !objet_selection.includes(rowId)) {
                    // Afficher une fenêtre modale indiquant qu'une seule sélection est possible à la fois
                    showMessageModal("Une seule sélection est possible à la fois.");
                    return; // Empêcher la couleur de fond de changer
                }

                if (specialRowData.selection === "OFF") {
                    specialRowData.selection = "ON";
                    td.style.backgroundColor = "blue";

                    // Ajoutez l'identifiant à objet_selection
                    if (!objet_selection.includes(rowId)) {
                        objet_selection.push(rowId);
                    }
                } else {
                    specialRowData.selection = "OFF";
                    td.style.backgroundColor = "white";

                    // Supprimer l'identifiant de objet_selection
                    objet_selection = objet_selection.filter(id => id !== rowId);
                }
            }

            // Afficher les identifiants dans objet_selection pour vérification
            console.log("objet_selection:", objet_selection);
        }

        function toggleCollapse(specialRow) {
            const nextSpecialRow = getNextSpecialRow(specialRow);
            const rowsToToggle = [];
            let currentRow = specialRow.nextElementSibling;

            while (currentRow && currentRow !== nextSpecialRow) {
                if (!currentRow.classList.contains("special-row")) {
                    rowsToToggle.push(currentRow);
                }
                currentRow = currentRow.nextElementSibling;
            }

            rowsToToggle.forEach(row => {
                row.classList.toggle("collapsed");
            });
        }

        function getNextSpecialRow(specialRow) {
            let currentRow = specialRow.nextElementSibling;
            while (currentRow) {
                if (currentRow.classList.contains("special-row")) {
                    return currentRow;
                }
                currentRow = currentRow.nextElementSibling;
            }
            return null;
        }

        function showContextMenu(event, row) {
            contextMenu.innerHTML = `
                <button class="dropdown-item" id="add-row">Ajouter une ligne</button>
                <button class="dropdown-item" id="delete-row">Supprimer cette ligne</button>
                <!--
                <button class="dropdown-item" id="show-linkage">Afficher la liaison</button>
                -->
                <button class="dropdown-item" id="up-elements">UP</button>
                <button class="dropdown-item" id="down-elements">DOWN</button>
            `;

            contextMenu.style.top = `${event.clientY}px`;
            contextMenu.style.left = `${event.clientX}px`;
            contextMenu.style.display = "flex";
            contextMenu.style.flexDirection = "column";

            // Vérifier si la ligne est une ligne standard ou une ligne d'estimation
            const rowId = row.dataset.rowId;
            const isEstimationRow = rowId.startsWith("estimation-");

            // Afficher ou masquer l'option "Ajouter une ligne" en fonction du type de ligne
            const addRowButton = document.getElementById("add-row");
            if (isEstimationRow) {
                addRowButton.style.display = "block";
            } else {
                addRowButton.style.display = "none";
            }

            let linkedRowId = null;
            let linkedRow = null;

            // Vérifier si les options UP et DOWN doivent être désactivées

            if (rowId.startsWith("standard-")) {
                const linkage = linkages.find(link => link.standardRowId === rowId);
                if (linkage) {
                    linkedRowId = linkage.estimationRowId;
                    linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
                }
            } else if (rowId.startsWith("estimation-")) {
                const linkage = linkages.find(link => link.estimationRowId === rowId);
                if (linkage) {
                    linkedRowId = linkage.standardRowId;
                    linkedRow = document.querySelector(`tr[data-row-id="${linkedRowId}"]`);
                }
            }

            let disableUpDown = true;
            if (linkedRow) {
                const standardRowData = standardRowsData.find(data => data.id === rowId) || standardRowsData.find(data => data.id === linkedRowId);
                const estimationRowData = estimationRowsData.find(data => data.id === rowId) || estimationRowsData.find(data => data.id === linkedRowId);

                if (standardRowData.selection === "ON" && estimationRowData.selection === "ON") {
                    disableUpDown = false;
                }
            }

            const upButton = document.getElementById("up-elements");
            const downButton = document.getElementById("down-elements");

            if (disableUpDown) {
                upButton.classList.add("disabled");
                downButton.classList.add("disabled");
            } else {
                upButton.classList.remove("disabled");
                downButton.classList.remove("disabled");
            }

            document.getElementById("add-row").addEventListener("click", function () {
                addRow(row);
                hideContextMenu();
            });

            document.getElementById("delete-row").addEventListener("click", function () {
                showConfirmationModal(row);
                hideContextMenu();
            });

            upButton.addEventListener("click", function () {
                if (!disableUpDown) {
                    moveRowsUp();
                    hideContextMenu();
                }
            });

            downButton.addEventListener("click", function () {
                if (!disableUpDown) {
                    moveRowsDown();
                    hideContextMenu();
                }
            });
        }

        function insertSpecialRow(direction, row) {
            const newSpecialRow = document.createElement("tr");
            newSpecialRow.classList.add("special-row");
            newSpecialRow.setAttribute("draggable", "true");
            newSpecialRow.dataset.rowId = `special-${generateRandomId()}`;
            newSpecialRow.title = newSpecialRow.dataset.rowId;

            const firstCell = document.createElement("td");
            firstCell.classList.add("row-header");

            const input = document.createElement("input");
            input.type = "text";
            input.classList.add("editable-input");
            input.value = `Ligne spéciale`;
            input.addEventListener("click", function (event) {
                event.stopPropagation();
                input.focus();
                input.style.width = "130px";
            });
            input.addEventListener("blur", function () {
                input.classList.remove("editing");
                input.style.width = "65px";
                updateRowData(input);
            });
            input.addEventListener("keydown", function (event) {
                if (event.key === "Escape" || event.key === "Enter") {
                    input.classList.remove("editing");
                    input.blur();
                    input.style.width = "65px";
                    updateRowData(input);
                }
            });
            input.addEventListener("input", function () {
                updateRowData(input);
            });

            const addButton = document.createElement("button");
            addButton.classList.add("add-button");
            addButton.textContent = "+";
            addButton.addEventListener("click", function () {
                toggleCollapse(newSpecialRow);
            });

            firstCell.appendChild(input);
            firstCell.appendChild(addButton);
            firstCell.addEventListener("contextmenu", function (event) {
                event.preventDefault();
                showSpecialContextMenu(event, newSpecialRow);
            });

            newSpecialRow.appendChild(firstCell);

            const mergedCell = document.createElement("td");
            mergedCell.colSpan = 2;
            mergedCell.textContent = "";
            newSpecialRow.appendChild(mergedCell);

            const td = document.createElement("td");
            td.textContent = `Ligne spéciale - Détails`;
            td.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
            newSpecialRow.appendChild(td);

            if (direction === "up") {
                tableBody.insertBefore(newSpecialRow, row);
            } else if (direction === "down") {
                tableBody.insertBefore(newSpecialRow, row.nextSibling);
            }

            newSpecialRow.addEventListener("dragstart", dragStart);
            newSpecialRow.addEventListener("dragover", dragOver);
            newSpecialRow.addEventListener("drop", drop);

            specialRowsData.push({
                id: newSpecialRow.dataset.rowId,
                name: input.value
            });

            // Afficher le contenu du tableau specialRowsData après l'ajout
            displaySpecialRowsData();
        }

        function showSpecialContextMenu(event, row) {
            specialContextMenu.innerHTML = `
                <button class="dropdown-item" id="add-special-row">Ajouter une ligne spéciale</button>
                <button class="dropdown-item" id="delete-special-row">Supprimer cette ligne</button>

                <!--
                <button class="dropdown-item text-danger" id="delete-special-row">Supprimer cette ligne</button>
                -->

                <!-- <label class="dropdown-item">
                    <input type="checkbox" id="special-checkbox"> Attacher
                </label> -->
                <button class="dropdown-item" id="up-special-row">UP</button>
                <button class="dropdown-item" id="down-special-row">DOWN</button>
            `;

            specialContextMenu.style.top = `${event.clientY}px`;
            specialContextMenu.style.left = `${event.clientX}px`;
            specialContextMenu.style.display = "flex";
            specialContextMenu.style.flexDirection = "column";

            // inactif attacher const checkbox = document.getElementById("special-checkbox");
            const rowId = row.dataset.rowId;

            // inactif attacher let hasStandardRowsBelow = false;
            // inactif attacher let currentRow = row.nextElementSibling;
            // inactif attacher const standardRows = [];
            // inactif attacher while (currentRow && !currentRow.classList.contains("special-row")) {
            // inactif attacher     if (!currentRow.classList.contains("special-row")) {
            // inactif attacher         hasStandardRowsBelow = true;
            // inactif attacher         standardRows.push(currentRow);
            // inactif attacher     }
            // inactif attacher     currentRow = currentRow.nextElementSibling;
            // inactif attacher }

            // inactif attacher if (hasStandardRowsBelow) {
            // inactif attacher     checkbox.disabled = false;
            // inactif attacher } else {
            // inactif attacher     checkbox.disabled = true;
            // inactif attacher     checkbox.checked = false;
            // inactif attacher }

            // inactif attacher if (specialRowStates[rowId]) {
            // inactif attacher     checkbox.checked = specialRowStates[rowId].checked;
            // inactif attacher }

            // inactif attacher checkbox.addEventListener("change", function () {
            // inactif attacher     specialRowStates[rowId] = {
            // inactif attacher         checked: checkbox.checked,
            // inactif attacher         rows: standardRows
            // inactif attacher     };

            // inactif attacher     standardRows.forEach(standardRow => {
            // inactif attacher         const firstCell = standardRow.querySelector("td:first-child");
            // inactif attacher         if (checkbox.checked) {
            // inactif attacher             firstCell.style.backgroundColor = "yellow";
            // inactif attacher             standardRow.classList.add("no-drag");
            // inactif attacher         } else {
            // inactif attacher             firstCell.style.backgroundColor = "";
            // inactif attacher             standardRow.classList.remove("no-drag");
            // inactif attacher         }
            // inactif attacher     });

            // inactif attacher     if (checkbox.checked) {
            // inactif attacher         associations[rowId] = standardRows.map(row => row.dataset.rowId);
            // inactif attacher     } else {
            // inactif attacher         delete associations[rowId];
            // inactif attacher     }

            // inactif attacher     console.log(`Lignes standards concernées : ${standardRows.map(row => row.rowIndex).join(", ")}`);
            // inactif attacher });

            // Vérifier si les options UP et DOWN doivent être désactivées
            const specialRowData = specialRowsData.find(data => data.id === rowId);
            let disableUpDown = true;
            if (specialRowData && specialRowData.selection === "ON") {
                disableUpDown = false;
            }

            const upButton = document.getElementById("up-special-row");
            const downButton = document.getElementById("down-special-row");

            if (disableUpDown) {
                upButton.classList.add("disabled");
                downButton.classList.add("disabled");
            } else {
                upButton.classList.remove("disabled");
                downButton.classList.remove("disabled");
            }

            document.getElementById("add-special-row").addEventListener("click", function () {
                addSpecialRow(row);
                hideSpecialContextMenu();
            });

            document.getElementById("delete-special-row").addEventListener("click", function () {
                showConfirmationModal(row);
                hideSpecialContextMenu();
            });

            upButton.addEventListener("click", function () {
                if (!disableUpDown) {
                    moveSpecialRowUp(row);
                    hideSpecialContextMenu();
                }
            });

            downButton.addEventListener("click", function () {
                if (!disableUpDown) {
                    moveSpecialRowDown(row);
                    hideSpecialContextMenu();
                }
            });
        }

        function showColorContextMenu(event, cell) {
            colorContextMenu.style.top = `${event.clientY}px`;
            colorContextMenu.style.left = `${event.clientX}px`;
            colorContextMenu.style.display = "flex";
            colorContextMenu.style.flexDirection = "column";

            document.querySelectorAll(".selected-cell").forEach(c => c.classList.remove("selected-cell"));
            cell.classList.add("selected-cell");
        }

        function showMessageModal(message) {
            const modal = new bootstrap.Modal(document.getElementById('messageModal'));
            const modalBody = document.getElementById('messageModalBody');
            modalBody.textContent = message;
            modal.show();
        }

        document.addEventListener("click", function (event) {
            if (!contextMenu.contains(event.target)) {
                hideContextMenu();
            }
            if (!specialContextMenu.contains(event.target)) {
                hideSpecialContextMenu();
            }
            if (!colorContextMenu.contains(event.target)) {
                hideColorContextMenu();
            }
            const inputs = document.querySelectorAll(".editable-input");
            inputs.forEach(input => {
                if (!input.contains(event.target)) {
                    input.classList.remove("editing");
                }
            });
        });

        document.addEventListener("keydown", function (event) {
            if (event.key === "Escape") {
                hideContextMenu();
                hideSpecialContextMenu();
                hideColorContextMenu();
            }
        });

        function hideContextMenu() {
            contextMenu.style.display = "none";
        }

        function hideSpecialContextMenu() {
            specialContextMenu.style.display = "none";
        }

        function hideColorContextMenu() {
            colorContextMenu.style.display = "none";
        }

        document.getElementById("addRowButton").addEventListener("click", addRow);
        document.getElementById("addSpecialRowButton").addEventListener("click", addSpecialRow);

        document.querySelectorAll("tbody tr td:first-child").forEach(td => {
            td.addEventListener("contextmenu", function (event) {
                event.preventDefault();
                showContextMenu(event, td.parentElement);
            });
        });

        let draggedRowId = null;

        function dragStart(event) {
            const row = event.target.closest("tr");
            if (!row) return;

            const rowId = row.dataset.rowId;

            // Vérifiez si la ligne est une ligne d'estimation
            if (rowId.startsWith("standard-") || rowId.startsWith("estimation-")) {
                event.preventDefault();
                return;
            }

            draggedRowId = row.dataset.rowId;
            event.dataTransfer.setData("text/plain", row.rowIndex);
            row.classList.add("dragging");
        }

        function dragOver(event) {
            event.preventDefault();
            const draggingRow = document.querySelector(".dragging");
            const targetRow = event.target.closest("tr");

            if (targetRow && draggingRow !== targetRow && !targetRow.classList.contains("no-drag")) {
                const rect = targetRow.getBoundingClientRect();
                const offset = rect.top + (rect.height / 2);
                if (event.clientY - offset > 0) {
                    tableBody.insertBefore(draggingRow, targetRow.nextSibling);
                } else {
                    tableBody.insertBefore(draggingRow, targetRow);
                }

                const targetRowId = targetRow.dataset.rowId;
                let linkage = null;

                if (targetRowId.startsWith("standard-")) {
                    linkage = linkages.find(link => link.standardRowId === targetRowId);
                } else if (targetRowId.startsWith("estimation-")) {
                    linkage = linkages.find(link => link.estimationRowId === targetRowId);
                }

                if (linkage) {
                    const draggedRowIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);
                    console.log("++++ " + linkage.standardRowId + " + " + linkage.estimationRowId + " at index " + draggedRowIndex);
                }
            }
        }

        function drop(event) {
            event.preventDefault();
            const draggingRow = document.querySelector(".dragging");
            draggingRow.classList.remove("dragging");

            const draggingRowId = draggingRow.dataset.rowId;
            let linkage = null;

            console.log(" Element " + draggingRowId);

            if (draggingRowId.startsWith("standard-")) {
                linkage = linkages.find(link => link.standardRowId === draggingRowId);

                console.log("Standard " + draggingRowId + " " + linkage.estimationRowId  + "  " + linkage.id );

                // sauvegarde l'identifiant qui correspond à la ligne estimation
                let save_identifiant_estimation = linkage.estimationRowId;
                console.log(" TRACE sauve identifiant estimation " + save_identifiant_estimation);

                const draggedRowIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);
                console.log("Position ligne drag standard " + draggedRowIndex);

                // Sélectionnez la ligne avec l'identifiant donné
                const estimationRow = document.querySelector(`tr[data-row-id="${linkage.estimationRowId}"]`);

                if (estimationRow) {
                    // Obtenez toutes les lignes du tbody
                    const rows = Array.from(tableBody.querySelectorAll("tr"));

                    // Trouvez l'index de la ligne estimation
                    const estimationRowIndex = rows.indexOf(estimationRow);

                    console.log("Position ligne estimation yes" + estimationRowIndex);

                    moveEstimationRow(estimationRowIndex, draggedRowIndex + 1);

                } else {
                    console.log(`Aucune ligne trouvée avec l'identifiant ${save_identifiant_estimation}.`);
                }
            }
            else if (draggingRowId.startsWith("estimation-")) {
                linkage = linkages.find(link => link.estimationRowId === draggingRowId);

                console.log("Estimation " );
            }

            if (linkage) {
                const draggedRowIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);
                console.log("++++ " + linkage.standardRowId + " + " + linkage.estimationRowId + " at index " + draggedRowIndex);

                console.log("Linkage " );
            }

            if (draggingRowId.startsWith("special-")) {
                console.log("Speciale ");

                // donne moi la position de la ligne speciale

                const index = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);
                console.log("Position ligne speciale " + index + " " + draggingRowId);

                // donne moi le nom de la ligne placée au dessus

                // donne moi le nom de la ligne placée en dessous

                // Donne moi le nom de la ligne placée au-dessus
                const previousRow = tableBody.querySelectorAll("tr")[index - 1];
                const nextRow = tableBody.querySelectorAll("tr")[index + 1];

                if (previousRow) {
                    const previousRowId = previousRow.dataset.rowId;
                    console.log("Identifiant de la ligne précédente :", previousRowId);
                }

                if (nextRow) {
                    const nextRowId = nextRow.dataset.rowId;
                    console.log("Identifiant de la ligne suivante :", nextRowId);
                }
            }

            if (draggingRowId.startsWith("special-")) {
                console.log("Speciale ");

                const specialRowId = draggingRow.dataset.rowId;
                const newIndex = Array.from(tableBody.querySelectorAll("tr")).indexOf(draggingRow);

                // Vérifiez si la nouvelle position est entre une ligne standard et une ligne d'estimation liées
                const previousRow = tableBody.querySelectorAll("tr")[newIndex - 1];
                const nextRow = tableBody.querySelectorAll("tr")[newIndex + 1];

                if (previousRow && nextRow) {
                    const previousRowId = previousRow.dataset.rowId;
                    const nextRowId = nextRow.dataset.rowId;

                    const linkage = linkages.find(link =>
                        (link.standardRowId === previousRowId && link.estimationRowId === nextRowId) ||
                        (link.standardRowId === nextRowId && link.estimationRowId === previousRowId)
                    );

                    if (linkage) {
                        // Ajustez la position en fonction de la direction du drag
                        const direction = draggingRow.rowIndex < newIndex ? 1 : -1;
                        tableBody.insertBefore(draggingRow, tableBody.querySelectorAll("tr")[newIndex + direction]);
                    }
                }

                if (associations[specialRowId]) {
                    const associatedRowIds = associations[specialRowId];
                    associatedRowIds.forEach(rowId => {
                        const associatedRow = document.querySelector(`tr[data-row-id="${rowId}"]`);
                        if (associatedRow) {
                            tableBody.insertBefore(associatedRow, draggingRow.nextSibling);
                        }
                    });
                }
            }
        }

        let deletedEstimationRowData = null;

        function deleteRowById(rowId) {
            const row = document.querySelector(`tr[data-row-id="${rowId}"]`);
            if (row) {
                // Conservez les données de la ligne avant de la supprimer
                deletedEstimationRowData = {
                    id: row.dataset.rowId,
                    name: row.cells[0].querySelector("input").value,
                    selectValue: row.cells[1].querySelector("select").value,
                    estimationValue: row.cells[2].querySelector("input").value,
                    selection: row.cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION
                };

                // Supprimez la ligne du DOM
                row.remove();
                console.log(`Ligne avec l'identifiant ${rowId} supprimée.`);
            } else {
                console.log(`Aucune ligne trouvée avec l'identifiant ${rowId}.`);
            }
        }

        function reinsertEstimationRowAtPosition(position) {
            if (deletedEstimationRowData) {
                const tableBody = document.querySelector("tbody");
                const newRow = document.createElement("tr");
                newRow.setAttribute("draggable", "true");
                newRow.dataset.rowId = deletedEstimationRowData.id;
                newRow.classList.add("estimation-row");
                newRow.title = newRow.dataset.rowId;

                // Créez les cellules de la nouvelle ligne
                const firstCells = [deletedEstimationRowData.name, "", deletedEstimationRowData.estimationValue];
                firstCells.forEach((text, index) => {
                    const td = document.createElement("td");
                    td.dataset.cellId = `cell-${deletedEstimationRowData.id}-${index}`;
                    if (index === 0) {
                        const input = document.createElement("input");
                        input.type = "text";
                        input.classList.add("editable-input");
                        input.value = deletedEstimationRowData.name;
                        input.addEventListener("click", function (event) {
                            event.stopPropagation();
                            input.focus();
                            input.style.width = "130px";
                        });
                        input.addEventListener("blur", function () {
                            input.classList.remove("editing");
                            input.style.width = "65px";
                            updateRowData(input);
                        });
                        input.addEventListener("keydown", function (event) {
                            if (event.key === "Escape" || event.key === "Enter") {
                                input.classList.remove("editing");
                                input.blur();
                                input.style.width = "65px";
                                updateRowData(input);
                            }
                        });
                        td.appendChild(input);
                    } else if (index === 1) {
                        const select = document.createElement("select");
                        for (let i = 1; i <= 10; i++) {
                            const option = document.createElement("option");
                            option.value = i;
                            option.textContent = `Option ${i}`;
                            select.appendChild(option);
                        }
                        select.value = deletedEstimationRowData.selectValue;
                        select.addEventListener("change", function () {
                            updateRowData(select);
                        });
                        td.appendChild(select);
                    } else {
                        const input = document.createElement("input");
                        input.type = "text";
                        input.classList.add("editable-input");
                        input.value = deletedEstimationRowData.estimationValue;
                        input.addEventListener("blur", function () {
                            const value = parseInt(input.value, 10);
                            if (isNaN(value) || value < 1 || value > 365) {
                                input.value = "1";
                                showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
                            } else {
                                updateRowData(input);
                            }
                            input.classList.remove("editing");
                            input.style.width = "65px";
                        });
                        input.addEventListener("keydown", function (event) {
                            if (event.key === "Escape" || event.key === "Enter") {
                                const value = parseInt(input.value, 10);
                                if (isNaN(value) || value < 1 || value > 365) {
                                    input.value = "1";
                                    showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
                                } else {
                                    updateRowData(input);
                                }
                                input.classList.remove("editing");
                                input.blur();
                                input.style.width = "65px";
                            }
                        });
                        td.appendChild(input);
                    }

                    if (index === 0) {
                        td.classList.add("row-header");
                        td.addEventListener("click", function (event) {
                            event.preventDefault();
                            handleRowClick(newRow, td); // TAG : SELECTION
                        });
                        td.addEventListener("contextmenu", function (event) {
                            event.preventDefault();
                            showContextMenu(event, newRow);
                        });
                    }

                    newRow.appendChild(td);
                });

                // Créez une cellule fusionnée pour les colonnes restantes
                const mergedCell = document.createElement("td");
                mergedCell.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
                mergedCell.textContent = "";
                mergedCell.classList.add("no-click");
                newRow.appendChild(mergedCell);

                // Insérez la nouvelle ligne à la position souhaitée
                if (position >= 0 && position <= tableBody.children.length) {
                    tableBody.insertBefore(newRow, tableBody.children[position]);
                } else {
                    tableBody.appendChild(newRow);
                }

                // Ajoutez les événements de drag-and-drop à la nouvelle ligne
                newRow.addEventListener("dragstart", dragStart);
                newRow.addEventListener("dragover", dragOver);
                newRow.addEventListener("drop", drop);

                // Ajoutez l'objet de la nouvelle ligne dans le tableau estimationRowsData
                estimationRowsData.push(deletedEstimationRowData);

                // Réinitialisez les données conservées
                deletedEstimationRowData = null;
            } else {
                console.log("Aucune donnée de ligne d'estimation supprimée à réinsérer.");
            }
        }

        function moveEstimationRow(fromPosition, toPosition) {
            const tableBody = document.querySelector("tbody");
            const rows = tableBody.querySelectorAll("tr");

            // Sélectionnez la ligne à déplacer
            const rowToMove = rows[fromPosition];

            // Vérifiez si la ligne est une ligne d'estimation
            if (rowToMove.dataset.rowId.startsWith("estimation-")) {
                // Retirez la ligne de sa position actuelle
                tableBody.removeChild(rowToMove);

                // Réinsérez la ligne à la nouvelle position
                if (toPosition >= rows.length) {
                    // Si la nouvelle position est à la fin, ajoutez la ligne à la fin
                    tableBody.appendChild(rowToMove);
                } else {
                    // Sinon, insérez la ligne avant la ligne à la nouvelle position
                    tableBody.insertBefore(rowToMove, rows[toPosition]);
                }

                console.log(`Ligne d'estimation déplacée de la position ${fromPosition} à la position ${toPosition}.`);
            } else {
                console.error("La ligne sélectionnée n'est pas une ligne d'estimation.");
            }
        }

        function getRowPositionById(rowId) {
            // Sélectionnez le tbody du tableau
            const tableBody = document.querySelector("tbody");

            // Sélectionnez la ligne avec l'identifiant donné
            const row = tableBody.querySelector(`tr[data-row-id="${rowId}"]`);

            // Vérifiez si la ligne existe
            if (row) {
                // Obtenez toutes les lignes du tbody
                const rows = Array.from(tableBody.querySelectorAll("tr"));

                // Trouvez l'index de la ligne
                const rowIndex = rows.indexOf(row);

                // Retournez la position de la ligne
                return rowIndex;
            } else {
                console.log(`Aucune ligne trouvée avec l'identifiant ${rowId}.`);
                return -1; // Retournez -1 si la ligne n'est pas trouvée
            }
        }

        function showConfirmationModal(row) {
            const modal = new bootstrap.Modal(document.getElementById('confirmationModal'));
            modal.show();

            document.getElementById('confirmDelete').addEventListener('click', function () {
                let linkageIndex = -1;

                const rowId = row.dataset.rowId;
                const isStandardRow = rowId.startsWith("standard-");
                const isEstimationRow = rowId.startsWith("estimation-");
                const isSpecialRow = rowId.startsWith("special-");

                console.log(" +++++++ " + rowId + " " + isSpecialRow)

                if (isStandardRow) {
                    linkageIndex = linkages.findIndex(link => link.standardRowId === rowId);
                }
                else if (isEstimationRow) {
                    linkageIndex = linkages.findIndex(link => link.estimationRowId === rowId);
                }
                else if (isSpecialRow) {
                    //linkageIndex = linkages.findIndex(link => link.specialRowId === rowId);
                    //console.log(" TRACE : " + linkageIndex);

                    const specialRowIndex = specialRowsData.findIndex(data => data.id === rowId);
                    console.log(" TRACE : " + specialRowIndex);

                    ///12345

                    //const tableData = traceTable();
                    //console.log("Données retournées par traceTable():", JSON.stringify(tableData, null, 2));

                    if (specialRowIndex !== -1) {
                        //console.log(" TRACE : " + linkageIndex);
                        specialRowsData.splice(specialRowIndex, 1);
                    }

                    // Vérifiez si l'identifiant de la ligne spéciale est dans objet_selection
                    if (objet_selection.includes(rowId)) {
                        // Purgez objet_selection
                        objet_selection = objet_selection.filter(id => id !== rowId);
                        console.log("objet_selection purgé :", objet_selection);
                    }

                    row.remove(); // Remove the special row from the DOM
                    modal.hide();
                    return;
                }

                if (linkageIndex !== -1) {
                    const linkage = linkages[linkageIndex];
                    console.log("Liaison trouvée :");
                    console.log("Index de la liaison :", linkageIndex); // Afficher l'indice de la liaison
                    console.log("ID de la liaison :", linkage.id);
                    console.log("ID de la ligne standard :", linkage.standardRowId);
                    console.log("ID de la ligne d'estimation :", linkage.estimationRowId);

                    // Vérifiez si les identifiants de la ligne standard et de la ligne d'estimation sont dans objet_selection
                    if (objet_selection.includes(linkage.standardRowId) && objet_selection.includes(linkage.estimationRowId)) {
                        // Purgez objet_selection
                        objet_selection = objet_selection.filter(id => id !== linkage.standardRowId && id !== linkage.estimationRowId);
                        console.log("objet_selection purgé :", objet_selection);
                    }
                }

                let standardRowId = null;
                let estimationRowId = null;
                let linkageId = null;

                if (isStandardRow) {
                    standardRowId = rowId;
                    const linkage = linkages.find(link => link.standardRowId === standardRowId);
                    if (linkage) {
                        estimationRowId = linkage.estimationRowId;
                        linkageId = linkage.id;
                    }
                }
                else if (isEstimationRow) {
                    estimationRowId = rowId;
                    const linkage = linkages.find(link => link.estimationRowId === estimationRowId);
                    if (linkage) {
                        standardRowId = linkage.standardRowId;
                        linkageId = linkage.id;
                    }
                }
                else if (isSpecialRow) {
                    // Handle special row deletion if needed
                }

                if (standardRowId && estimationRowId && linkageId) {
                    // Remove the corresponding sub-arrays in tableData
                    const tableData = traceTable();
                    const standardIndex = tableData.findIndex(item => item.id === standardRowId);
                    const estimationIndex = tableData.findIndex(item => item.id === estimationRowId);
                    const linkageIndex = tableData.findIndex(item => item.id === linkageId);

                    if (standardIndex !== -1) {
                        tableData.splice(standardIndex, 1);
                    }
                    if (estimationIndex !== -1) {
                        tableData.splice(estimationIndex, 1);
                    }
                    if (linkageIndex !== -1) {
                        tableData.splice(linkageIndex, 1);
                    }

                    // Remove the rows from the DOM
                    const standardRow = document.querySelector(`tr[data-row-id="${standardRowId}"]`);
                    const estimationRow = document.querySelector(`tr[data-row-id="${estimationRowId}"]`);

                    if (standardRow) {
                        standardRow.remove();
                    }
                    if (estimationRow) {
                        estimationRow.remove();
                    }

                    // Update the linkages array
                    const linkageIndexInLinkages = linkages.findIndex(link => link.id === linkageId);
                    if (linkageIndexInLinkages !== -1) {
                        linkages.splice(linkageIndexInLinkages, 1);
                    }

                    // Display the updated tableData
                    //displayJSONData(tableData);
                }

                modal.hide();
            });

            document.getElementById('cancelDelete').addEventListener('click', function () {
                modal.hide();
            });
        }

        function showMessageModal(message) {
            const modal = new bootstrap.Modal(document.getElementById('messageModal'));
            const modalBody = document.getElementById('messageModalBody');
            modalBody.textContent = message;
            modal.show();
        }

        function query() {
            const tableData = [];
            const rows = tableBody.querySelectorAll("tr");

            rows.forEach(row => {
                const rowData = {};
                const cells = row.querySelectorAll("td");

                if (row.dataset.rowId.startsWith("special-")) {
                    const inputCell = cells[0];
                    const inputValue = inputCell.querySelector("input").value;
                    rowData.id = row.dataset.rowId;
                    rowData.name = inputValue;
                    rowData.selection = inputCell.style.backgroundColor === "blue" ? "ON" : "OFF"; // Ajouter la variable selection
                } else if (row.dataset.rowId.startsWith("estimation-")) {
                    const inputCell = cells[0];
                    const inputValue = inputCell.querySelector("input").value;
                    rowData.id = row.dataset.rowId;
                    rowData.name = inputValue;
                    rowData.estimationValue = cells[2].querySelector("input").value;
                    rowData.selectValue = cells[1].querySelector("select").value;
                    rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION
                } else {
                    rowData.id = row.dataset.rowId;
                    rowData.name = cells[0].querySelector("input").value;
                    rowData.selectValue = cells[1].querySelector("select").value;
                    rowData.count = cells[2].textContent.trim();
                    rowData.cells = [];
                    rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION

                    cells.forEach((cell, index) => {
                        if (index > 2) {
                            rowData.cells.push({
                                value: cell.dataset.cellValue,
                                color: cell.dataset.cellColor,
                                full_date: cell.dataset.fullDate // Ajouter la clé full_date
                            });
                        }
                    });
                }

                tableData.push(rowData);
            });

            // Ajouter les objets linkage au tableau de données
            linkages.forEach(linkage => {
                tableData.push({
                    id: linkage.id,
                    standardRowId: linkage.standardRowId,
                    estimationRowId: linkage.estimationRowId
                });
            });

            //return tableData;

            //const tableData = traceTable();
            console.log("Données retournées par traceTable():", JSON.stringify(tableData, null, 2));
        }

        function traceTable() {
            const tableData = [];
            const rows = tableBody.querySelectorAll("tr");

            // Parcourir chaque ligne du tableau et récupérer les données des cellules
            rows.forEach(row => {
                const rowData = {};
                const cells = row.querySelectorAll("td");

                if (row.dataset.rowId.startsWith("special-")) {
                    const inputCell = cells[0];
                    const inputValue = inputCell.querySelector("input").value;
                    rowData.id = row.dataset.rowId;
                    rowData.name = inputValue;
                    rowData.selection = inputCell.style.backgroundColor === "blue" ? "ON" : "OFF"; // Ajouter la variable selection
                } else if (row.dataset.rowId.startsWith("estimation-")) {
                    const inputCell = cells[0];
                    const inputValue = inputCell.querySelector("input").value;
                    rowData.id = row.dataset.rowId;
                    rowData.name = inputValue;
                    rowData.estimationValue = cells[2].querySelector("input").value;
                    rowData.selectValue = cells[1].querySelector("select").value;
                    rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION
                } else {
                    rowData.id = row.dataset.rowId;
                    rowData.name = cells[0].querySelector("input").value;
                    rowData.selectValue = cells[1].querySelector("select").value;
                    rowData.count = cells[2].textContent.trim();
                    rowData.cells = [];
                    rowData.selection = cells[0].style.backgroundColor === "red" ? "ON" : "OFF"; // TAG : SELECTION

                    cells.forEach((cell, index) => {
                        if (index > 2) {
                            rowData.cells.push({
                                value: cell.dataset.cellValue,
                                color: cell.dataset.cellColor,
                                full_date: cell.dataset.fullDate // Ajouter la clé full_date
                            });
                        }
                    });
                }

                tableData.push(rowData);
            });

            // Ajouter les objets linkage au tableau de données
            linkages.forEach(linkage => {
                tableData.push({
                    id: linkage.id,
                    standardRowId: linkage.standardRowId,
                    estimationRowId: linkage.estimationRowId
                });
            });

            console.log("TRACE");
            return tableData;
        }

        function openRangeSelectionModal(cell) {
            const modal = new bootstrap.Modal(document.getElementById('rangeSelectionModal'));
            const startCellIdInput = document.getElementById('startCellId');
            const endCellIdInput = document.getElementById('endCellId');
            const rangeResult = document.getElementById('rangeResult');
            const rangeComboBox = document.getElementById('rangeComboBox');

            rangeComboBox.innerHTML = "";
            for (let i = 1; i <= 50; i++) {
                const option = document.createElement("option");
                option.value = i;
                option.textContent = i;
                rangeComboBox.appendChild(option);
            }

            rangeComboBox.addEventListener("change", function () {
                const startCellId = startCellIdInput.value;
                const startParts = startCellId.split('-');
                const startNumber = parseInt(startParts[2], 10);
                const comboValue = parseInt(rangeComboBox.value, 10);
                const totalDays = startNumber + comboValue;
                const endCellId = `${startParts[0]}-${startParts[1]}-${totalDays}`;

                console.log("Valeur sélectionnée :", comboValue);
                console.log("Nb jours :", totalDays);
                rangeResult.textContent = `Nb jours : ${totalDays}`;

                endCellIdInput.value = endCellId;
            });

            startCellIdInput.value = cell.dataset.cellId;
            endCellIdInput.value = "";
            rangeResult.textContent = "Nb jours : 0";

            modal.show();

            document.getElementById('confirmRangeSelection').addEventListener('click', function () {
                const startCellId = startCellIdInput.value;
                const endCellId = endCellIdInput.value;
                const comboValue = rangeComboBox.value;

                alert(startCellId + "  " + endCellId);

                updateCellRange(startCellId, endCellId, comboValue);
                modal.hide();
            });

            document.getElementById('cancelRangeSelection').addEventListener('click', function () {
                modal.hide();
            });

            const modalHeader = modal._dialog.querySelector('.modal-header');
            let isDragging = false;
            let offsetX, offsetY;

            modalHeader.addEventListener('mousedown', function (event) {
                isDragging = true;
                offsetX = event.clientX - modal._dialog.offsetLeft;
                offsetY = event.clientY - modal._dialog.offsetTop;
                modal._dialog.style.pointerEvents = 'none';
            });

            document.addEventListener('mousemove', function (event) {
                if (isDragging) {
                    modal._dialog.style.left = `${event.clientX - offsetX}px`;
                    modal._dialog.style.top = `${event.clientY - offsetY}px`;
                }
            });

            document.addEventListener('mouseup', function () {
                isDragging = false;
                modal._dialog.style.pointerEvents = 'all';
            });

            endCellIdInput.addEventListener('input', function () {
                const startParts = startCellIdInput.value.split('-');
                const endParts = endCellIdInput.value.split('-');

                if (startParts.length === 3 && endParts.length === 3 && startParts[0] === endParts[0] && startParts[1] === endParts[1]) {
                    const startValue = parseInt(startParts[2], 10);
                    const endValue = parseInt(endParts[2], 10);

                    console.log(" ++  " + startValue + " " + endValue);

                    const result = endValue - startValue;
                    rangeResult.textContent = `Nb jours : ${result} jours`;
                    if (result > 0) {
                        alert(`Nb jours : ${result} jours`);
                    }
                } else {
                    rangeResult.textContent = "Nb jours : 0";
                }
            });
        }

        function updateCellRange(startCellId, endCellId) {
            const startCell = document.querySelector(`td[data-cell-id="${startCellId}"]`);
            const endCell = document.querySelector(`td[data-cell-id="${endCellId}"]`);

            if (startCell && endCell && startCell.parentElement === endCell.parentElement) {
                const startIndex = Array.from(startCell.parentElement.cells).indexOf(startCell);
                const endIndex = Array.from(endCell.parentElement.cells).indexOf(endCell);

                for (let i = startIndex; i <= endIndex; i++) {
                    const cell = startCell.parentElement.cells[i];
                    cell.dataset.cellValue = "1";
                    cell.textContent = "1";
                    cell.style.backgroundColor = "green";
                    cell.dataset.cellColor = "green";
                    updateRowData(cell);
                }

                updateCountCell(startCell.parentElement);
            } else {
                showMessageModal("Les cellules doivent être sur la même ligne.");
            }
        }

        tableBody.addEventListener("mouseover", function (event) {
            const cell = event.target.closest("td");
            if (cell) {
                currentCell = cell;
            }
        });

        document.addEventListener("keydown", function (event) {
            if (event.key === "p" && currentCell) {
                openRangeSelectionModal(currentCell);
            }
        });

        document.getElementById("SauveButton").addEventListener("click", function () {
            const rows = tableBody.querySelectorAll("tr");

            if (rows.length === 0) {
                showMessageModal("Aucune ligne à sauvegarder. Veuillez ajouter des lignes avant de sauvegarder.");
            } else {
                const modal = new bootstrap.Modal(document.getElementById('confirmSaveModal'));
                modal.show();

                document.getElementById('confirmSave').addEventListener('click', function () {
                    Jsondata();
                    modal.hide();
                });

                document.getElementById('cancelSave').addEventListener('click', function () {
                    modal.hide();
                });
            }
        });

      /*  function async  Jsondata() 
        {
            const jsonData = [];
            const rows = document.querySelectorAll("tbody tr");

            rows.forEach(row => {
                const rowId = row.dataset.rowId;
                const cells = row.querySelectorAll("td");

                if (rowId.startsWith("standard-")) {
                    const standardRow = {
                        id: rowId,
                        name: cells[0].querySelector("input").value,
                        selectValue: cells[1].querySelector("select").value,
                        count: cells[2].textContent.trim(),
                        cells: [],
                        selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION
                    };

                    cells.forEach((cell, index) => {
                        if (index > 2) {
                            standardRow.cells.push({
                                value: cell.dataset.cellValue,
                                color: cell.dataset.cellColor,
                                full_date: cell.dataset.fullDate // Ajouter la clé full_date
                            });
                        }
                    });

                    jsonData.push(standardRow);
                } else if (rowId.startsWith("estimation-")) {
                    const estimationRow = {
                        id: rowId,
                        name: cells[0].querySelector("input").value,
                        selectValue: cells[1].querySelector("select").value,
                        estimationValue: cells[2].querySelector("input").value,
                        selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION
                    };

                    jsonData.push(estimationRow);
                } else if (rowId.startsWith("special-")) {
                    const specialRow = {
                        id: rowId,
                        name: cells[0].querySelector("input").value,
                        selection: cells[0].style.backgroundColor === "blue" ? "ON" : "OFF" // TAG : SELECTION
                    };

                    jsonData.push(specialRow);
                }
            });

            // Ajouter les objets linkage
            linkages.forEach(linkage => {
                jsonData.push({
                    id: linkage.id,
                    standardRowId: linkage.standardRowId,
                    estimationRowId: linkage.estimationRowId
                });
            });

            console.log(JSON.stringify(jsonData, null, 2));

            // Générer et télécharger le fichier JSON
            //generateAndDownloadJSON(jsonData);

            // Demander à l'utilisateur de choisir un nom de fichier
            try {
                    const fileHandle = await window.showSaveFilePicker({
                        suggestedName: 'table_data.json',
                        types: [{
                            description: 'JSON Files',
                            accept: {
                                'application/json': ['.json'],
                            },
                        }],
                    });

                    // Écrire les données dans le fichier
                    const writableStream = await fileHandle.createWritable();
                    await writableStream.write(jsonDataStr);
                    await writableStream.close();

                    console.log('Fichier sauvegardé avec succès.');
            } 
            catch (error) 
            {
                console.error('Erreur lors de la sauvegarde du fichier :', error);
                showMessageModal('Une erreur est survenue lors de la sauvegarde du fichier.');
            }

        }
*/

async function Jsondata() 
{
    const jsonData = [];
    const rows = document.querySelectorAll("tbody tr");

    rows.forEach(row => {
        const rowId = row.dataset.rowId;
        const cells = row.querySelectorAll("td");

        if (rowId.startsWith("standard-")) {
            const standardRow = {
                id: rowId,
                name: cells[0].querySelector("input").value,
                selectValue: cells[1].querySelector("select").value,
                count: cells[2].textContent.trim(),
                cells: [],
                selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION
            };

            cells.forEach((cell, index) => {
                if (index > 2) {
                    standardRow.cells.push({
                        value: cell.dataset.cellValue,
                        color: cell.dataset.cellColor,
                        full_date: cell.dataset.fullDate // Ajouter la clé full_date
                    });
                }
            });

            jsonData.push(standardRow);
        } else if (rowId.startsWith("estimation-")) {
            const estimationRow = {
                id: rowId,
                name: cells[0].querySelector("input").value,
                selectValue: cells[1].querySelector("select").value,
                estimationValue: cells[2].querySelector("input").value,
                selection: cells[0].style.backgroundColor === "red" ? "ON" : "OFF" // TAG : SELECTION
            };

            jsonData.push(estimationRow);
        } else if (rowId.startsWith("special-")) {
            const specialRow = {
                id: rowId,
                name: cells[0].querySelector("input").value,
                selection: cells[0].style.backgroundColor === "blue" ? "ON" : "OFF" // TAG : SELECTION
            };

            jsonData.push(specialRow);
        }
    });

    // Ajouter les objets linkage
    linkages.forEach(linkage => {
        jsonData.push({
            id: linkage.id,
            standardRowId: linkage.standardRowId,
            estimationRowId: linkage.estimationRowId
        });
    });

    console.log(JSON.stringify(jsonData, null, 2));

    // Convertir les données en chaîne JSON
    const jsonDataStr = JSON.stringify(jsonData, null, 2);

    // Demander à l'utilisateur de choisir un nom de fichier
    try {
        const fileHandle = await window.showSaveFilePicker({
            suggestedName: 'table_data.json',
            types: [{
                description: 'JSON Files',
                accept: {
                    'application/json': ['.json'],
                },
            }],
        });

        // Écrire les données dans le fichier
        const writableStream = await fileHandle.createWritable();
        await writableStream.write(jsonDataStr);
        await writableStream.close();

        console.log('Fichier sauvegardé avec succès.');
    } catch (error) {
        console.error('Erreur lors de la sauvegarde du fichier :', error);
        showMessageModal('Une erreur est survenue lors de la sauvegarde du fichier.');
    }
}


        function generateAndDownloadJSON(jsonData) {
            // Convertir les données en chaîne JSON
            const jsonDataStr = JSON.stringify(jsonData, null, 2);

            // Créer un blob avec les données JSON
            const blob = new Blob([jsonDataStr], { type: 'application/json' });

            // Créer un lien de téléchargement
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = 'table_data.json';

            // Ajouter le lien au DOM et déclencher le téléchargement
            document.body.appendChild(a);
            a.click();

            // Nettoyer
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }

        function logRowTypes() {
            console.log("TRACE Start");

            const rowDataArray = [];

            const rows = tableBody.querySelectorAll("tr");
            const rowTypes = {
                standard: 0,
                estimation: 0,
                special: 0
            };

            linkages.forEach((linkage, index) => {
                rowDataArray.push(linkage);
            });

            rows.forEach(row => {
                const rowId = row.dataset.rowId;
                if (rowId.startsWith("standard-")) {
                    rowTypes.standard++;
                } else if (rowId.startsWith("estimation-")) {
                    rowTypes.estimation++;
                } else if (rowId.startsWith("special-")) {
                    rowTypes.special++;
                }

                let rowData = null;
                if (rowId.startsWith("standard-")) {
                    rowData = standardRowsData.find(data => data.id === rowId);
                } else if (rowId.startsWith("estimation-")) {
                    rowData = estimationRowsData.find(data => data.id === rowId);
                } else if (rowId.startsWith("special-")) {
                    rowData = specialRowsData.find(data => data.id === rowId);
                }

                if (rowData) {
                    console.log("Identifiant de la ligne :", rowId);
                    console.log("Détails de l'objet :", rowData);
                    rowDataArray.push(rowData);
                } else {
                    console.log("Aucune donnée trouvée pour l'identifiant de la ligne :", rowId);
                }
            });

            linkages.forEach((linkage, index) => {
                console.log(`Liaison ${index + 1} :`, linkage);
            });

            console.log("Nombre de lignes standard :", rowTypes.standard);
            console.log("Nombre de lignes d'estimation :", rowTypes.estimation);
            console.log("Nombre de lignes spéciales :", rowTypes.special);

            sendDataToPHP(rowDataArray);

            console.log("TRACE end");
        }

        function sendDataToPHP(rowDataArray) {
            // Afficher les données dans la console
            console.log("Données envoyées à PHP :", rowDataArray);

            // Envoyer les données au script PHP
            fetch('script_export02.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(rowDataArray)
            })
            .then(response => response.json())
            .then(data => {
                // Gérer les différents types de messages renvoyés
                if (data.status === 'success') {
                    console.log('Succès :', data.message);
                    showMessageModal(data.message);
                } else if (data.status === 'error') {
                    console.error('Erreur :', data.message);
                    showMessageModal(data.message);
                } else {
                    console.error('Réponse inattendue :', data);
                    showMessageModal('Réponse inattendue du serveur.');
                }
            })
            .catch(error => {
                console.error('Erreur :', error);
                showMessageModal('Une erreur est survenue lors de l\'envoi des données.');
            });
        }

       //document.getElementById("ChargeButton").addEventListener("click", fetchJsonData);

/************************/
        function original_fetchJsonData() 
        {
            // Envoyer une requête GET au script PHP
            fetch('script_import_02.php')
                .then(response => response.json())
                .then(data => {
                    // Gérer les différents types de messages renvoyés
                    if (data.status === 'success') {

                        //console.log("<--------------- Début file.json  --------------------->");

                        console.log('Données JSON récupérées :', data.data);

                        // Parcourir chaque élément (sous-tableau JSON) de data
                        data.data.forEach((item, index) => {
                            //console.log("<------------------------------------>");
                            //console.log(`Élément ${index + 1} :`);

                            if (item.id.includes('standard')) {
                                //console.log('Détails de la ligne standard :');
                                for (const key in item) {
                                    if (item.hasOwnProperty(key)) {
                                        if (key === 'cells' && Array.isArray(item[key])) {
                                            //console.log(`  ${key}:`);
                                            /* pas utile de voir le détail de chaque cellule
                                            item[key].forEach((cell, cellIndex) => {
                                                console.log(`    Cell ${cellIndex + 1}:`);
                                                for (const cellKey in cell) {
                                                    if (cell.hasOwnProperty(cellKey)) {
                                                        console.log(`      ${cellKey}: ${cell[cellKey]}`);
                                                    }
                                                }
                                            });*/
                                        }
                                        else {
                                           // console.log(`  ${key}: ${item[key]}`);
                                        }
                                    }
                                }
                            }

                            else if (item.id.includes('estimation')) {
                                //console.log('Détails de la ligne d\'estimation :');
                                for (const key in item) {
                                    if (item.hasOwnProperty(key)) {
                                        //console.log(`  ${key}: ${item[key]}`);
                                    }
                                }
                            } else if (item.id.includes('special')) {
                                //console.log('Détails de la ligne spéciale :');
                                for (const key in item) {
                                    if (item.hasOwnProperty(key)) {
                                        //console.log(`  ${key}: ${item[key]}`);
                                    }
                                }
                            }
                            else if (item.id.includes('linkage')) {
                                //console.log('Détails de la liaison :');
                                for (const key in item) {
                                    if (item.hasOwnProperty(key)) {
                                        //console.log(`  ${key}: ${item[key]}`);
                                    }
                                }
                            }

                            else {
                                //console.log('Type de ligne inconnu :', item.id);
                            }
                        });

                        //console.log("<--------------- FIN file.json  --------------------->");

                        //preparation(data.data);
                        regeneration(data.data);
                    }
                    else if (data.status === 'error') {
                        console.error('Erreur :', data.message);
                        showMessageModal(data.message);
                    }
                    else {
                        console.error('Réponse inattendue :', data);
                        showMessageModal('Réponse inattendue du serveur.');
                    }
                })
                .catch(error => {
                    console.error('Erreur :', error);
                    showMessageModal('Une erreur est survenue lors de la récupération des données.');
                });
        }


 /*****************************/       
 
 document.getElementById("loadJsonButton").addEventListener("click", function () {
    document.getElementById("fileInput").click();
});

document.getElementById("fileInput").addEventListener("change", function (event) 
{
    const file = event.target.files[0];
    if (file) {
        const reader = new FileReader();
        reader.onload = function (e) {
            try 
            {
                    const data = JSON.parse(e.target.result);
                    console.log('Données JSON récupérées :', data.data);

                    // Parcourir chaque élément (sous-tableau JSON) de data
                    data.forEach((item, index) => 
                    {
                        console.log(`Élément ${index + 1} :`);

                        if (item.id.includes('standard')) 
                        {
                            console.log('Détails de la ligne standard :');
                            for (const key in item) {
                                if (item.hasOwnProperty(key)) {
                                    if (key === 'cells' && Array.isArray(item[key])) {
                                        console.log(`  ${key}:`);
                                        // pas utile de voir le détail de chaque cellule
                                        /*item[key].forEach((cell, cellIndex) => {
                                            console.log(`    Cell ${cellIndex + 1}:`);
                                            for (const cellKey in cell) {
                                                if (cell.hasOwnProperty(cellKey)) {
                                                    console.log(`      ${cellKey}: ${cell[cellKey]}`);
                                                }
                                            }
                                        });*/
                                    } else {
                                        console.log(`  ${key}: ${item[key]}`);
                                    }
                                }
                            }
                        } 
                        else if (item.id.includes('estimation')) 
                        {
                            console.log('Détails de la ligne d\'estimation :');
                            for (const key in item) {
                                if (item.hasOwnProperty(key)) {
                                    console.log(`  ${key}: ${item[key]}`);
                                }
                            }
                        } 
                        else if (item.id.includes('special')) 
                        {
                            console.log('Détails de la ligne spéciale :');
                            for (const key in item) {
                                if (item.hasOwnProperty(key)) {
                                    console.log(`  ${key}: ${item[key]}`);
                                }
                            }
                        } 
                        else if (item.id.includes('linkage')) 
                        {
                            console.log('Détails de la liaison :');
                            for (const key in item) {
                                if (item.hasOwnProperty(key)) {
                                    console.log(`  ${key}: ${item[key]}`);
                                }
                            }
                        } 
                        else 
                        {
                            console.log('Type de ligne inconnu :', item.id);
                        }
                    });

                    // Appeler la fonction de régénération avec les données récupérées
                    regeneration(data);
                 
            } 
            catch (error) 
            {
                console.error('Erreur lors de la lecture du fichier :', error);
            }
        };
        reader.readAsText(file);
    }
});

 function bis_fetchJsonData() 
 {
    // Utiliser fetch pour lire le fichier JSON local
    fetch('file_changed.json')
        .then(response => {
            if (!response.ok) {
                throw new Error('Network response was not ok');
            }
            return response.json();
        })
        .then(data => {
            // Gérer les différents types de messages renvoyés
            
                console.log('Données JSON récupérées :', data.data);

                // Parcourir chaque élément (sous-tableau JSON) de data
                data.forEach((item, index) => {
                    console.log(`Élément ${index + 1} :`);

                    if (item.id.includes('standard')) {
                        console.log('Détails de la ligne standard :');
                        for (const key in item) {
                            if (item.hasOwnProperty(key)) {
                                if (key === 'cells' && Array.isArray(item[key])) {
                                    console.log(`  ${key}:`);
                                    // pas utile de voir le détail de chaque cellule
                                    /*item[key].forEach((cell, cellIndex) => {
                                        console.log(`    Cell ${cellIndex + 1}:`);
                                        for (const cellKey in cell) {
                                            if (cell.hasOwnProperty(cellKey)) {
                                                console.log(`      ${cellKey}: ${cell[cellKey]}`);
                                            }
                                        }
                                    });*/
                                } else {
                                    console.log(`  ${key}: ${item[key]}`);
                                }
                            }
                        }
                    } else if (item.id.includes('estimation')) {
                        console.log('Détails de la ligne d\'estimation :');
                        for (const key in item) {
                            if (item.hasOwnProperty(key)) {
                                console.log(`  ${key}: ${item[key]}`);
                            }
                        }
                    } else if (item.id.includes('special')) {
                        console.log('Détails de la ligne spéciale :');
                        for (const key in item) {
                            if (item.hasOwnProperty(key)) {
                                console.log(`  ${key}: ${item[key]}`);
                            }
                        }
                    } else if (item.id.includes('linkage')) {
                        console.log('Détails de la liaison :');
                        for (const key in item) {
                            if (item.hasOwnProperty(key)) {
                                console.log(`  ${key}: ${item[key]}`);
                            }
                        }
                    } else {
                        console.log('Type de ligne inconnu :', item.id);
                    }
                });

                // Appeler la fonction de régénération avec les données récupérées
                regeneration(data);
            
        })
        
}


/******************************/ 

        function showMessageModal(message) {
            const modal = new bootstrap.Modal(document.getElementById('messageModal'));
            const modalBody = document.getElementById('messageModalBody');
            modalBody.textContent = message;
            modal.show();
        }

        function display_import(data) {
            // Parcourir chaque élément (sous-tableau JSON) de data
            data.forEach((item, index) => {
                console.log(`Élément ${index + 1} :`);

                // Vérifier si l'id contient 'standard', 'estimation' ou 'special'
                if (item.id.includes('standard')) {
                    console.log('Import : détails de la ligne standard :');
                    for (const key in item) {
                        if (item.hasOwnProperty(key)) {
                            if (key === 'cells' && Array.isArray(item[key])) {
                                console.log(`  ${key}:`);
                                // pas utile de voir le détail de chaque cellule
                                /*item[key].forEach((cell, cellIndex) => {
                                    console.log(`    Cell ${cellIndex + 1}:`);
                                    for (const cellKey in cell) {
                                        if (cell.hasOwnProperty(cellKey)) {
                                            console.log(`      ${cellKey}: ${cell[cellKey]}`);
                                        }
                                    }
                                });*/
                            } else {
                                console.log(`  ${key}: ${item[key]}`);
                            }
                        }
                    }
                } else if (item.id.includes('estimation')) {
                    console.log('Import : Détails de la ligne d\'estimation :');
                    for (const key in item) {
                        if (item.hasOwnProperty(key)) {
                            console.log(`  ${key}: ${item[key]}`);
                        }
                    }
                } else if (item.id.includes('special')) {
                    console.log('Import : Détails de la ligne spéciale :');
                    for (const key in item) {
                        if (item.hasOwnProperty(key)) {
                            console.log(`  ${key}: ${item[key]}`);
                        }
                    }
                }
                else if (item.id.includes('linkage')) {
                    console.log('Détails de la liaison :');
                    for (const key in item) {
                        if (item.hasOwnProperty(key)) {
                            console.log(`  ${key}: ${item[key]}`);
                        }
                    }
                }

                else {
                    console.log('Type de ligne inconnu :', item.id);
                }
            });
        }

        function code_annexe(data) {
            /*
            console.log(" ********** Début recherche ******************** ");

            // Afficher le contenu détaillé des objets
            //console.log("Contenu de standardRowsData :");
            standardRowsData.forEach((row, index) => {
                console.log(`Ligne standard ${index + 1} :`, row);
            });

            //console.log("Contenu de estimationRowsData :");
            estimationRowsData.forEach((row, index) => {
                console.log(`Ligne d'estimation ${index + 1} :`, row);
            });

            //console.log("Contenu de specialRowsData :");
            specialRowsData.forEach((row, index) => {
                console.log(`Ligne spéciale ${index + 1} :`, row);
            });

            //console.log("Contenu de linkages :");
            linkages.forEach((linkage, index) => {
                console.log(`Liaison ${index + 1} :`, linkage);
            });

            console.log(" ********** Fin recherche ******************** ");

            console.log(" ********** Début vérification purge  ******************** ");

            standardRowsData.length = 0;
            estimationRowsData.length = 0;
            specialRowsData.length = 0;
            linkages.length = 0;

            if (standardRowsData.length === 0) {
                console.log("  standardRowsData empty");
            }
            if (estimationRowsData.length === 0) {
                console.log("  estimationRowsData empty");
            }
            if (specialRowsData.length === 0) {
                console.log("  specialRowsData empty");
            }
            if (linkages.length === 0) {
                console.log("  linkages  empty");
            }

            console.log(" ********** Fin vérification purge  ******************** ");
            */
            // Afficher le nombre de sous-tableaux dans data
            //console.log("Nombre de sous-tableaux dans data :", data.length);

            /*for (const item of data)
            {
                if (item.id.includes('special'))
                {
                    const specialRowData = {
                        id: item.id,
                        name: item.name
                    };
                    specialRowsData.push(specialRowData);
                }
            }*/

            /*for (let i = 0; i < data.length; i++)
            {
                console.log(" Indice " + i);
            }*/
        }

        function regeneration(data) {
            console.log("Purging table and regenerating rows...");

            // Clear existing table data
            tableBody.innerHTML = "";
            standardRowsData.length = 0;
            estimationRowsData.length = 0;
            specialRowsData.length = 0;
            linkages.length = 0;
            objet_selection = []; // Réinitialiser l'objet objet_selection

            data.forEach(item => {
                if (item.id.includes('linkage')) {
                    console.log("Creating a linkage...");
                    const linkage = {
                        id: item.id,
                        standardRowId: item.standardRowId,
                        estimationRowId: item.estimationRowId,
                    };
                    linkages.push(linkage);
                }

                if (item.id.includes('standard')) {
                    console.log("Creating a standard row...");
                    const standardRowData = {
                        id: item.id,
                        name: item.name,
                        selectValue: item.selectValue,
                        count: item.count,
                        cells: item.cells,
                        selection: item.selection // TAG : SELECTION
                    };
                    standardRowsData.push(standardRowData);

                    const standardRow = document.createElement("tr");
                    standardRow.setAttribute("draggable", "true");
                    standardRow.dataset.rowId = item.id;
                    standardRow.title = standardRow.dataset.rowId; // Ajoutez cette ligne

                    const firstCells = [item.name, "", item.count];
                    firstCells.forEach((text, index) => {
                        const td = document.createElement("td");
                        td.dataset.cellId = `cell-${item.id}-${index}`;
                        if (index === 0) {
                            const input = document.createElement("input");
                            input.type = "text";
                            input.classList.add("editable-input");
                            input.value = item.name;
                            input.addEventListener("click", function (event) {
                                event.stopPropagation();
                                input.focus();
                                input.style.width = "130px";
                                console.log("Input clicked, setting width to 130px");
                            });
                            input.addEventListener("blur", function () {
                                if (!keydownHandled && !alertShown) {
                                    alertShown = true;
                                    input.classList.remove("editing");
                                    input.blur();
                                    input.style.width = "65px";
                                    console.clear;
                                    updateRowData(input);
                                }
                                keydownHandled = false;
                                alertShown = false;
                            });
                            input.addEventListener("keydown", function (event) {
                                if (event.key === "Escape" || event.key === "Enter") {
                                    keydownHandled = true;
                                    if (!alertShown) {
                                        alertShown = true;
                                        input.classList.remove("editing");
                                        input.blur();
                                        input.style.width = "65px";
                                        console.clear;
                                        updateRowData(input);
                                    }
                                }
                            });
                            td.appendChild(input);
                        } else if (index === 1) {
                            const select = document.createElement("select");
                            for (let i = 1; i <= 10; i++) {
                                const option = document.createElement("option");
                                option.value = i;
                                option.textContent = `Option ${i}`;
                                select.appendChild(option);
                            }
                            select.value = item.selectValue;
                            select.addEventListener("change", function () {
                                updateRowData(select);
                            });
                            td.appendChild(select);
                        } else {
                            td.textContent = text;
                        }

                        if (index === 0) {
                            td.classList.add("row-header");
                            td.addEventListener("click", function (event) {
                                event.preventDefault();
                                handleRowClick(standardRow, td); // TAG : SELECTION
                            });
                            td.addEventListener("contextmenu", function (event) {
                                event.preventDefault();
                                showContextMenu(event, standardRow);
                            });
                        }

                        standardRow.appendChild(td);
                    });

                    const headerCells = document.querySelectorAll("thead tr:nth-child(2) th:not(.weekend):not(.holiday)");
                    const workingDaysCount = headerCells.length;

                    for (let i = 0; i < workingDaysCount - 3; i++) {
                        const td = document.createElement("td");
                        td.dataset.cellId = `cell-${item.id}-${i}`;
                        td.dataset.cellValue = item.cells[i].value;
                        td.dataset.cellColor = item.cells[i].color;
                        td.dataset.fullDate = item.cells[i].full_date; // Ajouter la clé full_date
                        td.textContent = item.cells[i].value;
                        td.style.backgroundColor = item.cells[i].color;

                        td.addEventListener("click", function () {
                            const newValue = td.dataset.cellValue === "0" ? "1" : "0";
                            td.dataset.cellValue = newValue;
                            td.textContent = newValue;
                            td.style.backgroundColor = newValue === "1" ? "green" : "white";
                            td.dataset.cellColor = newValue === "1" ? "green" : "white";
                            updateCountCell(standardRow);
                            updateRowData(td);
                        });

                        td.addEventListener("contextmenu", function (event) {
                            event.preventDefault();
                            if (td.dataset.cellValue === "1") {
                                showColorContextMenu(event, td);
                            }
                        });

                        // Ajouter l'écouteur d'événement pour afficher la date complète
                        td.addEventListener("click", function (event) {
                            const fullDate = event.target.dataset.fullDate;
                            console.log("Date complète :", fullDate);
                            //alert(fullDate);
                            // Maintenant utiliser fullDate pour d'autres opérations
                        });

                        td.title = `ID: ${td.dataset.cellId}`;

                        standardRow.appendChild(td);
                    }

                    if (item.selection === "ON") {
                        standardRow.cells[0].style.backgroundColor = "red";
                    }

                    tableBody.appendChild(standardRow);

                    standardRow.addEventListener("dragstart", dragStart);
                    standardRow.addEventListener("dragover", dragOver);
                    standardRow.addEventListener("drop", drop);
                }

                if (item.id.includes('estimation')) {
                    console.log("Creating an estimation row...");
                    const estimationRowData = {
                        id: item.id,
                        name: item.name,
                        selectValue: item.selectValue,
                        estimationValue: item.estimationValue,
                        selection: item.selection // TAG : SELECTION
                    };
                    estimationRowsData.push(estimationRowData);

                    const estimationRow = document.createElement("tr");
                    estimationRow.setAttribute("draggable", "true");
                    estimationRow.dataset.rowId = item.id;
                    estimationRow.classList.add("estimation-row");
                    estimationRow.title = estimationRow.dataset.rowId; // Ajoutez cette ligne

                    const estimationFirstCells = [item.name, "", item.estimationValue];
                    estimationFirstCells.forEach((text, index) => {
                        const td = document.createElement("td");
                        td.dataset.cellId = `cell-${item.id}-${index}`;
                        if (index === 0) {
                            const input = document.createElement("input");
                            input.type = "text";
                            input.classList.add("editable-input");
                            input.value = item.name;
                            input.addEventListener("click", function (event) {
                                event.stopPropagation();
                                input.focus();
                                input.style.width = "130px";
                                console.log("Input clicked, setting width to 130px");
                            });
                            input.addEventListener("blur", function () {
                                if (!keydownHandled && !alertShown) {
                                    alertShown = true;
                                    input.classList.remove("editing");
                                    input.blur();
                                    input.style.width = "65px";
                                    console.clear;
                                    updateRowData(input);
                                }
                                keydownHandled = false;
                                alertShown = false;
                            });
                            input.addEventListener("keydown", function (event) {
                                if (event.key === "Escape" || event.key === "Enter") {
                                    keydownHandled = true;
                                    if (!alertShown) {
                                        alertShown = true;
                                        input.classList.remove("editing");
                                        input.blur();
                                        input.style.width = "65px";
                                        console.clear;
                                        updateRowData(input);
                                    }
                                }
                            });
                            td.appendChild(input);
                        } else if (index === 1) {
                            const select = document.createElement("select");
                            for (let i = 1; i <= 10; i++) {
                                const option = document.createElement("option");
                                option.value = i;
                                option.textContent = `Option ${i}`;
                                select.appendChild(option);
                            }
                            select.value = item.selectValue;
                            select.addEventListener("change", function () {
                                updateRowData(select);
                            });
                            td.appendChild(select);
                        } else {
                            const input = document.createElement("input");
                            input.type = "text";
                            input.classList.add("editable-input");
                            input.value = text;
                            input.addEventListener("blur", function () {
                                const value = parseInt(input.value, 10);
                                if (isNaN(value) || value < 1 || value > 365) {
                                    input.value = "1";
                                    showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
                                } else {
                                    updateRowData(input);
                                }
                                input.classList.remove("editing");
                                input.style.width = "65px";
                            });
                            input.addEventListener("keydown", function (event) {
                                if (event.key === "Escape" || event.key === "Enter") {
                                    const value = parseInt(input.value, 10);
                                    if (isNaN(value) || value < 1 || value > 365) {
                                        input.value = "1";
                                        showMessageModal("La valeur doit être un nombre entier compris entre 1 et 365.");
                                    } else {
                                        updateRowData(input);
                                    }
                                    input.classList.remove("editing");
                                    input.blur();
                                    input.style.width = "65px";
                                }
                            });
                            td.appendChild(input);
                        }

                        if (index === 0) {
                            td.classList.add("row-header");
                            td.addEventListener("click", function (event) {
                                event.preventDefault();
                                handleRowClick(estimationRow, td); // TAG : SELECTION
                            });
                            td.addEventListener("contextmenu", function (event) {
                                event.preventDefault();
                                showContextMenu(event, estimationRow);
                            });
                        }

                        estimationRow.appendChild(td);
                    });

                    const mergedCell = document.createElement("td");
                    mergedCell.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
                    mergedCell.textContent = "";
                    mergedCell.classList.add("no-click");
                    estimationRow.appendChild(mergedCell);

                    if (item.selection === "ON") {
                        estimationRow.cells[0].style.backgroundColor = "red";
                    }

                    tableBody.appendChild(estimationRow);

                    estimationRow.addEventListener("dragstart", dragStart);
                    estimationRow.addEventListener("dragover", dragOver);
                    estimationRow.addEventListener("drop", drop);
                }

                if (item.id.includes('special')) {
                    console.log("Creating a special row...");
                    const specialRowData = {
                        id: item.id,
                        name: item.name,
                        selection: item.selection // TAG : SELECTION
                    };
                    specialRowsData.push(specialRowData);

                    const specialRow = document.createElement("tr");
                    specialRow.classList.add("special-row");
                    specialRow.setAttribute("draggable", "true");
                    specialRow.dataset.rowId = item.id;
                    specialRow.title = specialRow.dataset.rowId; // Ajoutez cette ligne

                    const firstCell = document.createElement("td");
                    firstCell.classList.add("row-header");

                    const input = document.createElement("input");
                    input.type = "text";
                    input.classList.add("editable-input");
                    input.value = item.name;
                    input.addEventListener("click", function (event) {
                        event.stopPropagation();
                        input.focus();
                        input.style.width = "130px";
                        console.log("Input clicked, setting width to 130px");
                    });
                    input.addEventListener("blur", function () {
                        input.classList.remove("editing");
                        input.style.width = "65px";
                        updateRowData(input);
                    });
                    input.addEventListener("keydown", function (event) {
                        if (event.key === "Escape" || event.key === "Enter") {
                            input.classList.remove("editing");
                            input.blur();
                            input.style.width = "65px";
                            updateRowData(input);
                        }
                    });
                    input.addEventListener("input", function () {
                        updateRowData(input);
                    });

                    const addButton = document.createElement("button");
                    addButton.classList.add("add-button");
                    addButton.textContent = "+";
                    addButton.addEventListener("click", function () {
                        toggleCollapse(specialRow);
                    });

                    firstCell.appendChild(input);
                    firstCell.appendChild(addButton);
                    firstCell.addEventListener("contextmenu", function (event) {
                        event.preventDefault();
                        showSpecialContextMenu(event, specialRow);
                    });

                    // Ajouter un gestionnaire de clic pour changer la couleur de fond
                    firstCell.addEventListener("click", function () {
                        handleSpecialRowClick(specialRow, firstCell);
                    });

                    if (item.selection === "ON") {
                        firstCell.style.backgroundColor = "blue";
                    }

                    specialRow.appendChild(firstCell);

                    const mergedCell = document.createElement("td");
                    mergedCell.colSpan = 2;
                    mergedCell.textContent = "";
                    specialRow.appendChild(mergedCell);

                    const td = document.createElement("td");
                    td.textContent = `${item.name} - Détails`;
                    td.colSpan = document.querySelector("thead tr:nth-child(2)").cells.length - 3;
                    specialRow.appendChild(td);

                    tableBody.appendChild(specialRow);

                    specialRow.addEventListener("dragstart", dragStart);
                    specialRow.addEventListener("dragover", dragOver);
                    specialRow.addEventListener("drop", drop);
                }
            });

            // Recréer l'objet objet_selection
            linkages.forEach(linkage => {
                const standardRowData = standardRowsData.find(data => data.id === linkage.standardRowId);
                const estimationRowData = estimationRowsData.find(data => data.id === linkage.estimationRowId);

                if (standardRowData && estimationRowData && standardRowData.selection === "ON" && estimationRowData.selection === "ON") {
                    objet_selection.push(standardRowData.id, estimationRowData.id);
                }
            });

            // Afficher les liaisons dans la console
            //displayLinkages();
        }

        document.getElementById("queryButton").addEventListener("click", function () {
            query();
        });

        document.getElementById("GraphiqueButton").addEventListener("click", function () {
            console.log("Envoie ...");

            const tableData = traceTable();
            console.log("Données envoyées à graphique.php :", tableData);

            // Filtrer les lignes pour supprimer les lignes spéciales
            //tableData = tableData.filter(row => !row.id.includes('special'));

            // Filtrer les lignes pour supprimer celles dont l'id contient "special"
            //const filteredTableData = tableData.filter(row => !row.id.includes('special'));

            const filteredTableData = tableData.filter(row => !row.id.includes('special') && !row.id.startsWith('linkage'));

            // Convertir les données en chaîne JSON
            const jsonData = JSON.stringify(filteredTableData);

            console.log("Stop ...");

            filteredTableData.forEach(row => {
                if (row.id) {
                    console.log("ID de la ligne :", row.id);
                }
            });

            // Créer un formulaire temporaire pour envoyer les données via POST
            const form = document.createElement('form');
            form.method = 'post';
            form.action = 'graphique0021.php';

            const input = document.createElement('input');
            input.type = 'hidden';
            input.name = 'data';
            input.value = jsonData;

            form.appendChild(input);
            document.body.appendChild(form);
            form.submit();
        });

        // Récupérer la valeur renvoyée
        const returnValue = sessionStorage.getItem('returnValue');

        if (returnValue === "rechargement") {
            console.log('Valeur renvoyée :', returnValue);
            // Faites quelque chose avec la valeur renvoyée
            //fetchJsonData();
            console.log("Fin");
        }
    });
</script>
</body>
</html>