сделай чтобы в календаре неупакованные дни были заливкой именно в тот день и месяц где неупакованные записи, а не дублирвоались и на следующие месяца
let isEditing = false;
let searchTimeout;
let lastUpdateTime = 0;
const updateInterval = 1000;
let eventSource;
let lastData = null;
let isDeleting = false;
let fpInstance;
let currentUnpackedDays = new Set();
const deviceSparklines = {};

// Глобальные переменные для отслеживания сортировки
let globalSortColumn = null;
let globalSortOrder = 'asc';

function getSelectedDate() {
    return $('#datepicker').val();
}

// Функция для получения состояния фильтра
function getArmaFilter() {
    return $('#armaFilter').is(':checked') ? 'RPA' : '';
}

function updateTable(force = false, highlightNew = false) {
    return new Promise((resolve, reject) => {
        const now = Date.now();
        if (!force && now - lastUpdateTime < updateInterval) {
            resolve();
            return;
        }
        if (isEditing) {
            resolve();
            return;
        }

        if (isEditing || isDeleting) { // Добавляем проверку на isDeleting
            resolve();
            return;
        }

        $.ajax({
            url: '/get_table_data',
            type: 'GET',
            data: { 
                date: getSelectedDate(),
                filter_arma: getArmaFilter()
            },
            success: function(response) {
                var tableBody = $('#tableBody');

                // Обновляем содержимое таблицы
                updateTableContent(response.data, tableBody, highlightNew);

                // Применяем текущую сортировку
                if (globalSortColumn !== null) {
                    sortTable(globalSortColumn, globalSortOrder);
                }

                updateStatistics();
                lastUpdateTime = now;

                // Проверяем и подсвечиваем дубликаты
                highlightDuplicates(response.duplicates);

                resolve();
            },
            error: function(xhr, status, error) {
                console.error('Error updating table:', error);
                reject(error);
            }
        });
    });
}

function initializeSparklines(activity) {
    for (const [name, data] of Object.entries(activity)) {
        const sparklineSpan = $(`#${name}-sparkline`);
        sparklineSpan.sparkline(data, {
            type: 'line',
            width: '100px',
            height: '30px',
            lineColor: 'green',
            fillColor: 'transparent',
            spotColor: false,
            minSpotColor: false,
            maxSpotColor: false,
            highlightSpotColor: 'blue',
            highlightLineColor: 'blue'
        });
        sparklineSpan.data('sparkline-initialized', true);
    }
}


function updateSparklines(devices, activity) {
    for (const [name, status] of Object.entries(devices)) {
        const sparklineSpan = $(`#${name}-sparkline`);
        const data = activity[name];
        // Определяем цвет линии в зависимости от статуса устройства
        let lineColor;
        if (status === 'online') {
            lineColor = 'green';
        } else if (status === 'no_internet') {
            lineColor = 'orange';
        } else {
            lineColor = 'gray';
        }
        if (sparklineSpan.data('sparkline-initialized')) {
            // Обновляем существующий Sparkline
            sparklineSpan.sparkline(data, {
                type: 'line',
                width: '100px',
                height: '30px',
                lineColor: status === 'online' ? 'green' : 'gray',
                fillColor: 'transparent',
                spotColor: false,
                minSpotColor: false,
                maxSpotColor: false,
                highlightSpotColor: 'blue',
                highlightLineColor: 'blue'
            });
        } else {
            // Инициализируем Sparkline, если он еще не инициализирован
            sparklineSpan.sparkline(data, {
                type: 'line',
                width: '100px',
                height: '30px',
                lineColor: status === 'online' ? 'green' : 'gray',
                fillColor: 'transparent',
                spotColor: false,
                minSpotColor: false,
                maxSpotColor: false,
                highlightSpotColor: 'blue',
                highlightLineColor: 'blue'
            });
            sparklineSpan.data('sparkline-initialized', true);
        }
    }
}

function fetchDeviceStatuses() {
    $.ajax({
        url: '/get_device_status',
        type: 'GET',
        success: function(response) {
            if (response.status === 'success') {
                const devices = response.devices;
                const activity = response.activity;

                for (const [name, status] of Object.entries(devices)) {
                    // Обновляем кружочек статуса
                    const statusCircle = $(`#${name}-status`);
                    const statusText = $(`#${name}-status-text`);
                    statusCircle.removeClass('online offline no_internet');
                    if (status === 'online') {
                        statusCircle.addClass('online');
                        statusText.text('Онлайн');
                    } else if (status === 'no_internet') {
                        statusCircle.addClass('no_internet');
                        statusText.text('Нет интернета');
                    } else {
                        statusCircle.addClass('offline');
                        statusText.text('Оффлайн');
                    }
                }

                // Обновляем Sparkline
                updateSparklines(devices, activity);
            }
        },
        error: function(error) {
            console.error('Ошибка при получении статусов устройств:', error);
        }
    });
}






function highlightDuplicates(duplicates) {
    // Очищаем предыдущие выделения
    $('#tableBody td').removeClass('duplicate-highlight');

    // Подсвечиваем дубликаты номеров
    for (let number in duplicates.numbers) {
        duplicates.numbers[number].forEach(index => {
            $(`#tableBody tr:eq(${index}) td:nth-child(3)`).addClass('duplicate-highlight');
        });
    }

    // Подсвечиваем дубликаты серийных номеров
    for (let serial in duplicates.serials) {
        duplicates.serials[serial].forEach(index => {
            $(`#tableBody tr:eq(${index}) td:nth-child(4)`).addClass('duplicate-highlight');
        });
    }

    // Подсвечиваем дубликаты "Графа" (dl_number)
    for (let dl_number in duplicates.dl_numbers) {
        duplicates.dl_numbers[dl_number].forEach(index => {
            $(`#tableBody tr:eq(${index}) td:nth-child(5)`).addClass('duplicate-highlight');
        });
    }
}

function updateCell(cell, newValue, rowId, cellIndex, rowData) {
    console.log(`Updating cell: index=${cellIndex}, value=${newValue}, rowId=${rowId}`);

    const excludedArmaTypes = ["CFA", "VND", "SRC"];

    if (cellIndex === 4) { // Столбец "Графа"
        if (rowData.arma_type === 'RPA' && !excludedArmaTypes.includes(rowData.arma_type)) {
            if (newValue && newValue.startsWith('DL')) {
                cell.text(newValue)
                    .addClass('clickable')
                    .css('cursor', 'pointer')
                    .off('click') // Удаляем предыдущие обработчики
                    .on('click', function() {
                        copyToClipboard(newValue);
                        $(this).addClass('copied');
                        setTimeout(() => {
                            $(this).removeClass('copied');
                        }, 200);
                    });

                // Обновляем data-value
                let numericValue = parseDL(newValue) || 0;
                cell.attr('data-value', numericValue);
            } else {
                cell.html('<button class="generate-button">Генерировать</button>')
                    .find('button')
                    .click(function() {
                        generateDL(rowId);
                    });

                // Обновляем data-value
                cell.attr('data-value', 0);
            }
        } else if (!excludedArmaTypes.includes(rowData.arma_type)) {
            if (newValue && newValue.startsWith('DL')) {
                cell.text(newValue)
                    .addClass('clickable')
                    .css('cursor', 'pointer')
                    .off('click')
                    .on('click', function() {
                        copyToClipboard(newValue);
                        $(this).addClass('copied');
                        setTimeout(() => {
                            $(this).removeClass('copied');
                        }, 200);
                    });

                // Обновляем data-value
                let numericValue = parseDL(newValue) || 0;
                cell.attr('data-value', numericValue);
            } else {
                cell.text(newValue || '');
                // Обновляем data-value
                let numericValue = parseDL(newValue) || 0;
                cell.attr('data-value', numericValue);
            }
        } else {
            cell.text(newValue || '');
            // Обновляем data-value
            let numericValue = parseDL(newValue) || 0;
            cell.attr('data-value', numericValue);
        }
    } else if (cellIndex === 6) { // Столбец "Время упаковки"
        const dlCell = cell.parent().find('td').eq(4);
        const dlValue = dlCell.text().trim();
        const armaType = rowData.arma_type;

        if (dlValue.startsWith('DL') && !newValue && !excludedArmaTypes.includes(armaType)) {
            cell.html('<button class="pack-button">Упаковать</button>')
                .find('button')
                .click(function() {
                    packItem(rowId);
                });
        } else {
            cell.text(newValue);
        }
    } else if (cellIndex === 7) { // Столбец "Тип АРМА"
        if (!newValue || newValue.trim() === '') {
            newValue = 'RPA';
        }
        cell.text(newValue)
            .toggleClass('editable', true)
            .attr('data-column', cellIndex);
    } else {
        cell.text(newValue)
            .toggleClass('editable', cellIndex === 2 || cellIndex === 3)
            .attr('data-column', cellIndex);
    }
}

function sortTable(column, order) {
    const rows = $('#tableBody > tr').get();

    rows.sort(function(a, b) {
        let A = $(a).children('td').eq(column).text().trim();
        let B = $(b).children('td').eq(column).text().trim();

        // Обработка пустых значений
        if (A === '' && B === '') return 0;
        if (A === '') return order === 'asc' ? 1 : -1;
        if (B === '') return order === 'asc' ? -1 : 1;

        // Специальная обработка для столбца "Графа" (dl_number) с использованием data-value
        if (column === 4) { // Индекс столбца "Графа"
            let numA = parseInt($(a).children('td').eq(column).attr('data-value')) || 0;
            let numB = parseInt($(b).children('td').eq(column).attr('data-value')) || 0;

            // Отладочные сообщения
            console.log(`Сортировка Графа: numA = ${numA}; numB = ${numB}`);

            return order === 'asc' ? numA - numB : numB - numA;
        }

        // Обработка дат и времени для соответствующих столбцов
        if (column === 1 || column === 6) {  // Столбцы "Время отправки" и "Время упаковки"
            let dateA = Date.parse(A);
            let dateB = Date.parse(B);
            if (isNaN(dateA)) dateA = 0;
            if (isNaN(dateB)) dateB = 0;
            return order === 'asc' ? dateA - dateB : dateB - dateA;
        }

        // Обработка числовых столбцов
        if (column === 0 || column === 2) {  // Столбцы с числами (№ и Номер)
            let numA = parseFloat(A) || 0;
            let numB = parseFloat(B) || 0;
            return order === 'asc' ? numA - numB : numB - numA;
        }

        // Обработка строковых столбцов
        if (column === 5) {  // Столбец с именем отправителя
            A = A.toLowerCase();
            B = B.toLowerCase();
        }

        // Строковое сравнение для остальных столбцов
        A = A.toUpperCase();
        B = B.toUpperCase();
        if (A < B) return order === 'asc' ? -1 : 1;
        if (A > B) return order === 'asc' ? 1 : -1;
        return 0;
    });

    // Очистка тела таблицы
    $('#tableBody').empty();

    // Добавление отсортированных строк
    $.each(rows, function(index, row) {
        $('#tableBody').append(row);
    });

    checkDuplicates();
    bindEventHandlers();
}

function parseDL(dl_number) {
    if (typeof dl_number !== 'string') return null;
    dl_number = dl_number.trim();
    let match = dl_number.match(/^DL[-\s]?(\d+)$/i);
    if (match && match[1]) {
        return parseInt(match[1], 10);
    }
    return null;
}

function generateDL(rowId) {
    console.log(`Generating DL for row ID ${rowId}`);
    const selectedDate = getSelectedDate();
    console.log("Selected date:", selectedDate);

    $.ajax({
        url: '/generate_dl',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            id: rowId,
            date: selectedDate
        }),
        success: function(response) {
            if (response.status === 'success') {
                console.log('DL успешно сгенерирован:', response.dl_number);
                var row = $(`#tableBody tr[data-id='${rowId}']`);
                var dlCell = row.find('td:eq(4)');
                var packCell = row.find('td:eq(6)'); // Столбец "Время упаковки"
                var armaType = row.find('td:eq(7)').text().trim();

                dlCell.text(response.dl_number)
                    .addClass('clickable')
                    .css('cursor', 'pointer')
                    .off('click') // Удаляем предыдущие обработчики
                    .on('click', function() {
                        copyToClipboard(response.dl_number);
                        $(this).addClass('copied');
                        setTimeout(() => {
                            $(this).removeClass('copied');
                        }, 200);
                    });

                // Добавляем кнопку упаковки только если arma_type не исключен
                const excludedArmaTypes = ["CFA", "VND", "SRC"];
                if (!excludedArmaTypes.includes(armaType)) {
                    packCell.html('<button class="pack-button">Упаковать</button>')
                        .find('button')
                        .click(function() {
                            packItem(rowId);
                        });
                }

                // Обновляем поле initial-dl с текущим значением DL
                loadCurrentDL();
            } else {
                alert('Ошибка при генерации DL: ' + response.message);
            }
        },
        error: function(xhr, status, error) {
            console.error('Ошибка при генерации DL:', status, error);
            alert('Ошибка при генерации DL: ' + error);
        }
    });
}

function packItem(rowId) {
    console.log(`Упаковка элемента для строки ID ${rowId}`);
    const selectedDate = getSelectedDate();
    console.log("Selected date:", selectedDate);

    $.ajax({
        url: '/pack_item',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            id: rowId,
            date: selectedDate
        }),
        success: function(response) {
            console.log("Ответ сервера:", response);
            if (response.status === 'success') {
                var row = $(`#tableBody tr[data-id='${rowId}']`);
                row.addClass('packed-row');
                var cell = row.find('td:eq(6)'); // Столбец "Время упаковки"
                cell.text(response.pack_time);
                updateStatistics();

                // Удаляем кнопку "Упаковать", так как запись уже упакована
                cell.find('button.pack-button').remove();
            } else {
                alert('Ошибка при упаковке: ' + response.message);
            }
        },
        error: function(xhr, status, error) {
            console.error("Ошибка AJAX:", xhr, status, error);
            alert('Ошибка при упаковке: ' + error);
        }
    });
}

function areSimilarNumbers(num1, num2) {
    // Очищаем строки от нецифровых символов и пробелов
    const clean1 = num1.toString().replace(/\D/g, '').trim();
    const clean2 = num2.toString().replace(/\D/g, '').trim();
    
    // Если строки пустые или разной длины - не дубликаты
    if (!clean1 || !clean2 || clean1.length !== clean2.length) {
        return false;
    }
    
    // Проверяем на точное совпадение
    return clean1 === clean2;
}

function checkDuplicates() {
    console.log("Checking for duplicates...");
    const rows = $('#tableBody tr');
    
    // Очищаем предыдущие выделения
    rows.find('td').removeClass('duplicate-highlight');
    
    // Создаем массивы для хранения номеров и их индексов
    const numbers = new Map();
    const dl_numbers = new Map();
    const serials = new Map();
    
    // Собираем все номера и серийные номера
    rows.each(function(index) {
        const number = $(this).find('td:nth-child(3)').text().trim();
        const serial = $(this).find('td:nth-child(4)').text().trim();
        const dl_number = $(this).find('td:nth-child(5)').text().trim();
        
        if (number) {
            if (!numbers.has(number)) {
                numbers.set(number, []);
            }
            numbers.get(number).push(index);
        }

        if (dl_number) {
            if (!dl_numbers.has(dl_number)) {
                dl_numbers.set(dl_number, []);
            }
            dl_numbers.get(dl_number).push(index);
        }
        
        if (serial) {
            if (!serials.has(serial)) {
                serials.set(serial, []);
            }
            serials.get(serial).push(index);
        }
    });
    
    // Подсвечиваем дубликаты
    let duplicatesFound = false;
    


    dl_numbers.forEach((indices, dl_number) => {
        if (dl_number.startsWith("DL")) {
            if (indices.length > 1) {
                indices.forEach(index => {
                    rows.eq(index).find('td:nth-child(5)').addClass('duplicate-highlight');
                });
                duplicatesFound = true;
            }
        }
    });

    // Проверяем номера
    numbers.forEach((indices, number) => {
        if (indices.length > 1) {
            indices.forEach(index => {
                rows.eq(index).find('td:nth-child(3)').addClass('duplicate-highlight');
            });
            duplicatesFound = true;
        }
    });

    // // Проверяем грайвера
    // dl_numbers.forEach((indices, dl_number) => {
    //     if (indices.length > 1) {
    //         indices.forEach(index => {
    //             rows.eq(index).find('td:nth-child(5)').addClass('duplicate-highlight');
    //         });
    //         duplicatesFound = true;
    //     }
    // });
    
    // Проверяем серийные номера
    serials.forEach((indices, serial) => {
        if (indices.length > 1) {
            indices.forEach(index => {
                rows.eq(index).find('td:nth-child(4)').addClass('duplicate-highlight');
            });
            duplicatesFound = true;
        }
    });

    return duplicatesFound;
}

function appendNewRow(tableBody, rowData) {
    console.log("Добавление новой строки:", rowData);

    // Создаем элемент строки и присваиваем уникальный data-id
    var tr = $('<tr>').attr('data-id', rowData.id);

    // Если есть время упаковки и это не заголовок, добавляем класс 'packed-row'
    if (rowData.pack_time && rowData.pack_time !== "Время упаковки") {
        tr.addClass('packed-row');
    }

    // Добавляем ячейки в строку
    tr.append($('<td>').text(rowData.row_number));
    tr.append($('<td>').text(rowData.timestamp));

    // Столбец "Номер" (Третий столбец, индекс 2)
    var numberCell = $('<td>')
        .text(rowData.number)
        .addClass('editable') // Добавляем класс для редактирования
        .attr('data-column', '2'); // Указываем индекс столбца
    tr.append(numberCell);

    tr.append($('<td>').text(rowData.serial));

    // Столбец "Графа" (Пятый столбец, индекс 4)
    var dlCell = $('<td>')
        .text(rowData.dl_number || '')
        .addClass('editable') // Добавляем класс для редактирования
        .attr('data-column', '4'); // Указываем индекс столбца "Графа"
    tr.append(dlCell);
    
    // Добавляем data-value
    var numericValue = parseDL(rowData.dl_number) || 0;
    dlCell.attr('data-value', numericValue);

    // Проверка и добавление кнопок или кликабельного текста для "Графа"
    const excludedArmaTypes = ["CFA", "VND", "SRC"];

    if (rowData.arma_type === 'RPA' && !excludedArmaTypes.includes(rowData.arma_type)) {
        // Для типа АРМА 'RPA', проверяем наличие и формат dl_number
        if (!rowData.dl_number || !rowData.dl_number.startsWith('DL')) {
            // Если dl_number отсутствует или не начинается с 'DL', отображаем кнопку "Генерировать"
            dlCell.html('<button class="generate-button">Генерировать</button>')
                .find('button')
                .click(function() {
                    generateDL(rowData.id); // Передаем уникальный ID строки
                });
        } else {
            // Если dl_number присутствует и начинается с 'DL', делаем его кликабельным для копирования
            dlCell.text(rowData.dl_number)
                .addClass('clickable')
                .css('cursor', 'pointer')
                .on('click', function() {
                    copyToClipboard(rowData.dl_number);
                    $(this).addClass('copied');
                    setTimeout(() => {
                        $(this).removeClass('copied');
                    }, 200);
                });
        }
    } else if (!excludedArmaTypes.includes(rowData.arma_type)) {
        // Для других типов АРМА, которые не исключены, отображаем или скрываем кнопку
        if (rowData.dl_number && rowData.dl_number.startsWith('DL')) {
            dlCell.text(rowData.dl_number)
                .addClass('clickable')
                .css('cursor', 'pointer')
                .on('click', function() {
                    copyToClipboard(rowData.dl_number);
                    $(this).addClass('copied');
                    setTimeout(() => {
                        $(this).removeClass('copied');
                    }, 200);
                });
        } else {
            dlCell.text(rowData.dl_number || '');
        }
    } else {
        // Для типов АРМА "CFA", "VND", "SRC" оставляем ячейку пустой или с текущим значением
        dlCell.text(rowData.dl_number || '');
    }

    // Добавляем ячейку с именем отправителя
    tr.append($('<td>').text(rowData.worker_name));

    /**
     * Обработка ячейки "Время упаковки" (pack_time)
     */
    var packCell = $('<td>');

    if (rowData.dl_number && rowData.dl_number.startsWith('DL') && !rowData.pack_time && !excludedArmaTypes.includes(rowData.arma_type)) {
        // Если dl_number с 'DL', pack_time отсутствует и arma_type не исключен, показываем кнопку "Упаковать"
        packCell.html('<button class="pack-button">Упаковать</button>')
            .find('button')
            .click(function() {
                packItem(rowData.id); // Передаем уникальный ID строки
            });
    } else {
        // Иначе отображаем время упаковки или оставляем пустым
        packCell.text(rowData.pack_time || '');
    }

    tr.append(packCell);

    // Добавляем ячейку с типом АРМА
    tr.append($('<td>').text(rowData.arma_type || ''));

    

    /**
     * Добавление ячейки "Действие" с кнопкой "Удалить"
     */
    var actionTd = $('<td>');
    var deleteButton = $('<button>').text('Удалить').addClass('delete-button btn btn-danger btn-sm');
    deleteButton.click(function() {
        initiateDeleteConfirmation(rowData.id); // Используем новую функцию
    });
    actionTd.append(deleteButton);
    tr.append(actionTd);

    // Добавляем строку в тело таблицы
    tableBody.append(tr);

    /**
     * Дополнительная обработка после добавления строки
     */
    setTimeout(() => {
        const dlValue = dlCell.text().trim();
        const packValue = packCell.text().trim();

        if (dlValue.startsWith('DL') && !packValue && !excludedArmaTypes.includes(rowData.arma_type)) {
            console.log('Добавляем кнопку упаковки для DL:', dlValue);
            packCell.html('<button class="pack-button">Упаковать</button>')
                .find('button')
                .click(function() {
                    packItem(rowData.id); // Передаем уникальный ID строки
                });
        }

        // Проверяем дубликаты после добавления новой строки
        checkDuplicates();
    }, 100);
}


function bindEventHandlers() {
    // Привязка обработчика для кнопки "Генерировать"
    $('.generate-button').off('click').on('click', function() {
        var rowId = $(this).closest('tr').data('id');
        generateDL(rowId);
    });

    // Привязка обработчика для кнопки "Упаковать"
    $('.pack-button').off('click').on('click', function() {
        var rowId = $(this).closest('tr').data('id');
        packItem(rowId);
    });

    // Привязка обработчика для кнопки "Удалить"
    $('.delete-button').off('click').on('click', function() {
        var rowId = $(this).closest('tr').data('id');
        initiateDeleteConfirmation(rowId);
    });
}

function updateTableContent(data, tableBody, highlightNew = false) {
    tableBody.empty();  // Очищаем текущее содержимое таблицы
    data.forEach(function(rowData, index) {
        appendNewRow(tableBody, rowData);
        if (highlightNew && index === data.length - 1) {
            // Можно добавить подсветку новой строки, если нужно
        }
    });
    checkDuplicates();
    bindEventHandlers();  // Проверяем дубликаты после обновления таблицы
}

function scheduleNextUpdate() {
    setTimeout(() => {
        if (!isEditing) {
            updateTable(false, false).then(() => {
                scheduleNextUpdate();
            });
        } else {
            scheduleNextUpdate();
        }
    }, 3000);
}

function initializeEventSource() {
    if (eventSource) {
        eventSource.close();
    }

    eventSource = new EventSource('/stream');

    eventSource.onmessage = function(event) {
        const data = JSON.parse(event.data);
        if (data.type === 'update' && data.date === getSelectedDate()) {
            // Обновляем таблицу
            updateTable(true).then(() => {
                // После обновления таблицы, обновляем подсветку дней
                markUnpackedDays();
                fetchDeviceStatuses();
            });
        }
    };

    eventSource.onerror = function(error) {
        console.error('EventSource failed:', error);
        eventSource.close();
        setTimeout(initializeEventSource, 5000);  // Попытка переподключения через 5 секунд
    };
}

// Обработчики событий для таблицы
$(document).ready(function() {
    updateTable();
    updateStatistics(); // Убедитесь, что эта функция определена
    initializeEventSource();
    scheduleNextUpdate();
    fetchDeviceStatuses();
    loadCurrentDL();
    // Обработчик сортировки
    $('.sortable').click(function() {
        const column = $(this).data('column');
        const order = $(this).hasClass('asc') ? 'desc' : 'asc';
        
        // Удаляем классы сортировки со всех заголовков
        $('.sortable').removeClass('asc desc');
        // Добавляем класс текущей сортировки
        $(this).addClass(order);
        
        // Сохраняем текущие параметры сортировки
        globalSortColumn = column;
        globalSortOrder = order;
        
        // Сортируем таблицу
        sortTable(column, order);
    });

    // Обработчик поиска
    $('#searchButton').click(function() {
        searchNumber();
    });
    $('#searchInput').keypress(function(e) {
        if (e.which === 13) {
            searchNumber();
        }
    });
    $('#armaFilter').on('change', function() {
        updateTable();
    });
});

// Обработчик изменения даты
$('#datepicker').on('change', function() {
    initializeEventSource();
    updateTable();
});

// Обработчик экспорта в Excel
$(document).ready(function() {
    $('.export-button').on('click', function(e) {
        e.preventDefault();
        
        // Получаем информацию о сортировке
        const sortableColumn = $('.sortable.asc, .sortable.desc');
        const sortColumn = sortableColumn.length ? sortableColumn.data('column') : '';
        const sortOrder = $('.sortable.asc').length ? 'asc' : 'desc';
        
        // Формируем URL
        const date = getSelectedDate();
        const queryParams = new URLSearchParams({
            date: date,
            sort_column: sortColumn || '',
            sort_order: sortOrder
        });
        
        // Создаем и отправляем запрос
        fetch(`/export_excel?${queryParams.toString()}`)
        .then(response => {
            if (response.ok) {
                return response.blob();
            }
            throw new Error('Network response was not ok.');
        })
        .then(blob => {
            // Создаем ссылку для скачивания
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `export_${date}.xlsx`;
            document.body.appendChild(a);
            a.click();
            window.URL.revokeObjectURL(url);
            a.remove();
        })
        .catch(error => {
            console.error('Error:', error);
            alert('Ошибка при экспорте файла');
        });
    });
});

$(document).ready(function() {
    fpInstance = flatpickr("#datepicker", {
        locale: "ru",
        dateFormat: "Y-m-d",
        defaultDate: "today",
        onChange: function(selectedDates, dateStr, instance) {
            updateTable();
            markUnpackedDays(); // Подсвечиваем дни при изменении даты
        },
        onMonthChange: function(selectedDates, dateStr, instance) {
            markUnpackedDays(); // Подсвечиваем дни при смене месяца
        },
        onDayCreate: function(dObj, dStr, fp, dayElem) {
            const day = dayElem.dateObj.getDate();
            if (currentUnpackedDays.has(day)) {
                dayElem.style.backgroundColor = 'lightcoral';
                dayElem.style.color = 'white';
            } else {
                // Сброс стилей для других дней
                dayElem.style.backgroundColor = '';
                dayElem.style.color = '';
            }
        }
    });

    markUnpackedDays(); // Первоначальная подсветка
    initializeEventSource();
    updateTable();
    updateStatistics();
    fetchDeviceStatuses();
    setInterval(fetchDeviceStatuses, 1000); // Интервал 20 секунд
});


// Обработчик двойного клика для редактирования ячеек
$(document).on('dblclick', '.editable', function() {
    if (isEditing) return; // Предотвращаем многократное редактирование
    isEditing = true;

    var td = $(this);
    var currentValue = td.text();
    var input = $('<input type="text">')
        .val(currentValue)
        .addClass('edit-input');

    td.html(input);
    input.focus();

    input.on('blur', function() {
        var newValue = $(this).val().trim();
        var rowId = td.closest('tr').data('id');
        var columnIndex = td.attr('data-column');

        // Определяем URL для обновления в зависимости от столбца
        let url;
        let updateData = {
            id: rowId,
            new_value: newValue,
            date: getSelectedDate()
        };

        if (columnIndex === '2') { // Столбец "Номер"
            url = '/update_number';
        } else if (columnIndex === '4') { // Столбец "Графа"
            url = '/update_graf';
        } else {
            alert('Неподдерживаемый столбец для редактирования');
            td.text(currentValue);
            isEditing = false;
            return;
        }

        $.ajax({
            url: url,
            type: 'POST',
            contentType: 'application/json',
            data: JSON.stringify(updateData),
            success: function(response) {
                if (response.status === 'success') {
                    td.text(newValue);
                    checkDuplicates();
                } else {
                    alert('Ошибка при обновлении значения: ' + response.message);
                    td.text(currentValue);
                }
                isEditing = false;
            },
            error: function(xhr, status, error) {
                alert('Ошибка при отправке данных: ' + error);
                td.text(currentValue);
                isEditing = false;
            }
        });
    });

    input.on('keypress', function(e) {
        if (e.which === 13) { // Нажатие Enter
            $(this).blur();
        }
    });

    input.on('keydown', function(e) {
        if (e.key === 'Escape') { // Нажатие Esc
            td.text(currentValue);
            isEditing = false;
        }
    });
});

function searchNumber() {
    const searchValue = $('#searchInput').val().trim();
    if (!searchValue) return;

    // Удаляем предыдущую подсветку
    $('.highlight-search').removeClass('highlight-search');

    const rows = $('#tableBody tr');
    let found = false;

    rows.each(function() {
        const numberCell = $(this).find('td:nth-child(3)');
        const cellText = numberCell.text().trim();
        if (cellText === searchValue) {
            numberCell.addClass('highlight-search');
            
            // Прокрутка к найденной строке
            $('.table-container').animate({
                scrollTop: $(this).offset().top - $('.table-container').offset().top + $('.table-container').scrollTop() - 100
            }, 500);

            found = true;

            // Устанавливаем таймер на удаление подсветки через 3 секунды
            setTimeout(() => {
                numberCell.removeClass('highlight-search');
            }, 3000);

            // Выводим сообщение в консоль для отладки
            console.log('Найдено совпадение:', cellText);

            return false; // Прерываем цикл, так как нашли нужную строку
        }
    });

    if (!found) {
        alert('Точное совпадение номера не найдено');
    }
}

function initiateDeleteConfirmation(rowId) {
    isDeleting = true; // Устанавливаем флаг подтверждения удаления
    var deleteCell = $(`tr[data-id='${rowId}'] td:last-child`);

    // Проверяем, не находится ли уже в состоянии подтверждения
    if (deleteCell.data('confirming')) {
        return; // Если подтверждение уже запрошено, ничего не делаем
    }

    // Устанавливаем флаг подтверждения
    deleteCell.data('confirming', true);

    // Создаем контейнер для кнопок "Да" и "Нет"
    var buttonsContainer = $('<div>').addClass('confirm-buttons');

    var yesButton = $('<button>')
        .text('Да')
        .addClass('confirm-yes-button btn btn-success btn-sm me-2')
        .click(function() {
            deleteConfirmed(rowId);
        });

    var noButton = $('<button>')
        .text('Нет')
        .addClass('confirm-no-button btn btn-secondary btn-sm')
        .click(function() {
            cancelDeleteConfirmation(rowId);
        });

    buttonsContainer.append(yesButton);
    buttonsContainer.append(noButton);

    // Заменяем содержимое ячейки на контейнер с кнопками
    deleteCell.empty();
    deleteCell.append(buttonsContainer);
}

function deleteConfirmed(rowId) {
    $.ajax({
        url: '/delete_row',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({ id: rowId }),
        success: function(response) {
            if (response.status === 'success') {
                // Удаляем строку из таблицы
                $(`tr[data-id='${rowId}']`).remove();
            } else {
                console.error('Ошибка при удалении записи:', response.message);
                // Можно добавить уведомление пользователю о неудаче
            }
            // Восстанавливаем кнопку "Удалить" и сбрасываем флаг
            cancelDeleteConfirmation(rowId);
        },
        error: function(xhr, status, error) {
            console.error('Произошла ошибка при удалении записи:', error);
            // Можно добавить уведомление пользователю о неудаче
            // Восстанавливаем кнопку "Удалить" и сбрасываем флаг
            cancelDeleteConfirmation(rowId);
        }
    });
}

function cancelDeleteConfirmation(rowId) {
    var deleteCell = $(`tr[data-id='${rowId}'] td:last-child`);
    // Сбрасываем флаг подтверждения
    deleteCell.data('confirming', false);
    // Восстанавливаем кнопку "Удалить"
    deleteCell.empty();
    var deleteButton = $('<button>')
        .text('Удалить')
        .addClass('delete-button btn btn-danger btn-sm')
        .click(function() {
            initiateDeleteConfirmation(rowId);
        });
    deleteCell.append(deleteButton);

    isDeleting = false; // Сбрасываем глобальный флаг
}

function loadCurrentDL() {
    const selectedDate = getSelectedDate();
    $.ajax({
        url: '/get_current_dl',
        type: 'GET',
        data: { date: selectedDate },
        success: function(response) {
            if (response.status === 'success') {
                $('#initial-dl').val(response.current_dl);
            } else {
                $('#initial-dl').val(''); // Можно установить значение по умолчанию или показать сообщение
                console.warn(response.message);
            }
        },
        error: function(xhr, status, error) {
            console.error('Ошибка при получении текущего DL:', error);
            $('#initial-dl').val('');
        }
    });
}

function markUnpackedDays() {
    const selectedDate = getSelectedDate(); // "YYYY-MM-DD"
    if (!selectedDate) {
        console.warn('Дата не выбрана.');
        return;
    }

    const [year, month, day] = selectedDate.split('-');

    if (!year || !month) {
        console.warn('Год или месяц не выбраны.');
        return;
    }

    // Запрашиваем неупакованные дни для выбранного месяца и года
    fetch(`/get_unpacked_days?year=${year}&month=${month}`)
        .then(response => response.json())
        .then(data => {
            if (data.status === 'success') {
                currentUnpackedDays = new Set(data.unpacked_days);
                fpInstance.redraw(); // Перерисовываем календарь, чтобы применить новые стили
            } else {
                console.error('Ошибка при получении неупакованных дней:', data.message);
            }
        })
        .catch(error => {
            console.error('Ошибка при запросе неупакованных дней:', error);
        });
}