// script.js

// Инициализация Quill редактора внутри модального окна
const quill = new Quill('#editor-container', {
    theme: 'snow'
});

// Элементы интерфейса
const editorWrapper = document.getElementById('editor-container-wrapper');
const saveButton = document.getElementById('save-btn');
const closeEditorBtn = document.getElementById('close-editor-btn');
const overlay = document.getElementById('overlay');
const saveAllBtn = document.getElementById('save-all');
const exportCsvBtn = document.getElementById('export-csv');
const refreshAllBtn = document.getElementById('refresh-all-btn');
const exportFeedsBtn = document.getElementById('export-feeds');
const importFeedsBtn = document.getElementById('import-feeds');
const importForm = document.getElementById('import-form');

const searchInput = document.getElementById('search-input');
const feedFilter = document.getElementById('feed-filter');
const categoryFilter = document.getElementById('category-filter');

let currentEditingItem = null;

// Пагинация
const ITEMS_PER_PAGE = 5;
let currentPage = 1;
let totalPages = 1;

// Хранилище для RSS-лент и новостей
let feeds = [];

// Функция для отображения уведомлений
function showNotification(type, message) {
    const loadingIndicator = document.getElementById('loading');
    const errorMsg = document.getElementById('error');
    const successMsg = document.getElementById('success');

    // Скрыть все уведомления
    loadingIndicator.classList.add('hidden');
    errorMsg.classList.add('hidden');
    successMsg.classList.add('hidden');

    if (type === 'loading') {
        loadingIndicator.textContent = message;
        loadingIndicator.classList.remove('hidden');
    } else if (type === 'error') {
        errorMsg.textContent = message;
        errorMsg.classList.remove('hidden');
        setTimeout(() => errorMsg.classList.add('hidden'), 5000);
    } else if (type === 'success') {
        successMsg.textContent = message;
        successMsg.classList.remove('hidden');
        setTimeout(() => successMsg.classList.add('hidden'), 5000);
    }
}

// Функция для включения темного режима
function initializeTheme() {
    const themeCheckbox = document.getElementById('theme-checkbox');
    const savedTheme = localStorage.getItem('theme') || 'light';

    if (savedTheme === 'dark') {
        document.body.classList.add('dark-mode');
        themeCheckbox.checked = true;
    }

    themeCheckbox.addEventListener('change', () => {
        if (themeCheckbox.checked) {
            document.body.classList.add('dark-mode');
            localStorage.setItem('theme', 'dark');
        } else {
            document.body.classList.remove('dark-mode');
            localStorage.setItem('theme', 'light');
        }
    });
}

// Функция для включения режима редактирования
function enableEditing(content, feedItem) {
    editorWrapper.classList.remove('hidden');
    overlay.classList.remove('hidden');
    currentEditingItem = feedItem;

    quill.root.innerHTML = content;

    // Включение Bootstrap модального окна
    const editorModal = new bootstrap.Modal(editorWrapper);
    editorModal.show();
}

// Функция для закрытия редактора
function closeEditor() {
    const editorModal = bootstrap.Modal.getInstance(editorWrapper);
    editorModal.hide();
    currentEditingItem = null;
}

// Обработчик кнопки закрытия редактора
closeEditorBtn.addEventListener('click', closeEditor);

// Сохранение изменений в новости
saveButton.addEventListener('click', () => {
    if (currentEditingItem) {
        const updatedContent = DOMPurify.sanitize(quill.root.innerHTML);
        const descriptionElement = currentEditingItem.querySelector('.news-content p');

        if (descriptionElement) {
            descriptionElement.innerHTML = updatedContent;
            updateFeedData(currentEditingItem, updatedContent);
            showNotification('success', 'Изменения сохранены успешно!');
        } else {
            console.warn('Элемент для обновления не найден');
            showNotification('error', 'Не удалось сохранить изменения.');
        }

        closeEditor();
    } else {
        console.warn('Нет текущего редактируемого элемента');
        showNotification('error', 'Произошла ошибка при сохранении изменений.');
    }
});

// Функция для обновления данных в хранилище
function updateFeedData(feedItem, updatedContent) {
    const title = feedItem.querySelector('h2 a').textContent;
    const source = feedItem.querySelector('.source').textContent.replace('Источник: ', '');
    const category = feedItem.getAttribute('data-category');

    for (let feed of feeds) {
        if (feed.url.includes(source)) {
            const newsItem = feed.news.find(news => news.title === title);
            if (newsItem) {
                newsItem.description = updatedContent;
                break;
            }
        }
    }

    saveToLocalStorage();
}

// Функция для загрузки RSS ленты
async function fetchRSS(url) {
    try {
        showNotification('loading', `Загрузка RSS-ленты: ${url}`);
        const proxyUrl = 'https://api.allorigins.win/get?url='; // Прокси для обхода CORS
        const response = await fetch(proxyUrl + encodeURIComponent(url));
        if (!response.ok) {
            throw new Error(`Ошибка загрузки RSS: ${response.statusText}`);
        }

        const data = await response.json();
        const rssText = data.contents;
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(rssText, "application/xml");

        const parseError = xmlDoc.querySelector("parsererror");
        if (parseError) {
            throw new Error("Ошибка парсинга XML.");
        }

        const items = xmlDoc.querySelectorAll("item");
        const parsedItems = Array.from(items).map(item => {
            // Попытка извлечения изображения из различных источников
            let image = '';
            const mediaContent = item.querySelector('media\\:content, content');
            if (mediaContent && mediaContent.getAttribute('url')) {
                image = mediaContent.getAttribute('url');
            } else {
                // Попытка извлечения изображения из описания через регулярное выражение
                const desc = item.querySelector("description")?.textContent || "";
                const imgMatch = desc.match(/<img[^>]+src="([^">]+)"/);
                if (imgMatch && imgMatch[1]) {
                    image = imgMatch[1];
                }
            }

            return {
                title: item.querySelector("title")?.textContent || "Без названия",
                                                  link: item.querySelector("link")?.textContent || "Без ссылки",
                                                  description: item.querySelector("description")?.textContent || "Без описания",
                                                  pubDate: item.querySelector("pubDate")?.textContent || "Без даты",
                                                  image: image
            };
        });

        showNotification('success', `RSS-лента загружена успешно: ${url}`);
        return parsedItems;
    } catch (error) {
        console.error(error);
        showNotification('error', error.message);
        return [];
    }
}

// Функция для отображения RSS фидов с пагинацией
function displayFeed(data) {
    const feedContainer = document.getElementById("feed");
    feedContainer.innerHTML = ''; // Очистить предыдущие новости

    if (data.length === 0) {
        feedContainer.innerHTML = '<p>Нет новостей для отображения.</p>';
        document.getElementById('pagination').classList.add('hidden');
        return;
    }

    // Расчет пагинации
    totalPages = Math.ceil(data.length / ITEMS_PER_PAGE);
    if (totalPages > 1) {
        document.getElementById('pagination').classList.remove('hidden');
    } else {
        document.getElementById('pagination').classList.add('hidden');
    }

    // Отображение текущей страницы
    const start = (currentPage - 1) * ITEMS_PER_PAGE;
    const end = start + ITEMS_PER_PAGE;
    const paginatedData = data.slice(start, end);

    paginatedData.forEach((item, index) => {
        const feedItem = document.createElement('div');
        feedItem.classList.add('col-md-6', 'col-lg-4');
        feedItem.classList.add('news-card');
        feedItem.setAttribute('data-category', item.source);

        // Добавление изображения, если оно есть
        let imageHTML = '';
        if (item.image) {
            imageHTML = `<img src="${item.image}" alt="Изображение" class="img-fluid rounded mb-2">`;
        }

        // Добавление источника новости
        let sourceHTML = '';
        if (item.source) {
            sourceHTML = `<div class="source"><strong>Источник:</strong> ${item.source}</div>`;
        }

        // Добавление описания новости с изображением
        const description = DOMPurify.sanitize(item.description, { ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br', 'ul', 'ol', 'li'] });

        feedItem.innerHTML = `
        <div class="card h-100 bg-dark text-white">
        <div class="card-body">
        <h5 class="card-title"><a href="${item.link}" target="_blank" rel="noopener noreferrer" class="text-white text-decoration-none">${item.title}</a></h5>
        <div class="pubDate"><strong>Дата публикации:</strong> ${new Date(item.pubDate).toLocaleString()}</div>
        <div class="news-content mt-2">
        ${imageHTML}
        <p class="card-text">${description}</p>
        </div>
        ${sourceHTML}
        </div>
        <div class="card-footer bg-transparent border-top-0">
        <button class="btn btn-warning edit-btn">Редактировать</button>
        </div>
        </div>
        `;

        // Кнопка "Редактировать"
        const editButton = feedItem.querySelector('.edit-btn');
        editButton.addEventListener('click', () => enableEditing(item.description, feedItem));

        feedContainer.appendChild(feedItem);
    });

    updatePagination();
}

// Функция для обновления пагинации
function updatePagination() {
    const currentPageSpan = document.getElementById('current-page');
    const prevPageBtn = document.getElementById('prev-page');
    const nextPageBtn = document.getElementById('next-page');

    currentPageSpan.textContent = `${currentPage} из ${totalPages}`;

    // Управление состоянием кнопок
    prevPageBtn.disabled = currentPage === 1;
    nextPageBtn.disabled = currentPage === totalPages;
}

// Обработчики для кнопок пагинации
document.getElementById('prev-page').addEventListener('click', () => {
    if (currentPage > 1) {
        currentPage--;
        displayFeed(getAggregatedNews());
    }
});

document.getElementById('next-page').addEventListener('click', () => {
    if (currentPage < totalPages) {
        currentPage++;
        displayFeed(getAggregatedNews());
    }
});

// Функция для сохранения всех новостей в HTML-документ
function saveAllNewsAsDocument() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для сохранения.');
        return;
    }

    let htmlContent = `
    <!DOCTYPE html>
    <html lang="ru">
    <head>
    <meta charset="UTF-8">
    <title>Сохранённые RSS Новости</title>
    <style>
    body { font-family: Arial, sans-serif; padding: 20px; background-color: #f4f4f4; }
    .feed-item { background-color: white; padding: 20px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); margin-bottom: 20px; }
    .feed-item h2 { margin-top: 0; }
    .pubDate, .source { font-size: 0.9em; color: #555; margin-bottom: 10px; }
    .news-content img { max-width: 200px; border-radius: 4px; object-fit: cover; display: block; margin-bottom: 10px; }
    </style>
    </head>
    <body>
    <h1>Сохранённые RSS Новости</h1>
    `;

    feedItems.forEach(item => {
        htmlContent += `
        <div class="feed-item">
        ${item.innerHTML}
        </div>
        `;
    });

    htmlContent += `
    </body>
    </html>
    `;

    const blob = new Blob([htmlContent], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'saved_news.html';
    a.click();
    URL.revokeObjectURL(url);

    showNotification('success', 'Новости успешно сохранены!');
}

// Функция для экспорта новостей в PDF
async function exportToPDF() {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF();

    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для экспорта.');
        return;
    }

    showNotification('loading', 'Экспорт в PDF...');

    let yOffset = 10;

    for (let item of feedItems) {
        const title = item.querySelector('h2 a').textContent;
        const link = item.querySelector('h2 a').href;
        const pubDate = item.querySelector('.pubDate').textContent;
        const source = item.querySelector('.source') ? item.querySelector('.source').textContent : '';
        const description = item.querySelector('p').innerHTML;

        doc.setFontSize(16);
        doc.text(title, 10, yOffset);
        yOffset += 10;

        doc.setFontSize(12);
        doc.text(`${source}`, 10, yOffset);
        yOffset += 7;
        doc.text(`${pubDate}`, 10, yOffset);
        yOffset += 10;

        if (item.querySelector('img')) {
            const img = item.querySelector('img');
            try {
                const imgData = await getImageDataURL(img.src);
                doc.addImage(`data:image/jpeg;base64,${imgData}`, 'JPEG', 10, yOffset, 50, 30);
                yOffset += 35;
            } catch (error) {
                console.warn('Не удалось загрузить изображение:', img.src);
            }
        }

        const textLines = doc.splitTextToSize(description.replace(/<[^>]+>/g, ''), 180);
        doc.text(textLines, 10, yOffset);
        yOffset += textLines.length * 7;

        // Добавление разделителя
        yOffset += 10;
        if (yOffset > 270) { // Добавить новую страницу, если превышен лимит
            doc.addPage();
            yOffset = 10;
        }
    }

    doc.save('news.pdf');
    showNotification('success', 'Экспорт в PDF завершён успешно!');
}

// Функция для получения данных изображения в формате Base64
async function getImageDataURL(url) {
    const response = await fetch(url);
    const blob = await response.blob();
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result.split(',')[1]);
        reader.onerror = reject;
        reader.readAsDataURL(blob);
    });
}

// Функция для экспорта новостей в CSV
function exportToCSV() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для экспорта.');
        return;
    }

    let csvContent = "data:text/csv;charset=utf-8,";
    csvContent += "Заголовок,Ссылка,Описание,Дата публикации,Источник,Изображение\n";

    feedItems.forEach(item => {
        const title = item.querySelector('h2 a').textContent.replace(/,/g, ' ');
        const link = item.querySelector('h2 a').href;
        const description = item.querySelector('p').innerText.replace(/,/g, ' ').replace(/"/g, '""');
        const pubDate = item.querySelector('.pubDate').textContent;
        const source = item.querySelector('.source') ? item.querySelector('.source').textContent.replace('Источник: ', '') : '';
        const image = item.querySelector('img') ? item.querySelector('img').src : '';

        csvContent += `"${title}","${link}","${description}","${pubDate}","${source}","${image}"\n`;
    });

    const encodedUri = encodeURI(csvContent);
    const a = document.createElement('a');
    a.href = encodedUri;
    a.download = 'news.csv';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);

    showNotification('success', 'Новости успешно экспортированы в CSV!');
}

// Функция для импортирования RSS-лент из JSON-файла
importForm.addEventListener('submit', function(e) {
    e.preventDefault();
    const fileInput = document.getElementById('import-file');
    const file = fileInput.files[0];

    if (!file) {
        showNotification('error', 'Пожалуйста, выберите файл для импорта.');
        return;
    }

    const reader = new FileReader();
    reader.onload = function(event) {
        try {
            const importedFeeds = JSON.parse(event.target.result);
            if (!Array.isArray(importedFeeds)) {
                throw new Error('Неверный формат файла.');
            }

            importedFeeds.forEach(feed => {
                if (feed.url && !feeds.some(f => f.url === feed.url)) {
                    feeds.push({ url: feed.url, category: feed.category || 'Без категории', news: [] });
                    addFeedToList(feed.url, feed.category || 'Без категории');
                }
            });

            saveToLocalStorage();
            displayFeed(getAggregatedNews());
            updateFeedFilter();

            showNotification('success', 'RSS-ленты успешно импортированы!');
            const importModal = bootstrap.Modal.getInstance(document.getElementById('importModal'));
            importModal.hide();
            importForm.reset();
        } catch (error) {
            console.error(error);
            showNotification('error', 'Не удалось импортировать RSS-ленты: ' + error.message);
        }
    };

    reader.readAsText(file);
});

// Функция для добавления RSS-ленты в список с категорией
function addFeedToList(feedUrl, category = 'Без категории') {
    const feedsUl = document.getElementById('feeds-ul');
    const li = document.createElement('li');
    li.textContent = `${feedUrl} [${category}]`;

    const removeBtn = document.createElement('button');
    removeBtn.textContent = 'Удалить';
    removeBtn.classList.add('ms-3');
    removeBtn.addEventListener('click', () => {
        const index = feeds.findIndex(feed => feed.url === feedUrl);
        if (index > -1) {
            feeds.splice(index, 1);
            li.remove();
            saveToLocalStorage();
            displayFeed(getAggregatedNews());
            updateFeedFilter();
        }
    });

    li.appendChild(removeBtn);
    feedsUl.appendChild(li);
}

// Функция для сохранения всех новостей в CSV-документ
function exportToCSV() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для экспорта.');
        return;
    }

    let csvContent = "data:text/csv;charset=utf-8,";
    csvContent += "Заголовок,Ссылка,Описание,Дата публикации,Источник,Изображение\n";

    feedItems.forEach(item => {
        const title = item.querySelector('h2 a').textContent.replace(/,/g, ' ');
        const link = item.querySelector('h2 a').href;
        const description = item.querySelector('p').innerText.replace(/,/g, ' ').replace(/"/g, '""');
        const pubDate = item.querySelector('.pubDate').textContent;
        const source = item.querySelector('.source') ? item.querySelector('.source').textContent.replace('Источник: ', '') : '';
        const image = item.querySelector('img') ? item.querySelector('img').src : '';

        csvContent += `"${title}","${link}","${description}","${pubDate}","${source}","${image}"\n`;
    });

    const encodedUri = encodeURI(csvContent);
    const a = document.createElement('a');
    a.href = encodedUri;
    a.download = 'news.csv';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);

    showNotification('success', 'Новости успешно экспортированы в CSV!');
}

// Добавление обработчика кнопки "Экспортировать новости в CSV"
exportCsvBtn.addEventListener('click', exportToCSV);

// Функция для сохранения всех новостей в HTML-документ
function saveAllNewsAsDocument() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для сохранения.');
        return;
    }

    let htmlContent = `
    <!DOCTYPE html>
    <html lang="ru">
    <head>
    <meta charset="UTF-8">
    <title>Сохранённые RSS Новости</title>
    <style>
    body { font-family: Arial, sans-serif; padding: 20px; background-color: #f4f4f4; }
    .feed-item { background-color: white; padding: 20px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); margin-bottom: 20px; }
    .feed-item h2 { margin-top: 0; }
    .pubDate, .source { font-size: 0.9em; color: #555; margin-bottom: 10px; }
    .news-content img { max-width: 200px; border-radius: 4px; object-fit: cover; display: block; margin-bottom: 10px; }
    </style>
    </head>
    <body>
    <h1>Сохранённые RSS Новости</h1>
    `;

    feedItems.forEach(item => {
        htmlContent += `
        <div class="feed-item">
        ${item.innerHTML}
        </div>
        `;
    });

    htmlContent += `
    </body>
    </html>
    `;

    const blob = new Blob([htmlContent], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'saved_news.html';
    a.click();
    URL.revokeObjectURL(url);

    showNotification('success', 'Новости успешно сохранены!');
}

// Функция для экспорта новостей в PDF
async function exportToPDF() {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF();

    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для экспорта.');
        return;
    }

    showNotification('loading', 'Экспорт в PDF...');

    let yOffset = 10;

    for (let item of feedItems) {
        const title = item.querySelector('h2 a').textContent;
        const link = item.querySelector('h2 a').href;
        const pubDate = item.querySelector('.pubDate').textContent;
        const source = item.querySelector('.source') ? item.querySelector('.source').textContent : '';
        const description = item.querySelector('p').innerHTML;

        doc.setFontSize(16);
        doc.text(title, 10, yOffset);
        yOffset += 10;

        doc.setFontSize(12);
        doc.text(source, 10, yOffset);
        yOffset += 7;
        doc.text(pubDate, 10, yOffset);
        yOffset += 10;

        if (item.querySelector('img')) {
            const img = item.querySelector('img');
            try {
                const imgData = await getImageDataURL(img.src);
                doc.addImage(`data:image/jpeg;base64,${imgData}`, 'JPEG', 10, yOffset, 50, 30);
                yOffset += 35;
            } catch (error) {
                console.warn('Не удалось загрузить изображение:', img.src);
            }
        }

        const text = description.replace(/<[^>]+>/g, ' ');
        const lines = doc.splitTextToSize(text, 180);
        doc.text(lines, 10, yOffset);
        yOffset += lines.length * 7;

        // Добавление разделителя
        yOffset += 10;
        if (yOffset > 270) { // Добавить новую страницу, если превышен лимит
            doc.addPage();
            yOffset = 10;
        }
    }

    doc.save('news.pdf');
    showNotification('success', 'Экспорт в PDF завершён успешно!');
}

// Функция для экспортирования RSS-лент в JSON
function exportFeeds() {
    if (feeds.length === 0) {
        showNotification('error', 'Нет RSS-лент для экспорта.');
        return;
    }

    const dataStr = JSON.stringify(feeds, null, 2);
    const blob = new Blob([dataStr], { type: "application/json" });
    saveAs(blob, "rss_feeds.json");

    showNotification('success', 'RSS-ленты успешно экспортированы!');
}

// Функция для импортирования RSS-лент из JSON-файла
importForm.addEventListener('submit', function(e) {
    e.preventDefault();
    const fileInput = document.getElementById('import-file');
    const file = fileInput.files[0];

    if (!file) {
        showNotification('error', 'Пожалуйста, выберите файл для импорта.');
        return;
    }

    const reader = new FileReader();
    reader.onload = function(event) {
        try {
            const importedFeeds = JSON.parse(event.target.result);
            if (!Array.isArray(importedFeeds)) {
                throw new Error('Неверный формат файла.');
            }

            importedFeeds.forEach(feed => {
                if (feed.url && !feeds.some(f => f.url === feed.url)) {
                    feeds.push({ url: feed.url, category: feed.category || 'Без категории', news: [] });
                    addFeedToList(feed.url, feed.category || 'Без категории');
                }
            });

            saveToLocalStorage();
            displayFeed(getAggregatedNews());
            updateFeedFilter();

            showNotification('success', 'RSS-ленты успешно импортированы!');
            const importModal = bootstrap.Modal.getInstance(document.getElementById('importModal'));
            importModal.hide();
            importForm.reset();
        } catch (error) {
            console.error(error);
            showNotification('error', 'Не удалось импортировать RSS-ленты: ' + error.message);
        }
    };

    reader.readAsText(file);
});

// Функция для обновления фильтра по категориям
function updateCategoryFilter() {
    const categoryFilter = document.getElementById('category-filter');
    categoryFilter.innerHTML = `<option value="all">Все категории</option>`;

    const categories = [...new Set(feeds.map(feed => feed.category || 'Без категории'))];

    categories.forEach(category => {
        const option = document.createElement('option');
        option.value = category;
        option.textContent = category;
        categoryFilter.appendChild(option);
    });
}

// Функция для добавления RSS-ленты в список с категорией
function addFeedToList(feedUrl, category = 'Без категории') {
    const feedsUl = document.getElementById('feeds-ul');
    const li = document.createElement('li');
    li.textContent = `${feedUrl} [${category}]`;

    const removeBtn = document.createElement('button');
    removeBtn.textContent = 'Удалить';
    removeBtn.classList.add('ms-3', 'btn', 'btn-sm', 'btn-danger');
    removeBtn.addEventListener('click', () => {
        const index = feeds.findIndex(feed => feed.url === feedUrl);
        if (index > -1) {
            feeds.splice(index, 1);
            li.remove();
            saveToLocalStorage();
            displayFeed(getAggregatedNews());
            updateFeedFilter();
        }
    });

    li.appendChild(removeBtn);
    feedsUl.appendChild(li);
}

// Функция для агрегирования новостей из всех RSS-лент
function getAggregatedNews() {
    let allNews = [];
    feeds.forEach(feed => {
        if (Array.isArray(feed.news)) {
            allNews = allNews.concat(feed.news.map(newsItem => ({ ...newsItem, source: feed.url, category: feed.category || 'Без категории' })));
        }
    });

    // Сортировка по дате публикации (новые сначала)
    allNews.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate));

    return allNews;
}

// Функция для отображения RSS фидов с пагинацией
function displayFeed(data) {
    const feedContainer = document.getElementById("feed");
    feedContainer.innerHTML = ''; // Очистить предыдущие новости

    if (data.length === 0) {
        feedContainer.innerHTML = '<p>Нет новостей для отображения.</p>';
        document.getElementById('pagination').classList.add('hidden');
        return;
    }

    // Расчет пагинации
    totalPages = Math.ceil(data.length / ITEMS_PER_PAGE);
    if (totalPages > 1) {
        document.getElementById('pagination').classList.remove('hidden');
    } else {
        document.getElementById('pagination').classList.add('hidden');
    }

    // Отображение текущей страницы
    const start = (currentPage - 1) * ITEMS_PER_PAGE;
    const end = start + ITEMS_PER_PAGE;
    const paginatedData = data.slice(start, end);

    paginatedData.forEach((item, index) => {
        const feedItem = document.createElement('div');
        feedItem.classList.add('col-md-6', 'col-lg-4');
        feedItem.classList.add('news-card');
        feedItem.setAttribute('data-category', item.category);

        // Добавление изображения, если оно есть
        let imageHTML = '';
        if (item.image) {
            imageHTML = `<img src="${item.image}" alt="Изображение" class="img-fluid rounded mb-2">`;
        }

        // Добавление источника новости
        let sourceHTML = '';
        if (item.source) {
            const sourceName = new URL(item.source).hostname;
            sourceHTML = `<div class="source"><strong>Источник:</strong> ${sourceName}</div>`;
        }

        // Добавление описания новости с изображением
        const description = DOMPurify.sanitize(item.description, { ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br', 'ul', 'ol', 'li'] });

        feedItem.innerHTML = `
        <div class="card h-100 ${document.body.classList.contains('dark-mode') ? 'bg-dark text-white' : ''}">
        <div class="card-body">
        <h5 class="card-title"><a href="${item.link}" target="_blank" rel="noopener noreferrer" class="${document.body.classList.contains('dark-mode') ? 'text-white' : 'text-dark'} text-decoration-none">${item.title}</a></h5>
        <div class="pubDate"><strong>Дата публикации:</strong> ${new Date(item.pubDate).toLocaleString()}</div>
        <div class="news-content mt-2">
        ${imageHTML}
        <p class="card-text">${description}</p>
        </div>
        ${sourceHTML}
        </div>
        <div class="card-footer bg-transparent border-top-0">
        <button class="btn btn-warning edit-btn">Редактировать</button>
        </div>
        </div>
        `;

        // Кнопка "Редактировать"
        const editButton = feedItem.querySelector('.edit-btn');
        editButton.addEventListener('click', () => enableEditing(item.description, feedItem));

        feedContainer.appendChild(feedItem);
    });

    updatePagination();
}

// Функция для обновления пагинации
function updatePagination() {
    const currentPageSpan = document.getElementById('current-page');
    const prevPageBtn = document.getElementById('prev-page');
    const nextPageBtn = document.getElementById('next-page');

    currentPageSpan.textContent = `${currentPage} из ${totalPages}`;

    // Управление состоянием кнопок
    prevPageBtn.disabled = currentPage === 1;
    nextPageBtn.disabled = currentPage === totalPages;
}

// Обработчики для кнопок пагинации
document.getElementById('prev-page').addEventListener('click', () => {
    if (currentPage > 1) {
        currentPage--;
        displayFeed(getAggregatedNews());
    }
});

document.getElementById('next-page').addEventListener('click', () => {
    if (currentPage < totalPages) {
        currentPage++;
        displayFeed(getAggregatedNews());
    }
});

// Функция для сохранения всех новостей в HTML-документ
function saveAllNewsAsDocument() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для сохранения.');
        return;
    }

    let htmlContent = `
    <!DOCTYPE html>
    <html lang="ru">
    <head>
    <meta charset="UTF-8">
    <title>Сохранённые RSS Новости</title>
    <style>
    body { font-family: Arial, sans-serif; padding: 20px; background-color: #f4f4f4; }
    .feed-item { background-color: white; padding: 20px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); margin-bottom: 20px; }
    .feed-item h2 { margin-top: 0; }
    .pubDate, .source { font-size: 0.9em; color: #555; margin-bottom: 10px; }
    .news-content img { max-width: 200px; border-radius: 4px; object-fit: cover; display: block; margin-bottom: 10px; }
    </style>
    </head>
    <body>
    <h1>Сохранённые RSS Новости</h1>
    `;

    feedItems.forEach(item => {
        htmlContent += `
        <div class="feed-item">
        ${item.innerHTML}
        </div>
        `;
    });

    htmlContent += `
    </body>
    </html>
    `;

    const blob = new Blob([htmlContent], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'saved_news.html';
    a.click();
    URL.revokeObjectURL(url);

    showNotification('success', 'Новости успешно сохранены!');
}

// Функция для экспорта новостей в PDF
async function exportToPDF() {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF();

    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для экспорта.');
        return;
    }

    showNotification('loading', 'Экспорт в PDF...');

    let yOffset = 10;

    for (let item of feedItems) {
        const title = item.querySelector('h2 a').textContent;
        const link = item.querySelector('h2 a').href;
        const pubDate = item.querySelector('.pubDate').textContent;
        const source = item.querySelector('.source') ? item.querySelector('.source').textContent.replace('Источник: ', '') : '';
        const description = item.querySelector('p').innerHTML;

        doc.setFontSize(16);
        doc.text(title, 10, yOffset);
        yOffset += 10;

        doc.setFontSize(12);
        doc.text(`Источник: ${source}`, 10, yOffset);
        yOffset += 7;
        doc.text(`Дата публикации: ${pubDate}`, 10, yOffset);
        yOffset += 10;

        if (item.querySelector('img')) {
            const img = item.querySelector('img');
            try {
                const imgData = await getImageDataURL(img.src);
                doc.addImage(`data:image/jpeg;base64,${imgData}`, 'JPEG', 10, yOffset, 50, 30);
                yOffset += 35;
            } catch (error) {
                console.warn('Не удалось загрузить изображение:', img.src);
            }
        }

        const text = description.replace(/<[^>]+>/g, ' ');
        const lines = doc.splitTextToSize(text, 180);
        doc.text(lines, 10, yOffset);
        yOffset += lines.length * 7;

        // Добавление разделителя
        yOffset += 10;
        if (yOffset > 270) { // Добавить новую страницу, если превышен лимит
            doc.addPage();
            yOffset = 10;
        }
    }

    doc.save('news.pdf');
    showNotification('success', 'Экспорт в PDF завершён успешно!');
}

// Функция для экспортирования RSS-лент в JSON
function exportFeeds() {
    if (feeds.length === 0) {
        showNotification('error', 'Нет RSS-лент для экспорта.');
        return;
    }

    const dataStr = JSON.stringify(feeds, null, 2);
    const blob = new Blob([dataStr], { type: "application/json" });
    saveAs(blob, "rss_feeds.json");

    showNotification('success', 'RSS-ленты успешно экспортированы!');
}

// Функция для импортирования RSS-лент из JSON-файла
importForm.addEventListener('submit', function(e) {
    e.preventDefault();
    const fileInput = document.getElementById('import-file');
    const file = fileInput.files[0];

    if (!file) {
        showNotification('error', 'Пожалуйста, выберите файл для импорта.');
        return;
    }

    const reader = new FileReader();
    reader.onload = function(event) {
        try {
            const importedFeeds = JSON.parse(event.target.result);
            if (!Array.isArray(importedFeeds)) {
                throw new Error('Неверный формат файла.');
            }

            importedFeeds.forEach(feed => {
                if (feed.url && !feeds.some(f => f.url === feed.url)) {
                    feeds.push({ url: feed.url, category: feed.category || 'Без категории', news: [] });
                    addFeedToList(feed.url, feed.category || 'Без категории');
                }
            });

            saveToLocalStorage();
            displayFeed(getAggregatedNews());
            updateFeedFilter();

            showNotification('success', 'RSS-ленты успешно импортированы!');
            const importModal = bootstrap.Modal.getInstance(document.getElementById('importModal'));
            importModal.hide();
            importForm.reset();
        } catch (error) {
            console.error(error);
            showNotification('error', 'Не удалось импортировать RSS-ленты: ' + error.message);
        }
    };

    reader.readAsText(file);
});

// Функция для обновления фильтров
function updateFeedFilter() {
    const feedFilter = document.getElementById('feed-filter');
    const categoryFilter = document.getElementById('category-filter');

    feedFilter.innerHTML = `<option value="all">Все источники</option>`;
    categoryFilter.innerHTML = `<option value="all">Все категории</option>`;

    // Собираем уникальные источники и категории
    const sources = [...new Set(feeds.map(feed => new URL(feed.url).hostname))];
    const categories = [...new Set(feeds.map(feed => feed.category || 'Без категории'))];

    sources.forEach(source => {
        const option = document.createElement('option');
        option.value = source;
        option.textContent = source;
        feedFilter.appendChild(option);
    });

    categories.forEach(category => {
        const option = document.createElement('option');
        option.value = category;
        option.textContent = category;
        categoryFilter.appendChild(option);
    });
}

// Функция для агрегирования новостей из всех RSS-лент
function getAggregatedNews() {
    let allNews = [];
    feeds.forEach(feed => {
        if (Array.isArray(feed.news)) {
            allNews = allNews.concat(feed.news.map(newsItem => ({
                ...newsItem,
                source: new URL(feed.url).hostname,
                                                                category: feed.category || 'Без категории'
            })));
        }
    });

    // Сортировка по дате публикации (новые сначала)
    allNews.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate));

    // Применение фильтра и поиска
    const searchQuery = searchInput.value.toLowerCase();
    const selectedFeed = feedFilter.value;
    const selectedCategory = categoryFilter.value;

    allNews = allNews.filter(item => {
        const matchesSearch = item.title.toLowerCase().includes(searchQuery) || item.description.toLowerCase().includes(searchQuery);
        const matchesFeed = selectedFeed === 'all' || item.source === selectedFeed;
        const matchesCategory = selectedCategory === 'all' || item.category === selectedCategory;
        return matchesSearch && matchesFeed && matchesCategory;
    });

    return allNews;
}

// Функция для отображения RSS фидов с пагинацией
function displayFeed(data) {
    const feedContainer = document.getElementById("feed");
    feedContainer.innerHTML = ''; // Очистить предыдущие новости

    if (data.length === 0) {
        feedContainer.innerHTML = '<p>Нет новостей для отображения.</p>';
        document.getElementById('pagination').classList.add('hidden');
        return;
    }

    // Расчет пагинации
    totalPages = Math.ceil(data.length / ITEMS_PER_PAGE);
    if (totalPages > 1) {
        document.getElementById('pagination').classList.remove('hidden');
    } else {
        document.getElementById('pagination').classList.add('hidden');
    }

    // Отображение текущей страницы
    const start = (currentPage - 1) * ITEMS_PER_PAGE;
    const end = start + ITEMS_PER_PAGE;
    const paginatedData = data.slice(start, end);

    paginatedData.forEach((item, index) => {
        const feedItem = document.createElement('div');
        feedItem.classList.add('col-md-6', 'col-lg-4');
        feedItem.classList.add('news-card');
        feedItem.setAttribute('data-category', item.category);

        // Добавление изображения, если оно есть
        let imageHTML = '';
        if (item.image) {
            imageHTML = `<img src="${item.image}" alt="Изображение" class="img-fluid rounded mb-2">`;
        }

        // Добавление источника новости
        let sourceHTML = '';
        if (item.source) {
            sourceHTML = `<div class="source"><strong>Источник:</strong> ${item.source}</div>`;
        }

        // Добавление описания новости с изображением
        const description = DOMPurify.sanitize(item.description, { ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br', 'ul', 'ol', 'li'] });

        feedItem.innerHTML = `
        <div class="card h-100 ${document.body.classList.contains('dark-mode') ? 'bg-dark text-white' : ''}">
        <div class="card-body">
        <h5 class="card-title"><a href="${item.link}" target="_blank" rel="noopener noreferrer" class="${document.body.classList.contains('dark-mode') ? 'text-white' : 'text-dark'} text-decoration-none">${item.title}</a></h5>
        <div class="pubDate"><strong>Дата публикации:</strong> ${new Date(item.pubDate).toLocaleString()}</div>
        <div class="news-content mt-2">
        ${imageHTML}
        <p class="card-text">${description}</p>
        </div>
        ${sourceHTML}
        </div>
        <div class="card-footer bg-transparent border-top-0">
        <button class="btn btn-warning edit-btn">Редактировать</button>
        </div>
        </div>
        `;

        // Кнопка "Редактировать"
        const editButton = feedItem.querySelector('.edit-btn');
        editButton.addEventListener('click', () => enableEditing(item.description, feedItem));

        feedContainer.appendChild(feedItem);
    });

    updatePagination();
}

// Функция для обновления пагинации
function updatePagination() {
    const currentPageSpan = document.getElementById('current-page');
    const prevPageBtn = document.getElementById('prev-page');
    const nextPageBtn = document.getElementById('next-page');

    currentPageSpan.textContent = `${currentPage} из ${totalPages}`;

    // Управление состоянием кнопок
    prevPageBtn.disabled = currentPage === 1;
    nextPageBtn.disabled = currentPage === totalPages;
}

// Обработчики для кнопок пагинации
document.getElementById('prev-page').addEventListener('click', () => {
    if (currentPage > 1) {
        currentPage--;
        displayFeed(getAggregatedNews());
    }
});

document.getElementById('next-page').addEventListener('click', () => {
    if (currentPage < totalPages) {
        currentPage++;
        displayFeed(getAggregatedNews());
    }
});

// Функция для сохранения всех новостей в HTML-документ
function saveAllNewsAsDocument() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для сохранения.');
        return;
    }

    let htmlContent = `
    <!DOCTYPE html>
    <html lang="ru">
    <head>
    <meta charset="UTF-8">
    <title>Сохранённые RSS Новости</title>
    <style>
    body {
        font-family: Arial, sans-serif;
        padding: 20px;
        background-color: #f4f4f4;
    }
    .feed-item {
        background-color: white;
        padding: 20px;
        border-radius: 5px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        margin-bottom: 20px;
    }
    .feed-item h2 { margin-top: 0; }
    .pubDate, .source {
        font-size: 0.9em;
        color: #555;
        margin-bottom: 10px;
    }
    .news-content img {
        max-width: 200px;
        border-radius: 4px;
        object-fit: cover;
        display: block;
        margin-bottom: 10px;
    }
    </style>
    </head>
    <body>
    <h1>Сохранённые RSS Новости</h1>
    `;

    feedItems.forEach(item => {
        htmlContent += `
        <div class="feed-item">
        ${item.innerHTML}
        </div>
        `;
    });

    htmlContent += `
    </body>
    </html>
    `;

    const blob = new Blob([htmlContent], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'saved_news.html';
    a.click();
    URL.revokeObjectURL(url);

    showNotification('success', 'Новости успешно сохранены!');
}

// Функция для экспорта новостей в PDF
async function exportToPDF() {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF();

    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для экспорта.');
        return;
    }

    showNotification('loading', 'Экспорт в PDF...');

    let yOffset = 10;

    for (let item of feedItems) {
        const title = item.querySelector('h2 a').textContent;
        const link = item.querySelector('h2 a').href;
        const pubDate = item.querySelector('.pubDate').textContent;
        const source = item.querySelector('.source') ? item.querySelector('.source').textContent.replace('Источник: ', '') : '';
        const description = item.querySelector('p').innerHTML;

        doc.setFontSize(16);
        doc.text(title, 10, yOffset);
        yOffset += 10;

        doc.setFontSize(12);
        doc.text(`Источник: ${source}`, 10, yOffset);
        yOffset += 7;
        doc.text(`Дата публикации: ${pubDate}`, 10, yOffset);
        yOffset += 10;

        if (item.querySelector('img')) {
            const img = item.querySelector('img');
            try {
                const imgData = await getImageDataURL(img.src);
                doc.addImage(`data:image/jpeg;base64,${imgData}`, 'JPEG', 10, yOffset, 50, 30);
                yOffset += 35;
            } catch (error) {
                console.warn('Не удалось загрузить изображение:', img.src);
            }
        }

        const text = description.replace(/<[^>]+>/g, ' ');
        const lines = doc.splitTextToSize(text, 180);
        doc.text(lines, 10, yOffset);
        yOffset += lines.length * 7;

        // Добавление разделителя
        yOffset += 10;
        if (yOffset > 270) { // Добавить новую страницу, если превышен лимит
            doc.addPage();
            yOffset = 10;
        }
    }

    doc.save('news.pdf');
    showNotification('success', 'Экспорт в PDF завершён успешно!');
}

// Функция для экспортирования RSS-лент в JSON
function exportFeeds() {
    if (feeds.length === 0) {
        showNotification('error', 'Нет RSS-лент для экспорта.');
        return;
    }

    const dataStr = JSON.stringify(feeds, null, 2);
    const blob = new Blob([dataStr], { type: "application/json" });
    saveAs(blob, "rss_feeds.json");

    showNotification('success', 'RSS-ленты успешно экспортированы!');
}

// Функция для экспортирования новостей в CSV
function exportToCSV() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для экспорта.');
        return;
    }

    let csvContent = "data:text/csv;charset=utf-8,";
    csvContent += "Заголовок,Ссылка,Описание,Дата публикации,Источник,Изображение\n";

    feedItems.forEach(item => {
        const title = item.querySelector('h2 a').textContent.replace(/,/g, ' ');
        const link = item.querySelector('h2 a').href;
        const description = item.querySelector('p').innerText.replace(/,/g, ' ').replace(/"/g, '""');
        const pubDate = item.querySelector('.pubDate').textContent;
        const source = item.querySelector('.source') ? item.querySelector('.source').textContent.replace('Источник: ', '') : '';
        const image = item.querySelector('img') ? item.querySelector('img').src : '';

        csvContent += `"${title}","${link}","${description}","${pubDate}","${source}","${image}"\n`;
    });

    const encodedUri = encodeURI(csvContent);
    const a = document.createElement('a');
    a.href = encodedUri;
    a.download = 'news.csv';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);

    showNotification('success', 'Новости успешно экспортированы в CSV!');
}

// Добавление обработчика кнопки "Экспортировать новости в CSV"
exportCsvBtn.addEventListener('click', exportToCSV);

// Функция для сохранения всех новостей в HTML-документ
function saveAllNewsAsDocument() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для сохранения.');
        return;
    }

    let htmlContent = `
    <!DOCTYPE html>
    <html lang="ru">
    <head>
    <meta charset="UTF-8">
    <title>Сохранённые RSS Новости</title>
    <style>
    body {
        font-family: Arial, sans-serif;
        padding: 20px;
        background-color: #f4f4f4;
    }
    .feed-item {
        background-color: white;
        padding: 20px;
        border-radius: 5px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        margin-bottom: 20px;
    }
    .feed-item h2 { margin-top: 0; }
    .pubDate, .source {
        font-size: 0.9em;
        color: #555;
        margin-bottom: 10px;
    }
    .news-content img {
        max-width: 200px;
        border-radius: 4px;
        object-fit: cover;
        display: block;
        margin-bottom: 10px;
    }
    </style>
    </head>
    <body>
    <h1>Сохранённые RSS Новости</h1>
    `;

    feedItems.forEach(item => {
        htmlContent += `
        <div class="feed-item">
        ${item.innerHTML}
        </div>
        `;
    });

    htmlContent += `
    </body>
    </html>
    `;

    const blob = new Blob([htmlContent], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'saved_news.html';
    a.click();
    URL.revokeObjectURL(url);

    showNotification('success', 'Новости успешно сохранены!');
}

// Функция для экспорта новостей в PDF
// Уже реализована выше через exportToPDF

// Функция для сохранения всех новостей в HTML-документ
// Уже реализована выше через saveAllNewsAsDocument

// Функция для сохранения данных в localStorage
function saveToLocalStorage() {
    localStorage.setItem('rssFeeds', JSON.stringify(feeds));
}

// Функция для загрузки данных из localStorage
function loadFromLocalStorage() {
    const storedFeeds = localStorage.getItem('rssFeeds');
    if (storedFeeds) {
        feeds = JSON.parse(storedFeeds);
        feeds.forEach(feed => {
            addFeedToList(feed.url, feed.category || 'Без категории');
        });
        displayFeed(getAggregatedNews());
        updateFeedFilter();
    }
}

// Функция для добавления RSS-ленты в список с категорией
function addFeedToList(feedUrl, category = 'Без категории') {
    const feedsUl = document.getElementById('feeds-ul');
    const li = document.createElement('li');
    li.textContent = `${feedUrl} [${category}]`;

    const removeBtn = document.createElement('button');
    removeBtn.textContent = 'Удалить';
    removeBtn.classList.add('ms-3', 'btn', 'btn-sm', 'btn-danger');
    removeBtn.addEventListener('click', () => {
        const index = feeds.findIndex(feed => feed.url === feedUrl);
        if (index > -1) {
            feeds.splice(index, 1);
            li.remove();
            saveToLocalStorage();
            displayFeed(getAggregatedNews());
            updateFeedFilter();
        }
    });

    li.appendChild(removeBtn);
    feedsUl.appendChild(li);
}

// Функция для обновления фильтров
function updateFeedFilter() {
    const feedFilter = document.getElementById('feed-filter');
    const categoryFilter = document.getElementById('category-filter');

    feedFilter.innerHTML = `<option value="all">Все источники</option>`;
    categoryFilter.innerHTML = `<option value="all">Все категории</option>`;

    // Собираем уникальные источники и категории
    const sources = [...new Set(feeds.map(feed => new URL(feed.url).hostname))];
    const categories = [...new Set(feeds.map(feed => feed.category || 'Без категории'))];

    sources.forEach(source => {
        const option = document.createElement('option');
        option.value = source;
        option.textContent = source;
        feedFilter.appendChild(option);
    });

    categories.forEach(category => {
        const option = document.createElement('option');
        option.value = category;
        option.textContent = category;
        categoryFilter.appendChild(option);
    });
}

// Функция для агрегирования новостей из всех RSS-лент
function getAggregatedNews() {
    let allNews = [];
    feeds.forEach(feed => {
        if (Array.isArray(feed.news)) {
            allNews = allNews.concat(feed.news.map(newsItem => ({
                ...newsItem,
                source: new URL(feed.url).hostname,
                                                                category: feed.category || 'Без категории'
            })));
        }
    });

    // Сортировка по дате публикации (новые сначала)
    allNews.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate));

    return allNews;
}

// Функция для отображения RSS фидов с пагинацией
function displayFeed(data) {
    const feedContainer = document.getElementById("feed");
    feedContainer.innerHTML = ''; // Очистить предыдущие новости

    if (data.length === 0) {
        feedContainer.innerHTML = '<p>Нет новостей для отображения.</p>';
        document.getElementById('pagination').classList.add('hidden');
        return;
    }

    // Расчет пагинации
    totalPages = Math.ceil(data.length / ITEMS_PER_PAGE);
    if (totalPages > 1) {
        document.getElementById('pagination').classList.remove('hidden');
    } else {
        document.getElementById('pagination').classList.add('hidden');
    }

    // Отображение текущей страницы
    const start = (currentPage - 1) * ITEMS_PER_PAGE;
    const end = start + ITEMS_PER_PAGE;
    const paginatedData = data.slice(start, end);

    paginatedData.forEach((item, index) => {
        const feedItem = document.createElement('div');
        feedItem.classList.add('col-md-6', 'col-lg-4', 'mb-4');
        feedItem.classList.add('news-card');
        feedItem.setAttribute('data-category', item.category);

        // Добавление изображения, если оно есть
        let imageHTML = '';
        if (item.image) {
            imageHTML = `<img src="${item.image}" alt="Изображение" class="img-fluid rounded mb-2">`;
        }

        // Добавление источника новости
        let sourceHTML = '';
        if (item.source) {
            sourceHTML = `<div class="source"><strong>Источник:</strong> ${item.source}</div>`;
        }

        // Добавление описания новости с изображением
        const description = DOMPurify.sanitize(item.description, { ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br', 'ul', 'ol', 'li'] });

        feedItem.innerHTML = `
        <div class="card h-100 ${document.body.classList.contains('dark-mode') ? 'bg-dark text-white' : ''}">
        <div class="card-body">
        <h5 class="card-title"><a href="${item.link}" target="_blank" rel="noopener noreferrer" class="${document.body.classList.contains('dark-mode') ? 'text-white' : 'text-dark'} text-decoration-none">${item.title}</a></h5>
        <div class="pubDate"><strong>Дата публикации:</strong> ${new Date(item.pubDate).toLocaleString()}</div>
        <div class="news-content mt-2">
        ${imageHTML}
        <p class="card-text">${description}</p>
        </div>
        ${sourceHTML}
        </div>
        <div class="card-footer bg-transparent border-top-0">
        <button class="btn btn-warning edit-btn">Редактировать</button>
        </div>
        </div>
        `;

        // Кнопка "Редактировать"
        const editButton = feedItem.querySelector('.edit-btn');
        editButton.addEventListener('click', () => enableEditing(item.description, feedItem));

        feedContainer.appendChild(feedItem);
    });

    updatePagination();
}

// Функция для обновления пагинации
function updatePagination() {
    const currentPageSpan = document.getElementById('current-page');
    const prevPageBtn = document.getElementById('prev-page');
    const nextPageBtn = document.getElementById('next-page');

    currentPageSpan.textContent = `${currentPage} из ${totalPages}`;

    // Управление состоянием кнопок
    prevPageBtn.disabled = currentPage === 1;
    nextPageBtn.disabled = currentPage === totalPages;
}

// Обработчики для кнопок пагинации
document.getElementById('prev-page').addEventListener('click', () => {
    if (currentPage > 1) {
        currentPage--;
        displayFeed(getAggregatedNews());
    }
});

document.getElementById('next-page').addEventListener('click', () => {
    if (currentPage < totalPages) {
        currentPage++;
        displayFeed(getAggregatedNews());
    }
});

// Функция для сохранения всех новостей в HTML-документ
function saveAllNewsAsDocument() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для сохранения.');
        return;
    }

    let htmlContent = `
    <!DOCTYPE html>
    <html lang="ru">
    <head>
    <meta charset="UTF-8">
    <title>Сохранённые RSS Новости</title>
    <style>
    body {
        font-family: Arial, sans-serif;
        padding: 20px;
        background-color: #f4f4f4;
    }
    .feed-item {
        background-color: white;
        padding: 20px;
        border-radius: 5px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        margin-bottom: 20px;
    }
    .feed-item h2 { margin-top: 0; }
    .pubDate, .source {
        font-size: 0.9em;
        color: #555;
        margin-bottom: 10px;
    }
    .news-content img {
        max-width: 200px;
        border-radius: 4px;
        object-fit: cover;
        display: block;
        margin-bottom: 10px;
    }
    </style>
    </head>
    <body>
    <h1>Сохранённые RSS Новости</h1>
    `;

    feedItems.forEach(item => {
        htmlContent += `
        <div class="feed-item">
        ${item.innerHTML}
        </div>
        `;
    });

    htmlContent += `
    </body>
    </html>
    `;

    const blob = new Blob([htmlContent], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'saved_news.html';
    a.click();
    URL.revokeObjectURL(url);

    showNotification('success', 'Новости успешно сохранены!');
}

// Функция для экспорта новостей в PDF
// Реализована выше

// Функция для экспортирования RSS-лент в JSON
function exportFeeds() {
    if (feeds.length === 0) {
        showNotification('error', 'Нет RSS-лент для экспорта.');
        return;
    }

    const dataStr = JSON.stringify(feeds, null, 2);
    const blob = new Blob([dataStr], { type: "application/json" });
    saveAs(blob, "rss_feeds.json");

    showNotification('success', 'RSS-ленты успешно экспортированы!');
}

// Функция для экспортирования новостей в CSV
function exportToCSV() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для экспорта.');
        return;
    }

    let csvContent = "data:text/csv;charset=utf-8,";
    csvContent += "Заголовок,Ссылка,Описание,Дата публикации,Источник,Изображение\n";

    feedItems.forEach(item => {
        const title = item.querySelector('h2 a').textContent.replace(/,/g, ' ');
        const link = item.querySelector('h2 a').href;
        const description = item.querySelector('p').innerText.replace(/,/g, ' ').replace(/"/g, '""');
        const pubDate = item.querySelector('.pubDate').textContent;
        const source = item.querySelector('.source') ? item.querySelector('.source').textContent.replace('Источник: ', '') : '';
        const image = item.querySelector('img') ? item.querySelector('img').src : '';

        csvContent += `"${title}","${link}","${description}","${pubDate}","${source}","${image}"\n`;
    });

    const encodedUri = encodeURI(csvContent);
    const a = document.createElement('a');
    a.href = encodedUri;
    a.download = 'news.csv';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);

    showNotification('success', 'Новости успешно экспортированы в CSV!');
}

// Функция для импортирования RSS-лент из JSON-файла
importForm.addEventListener('submit', function(e) {
    e.preventDefault();
    const fileInput = document.getElementById('import-file');
    const file = fileInput.files[0];

    if (!file) {
        showNotification('error', 'Пожалуйста, выберите файл для импорта.');
        return;
    }

    const reader = new FileReader();
    reader.onload = function(event) {
        try {
            const importedFeeds = JSON.parse(event.target.result);
            if (!Array.isArray(importedFeeds)) {
                throw new Error('Неверный формат файла.');
            }

            importedFeeds.forEach(feed => {
                if (feed.url && !feeds.some(f => f.url === feed.url)) {
                    feeds.push({ url: feed.url, category: feed.category || 'Без категории', news: [] });
                    addFeedToList(feed.url, feed.category || 'Без категории');
                }
            });

            saveToLocalStorage();
            displayFeed(getAggregatedNews());
            updateFeedFilter();

            showNotification('success', 'RSS-ленты успешно импортированы!');
            const importModal = bootstrap.Modal.getInstance(document.getElementById('importModal'));
            importModal.hide();
            importForm.reset();
        } catch (error) {
            console.error(error);
            showNotification('error', 'Не удалось импортировать RSS-ленты: ' + error.message);
        }
    };

    reader.readAsText(file);
});

// Функция для обновления фильтров
function updateFeedFilter() {
    const feedFilter = document.getElementById('feed-filter');
    const categoryFilter = document.getElementById('category-filter');

    feedFilter.innerHTML = `<option value="all">Все источники</option>`;
    categoryFilter.innerHTML = `<option value="all">Все категории</option>`;

    // Собираем уникальные источники и категории
    const sources = [...new Set(feeds.map(feed => new URL(feed.url).hostname))];
    const categories = [...new Set(feeds.map(feed => feed.category || 'Без категории'))];

    sources.forEach(source => {
        const option = document.createElement('option');
        option.value = source;
        option.textContent = source;
        feedFilter.appendChild(option);
    });

    categories.forEach(category => {
        const option = document.createElement('option');
        option.value = category;
        option.textContent = category;
        categoryFilter.appendChild(option);
    });
}

// Функция для агрегирования новостей из всех RSS-лент
function getAggregatedNews() {
    let allNews = [];
    feeds.forEach(feed => {
        if (Array.isArray(feed.news)) {
            allNews = allNews.concat(feed.news.map(newsItem => ({
                ...newsItem,
                source: new URL(feed.url).hostname,
                                                                category: feed.category || 'Без категории'
            })));
        }
    });

    // Сортировка по дате публикации (новые сначала)
    allNews.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate));

    return allNews;
}

// Функция для отображения RSS фидов с пагинацией
function displayFeed(data) {
    const feedContainer = document.getElementById("feed");
    feedContainer.innerHTML = ''; // Очистить предыдущие новости

    if (data.length === 0) {
        feedContainer.innerHTML = '<p>Нет новостей для отображения.</p>';
        document.getElementById('pagination').classList.add('hidden');
        return;
    }

    // Расчет пагинации
    totalPages = Math.ceil(data.length / ITEMS_PER_PAGE);
    if (totalPages > 1) {
        document.getElementById('pagination').classList.remove('hidden');
    } else {
        document.getElementById('pagination').classList.add('hidden');
    }

    // Отображение текущей страницы
    const start = (currentPage - 1) * ITEMS_PER_PAGE;
    const end = start + ITEMS_PER_PAGE;
    const paginatedData = data.slice(start, end);

    paginatedData.forEach((item, index) => {
        const feedItem = document.createElement('div');
        feedItem.classList.add('col-md-6', 'col-lg-4', 'mb-4');
        feedItem.classList.add('news-card');
        feedItem.setAttribute('data-category', item.category);

        // Добавление изображения, если оно есть
        let imageHTML = '';
        if (item.image) {
            imageHTML = `<img src="${item.image}" alt="Изображение" class="img-fluid rounded mb-2">`;
        }

        // Добавление источника новости
        let sourceHTML = '';
        if (item.source) {
            sourceHTML = `<div class="source"><strong>Источник:</strong> ${item.source}</div>`;
        }

        // Добавление описания новости с изображением
        const description = DOMPurify.sanitize(item.description, { ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p', 'br', 'ul', 'ol', 'li'] });

        feedItem.innerHTML = `
        <div class="card h-100 ${document.body.classList.contains('dark-mode') ? 'bg-dark text-white' : ''}">
        <div class="card-body">
        <h5 class="card-title"><a href="${item.link}" target="_blank" rel="noopener noreferrer" class="${document.body.classList.contains('dark-mode') ? 'text-white' : 'text-dark'} text-decoration-none">${item.title}</a></h5>
        <div class="pubDate"><strong>Дата публикации:</strong> ${new Date(item.pubDate).toLocaleString()}</div>
        <div class="news-content mt-2">
        ${imageHTML}
        <p class="card-text">${description}</p>
        </div>
        ${sourceHTML}
        </div>
        <div class="card-footer bg-transparent border-top-0">
        <button class="btn btn-warning edit-btn">Редактировать</button>
        </div>
        </div>
        `;

        // Кнопка "Редактировать"
        const editButton = feedItem.querySelector('.edit-btn');
        editButton.addEventListener('click', () => enableEditing(item.description, feedItem));

        feedContainer.appendChild(feedItem);
    });

    updatePagination();
}

// Функция для обновления пагинации
function updatePagination() {
    const currentPageSpan = document.getElementById('current-page');
    const prevPageBtn = document.getElementById('prev-page');
    const nextPageBtn = document.getElementById('next-page');

    currentPageSpan.textContent = `${currentPage} из ${totalPages}`;

    // Управление состоянием кнопок
    prevPageBtn.disabled = currentPage === 1;
    nextPageBtn.disabled = currentPage === totalPages;
}

// Обработчики для кнопок пагинации
document.getElementById('prev-page').addEventListener('click', () => {
    if (currentPage > 1) {
        currentPage--;
        displayFeed(getAggregatedNews());
    }
});

document.getElementById('next-page').addEventListener('click', () => {
    if (currentPage < totalPages) {
        currentPage++;
        displayFeed(getAggregatedNews());
    }
});

// Функция для сохранения всех новостей в HTML-документ
function saveAllNewsAsDocument() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для сохранения.');
        return;
    }

    let htmlContent = `
    <!DOCTYPE html>
    <html lang="ru">
    <head>
    <meta charset="UTF-8">
    <title>Сохранённые RSS Новости</title>
    <style>
    body {
        font-family: Arial, sans-serif;
        padding: 20px;
        background-color: #f4f4f4;
    }
    .feed-item {
        background-color: white;
        padding: 20px;
        border-radius: 5px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        margin-bottom: 20px;
    }
    .feed-item h2 { margin-top: 0; }
    .pubDate, .source {
        font-size: 0.9em;
        color: #555;
        margin-bottom: 10px;
    }
    .news-content img {
        max-width: 200px;
        border-radius: 4px;
        object-fit: cover;
        display: block;
        margin-bottom: 10px;
    }
    </style>
    </head>
    <body>
    <h1>Сохранённые RSS Новости</h1>
    `;

    feedItems.forEach(item => {
        htmlContent += `
        <div class="feed-item">
        ${item.innerHTML}
        </div>
        `;
    });

    htmlContent += `
    </body>
    </html>
    `;

    const blob = new Blob([htmlContent], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'saved_news.html';
    a.click();
    URL.revokeObjectURL(url);

    showNotification('success', 'Новости успешно сохранены!');
}

// Функция для экспорта новостей в PDF
// Реализована выше

// Функция для экспортирования RSS-лент в JSON
exportFeedsBtn.addEventListener('click', exportFeeds);

// Функция для экспортирования новостей в CSV
function exportToCSV() {
    const feedContainer = document.getElementById("feed");
    const feedItems = feedContainer.querySelectorAll('.feed-item');

    if (feedItems.length === 0) {
        showNotification('error', 'Нет новостей для экспорта.');
        return;
    }

    let csvContent = "data:text/csv;charset=utf-8,";
    csvContent += "Заголовок,Ссылка,Описание,Дата публикации,Источник,Изображение\n";

    feedItems.forEach(item => {
        const title = item.querySelector('h2 a').textContent.replace(/,/g, ' ');
        const link = item.querySelector('h2 a').href;
        const description = item.querySelector('p').innerText.replace(/,/g, ' ').replace(/"/g, '""');
        const pubDate = item.querySelector('.pubDate').textContent;
        const source = item.querySelector('.source') ? item.querySelector('.source').textContent.replace('Источник:', '').trim() : '';
        const image = item.querySelector('img') ? item.querySelector('img').src : '';

        csvContent += `"${title}","${link}","${description}","${pubDate}","${source}","${image}"\n`;
    });

    const encodedUri = encodeURI(csvContent);
    const a = document.createElement('a');
    a.href = encodedUri;
    a.download = 'news.csv';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);

    showNotification('success', 'Новости успешно экспортированы в CSV!');
}

// Добавление обработчика кнопки "Экспортировать новости в CSV"
exportCsvBtn.addEventListener('click', exportToCSV);

// Функция для импортирования RSS-лент из JSON-файла
importForm.addEventListener('submit', function(e) {
    e.preventDefault();
    const fileInput = document.getElementById('import-file');
    const file = fileInput.files[0];

    if (!file) {
        showNotification('error', 'Пожалуйста, выберите файл для импорта.');
        return;
    }

    const reader = new FileReader();
    reader.onload = function(event) {
        try {
            const importedFeeds = JSON.parse(event.target.result);
            if (!Array.isArray(importedFeeds)) {
                throw new Error('Неверный формат файла.');
            }

            importedFeeds.forEach(feed => {
                if (feed.url && !feeds.some(f => f.url === feed.url)) {
                    feeds.push({ url: feed.url, category: feed.category || 'Без категории', news: [] });
                    addFeedToList(feed.url, feed.category || 'Без категории');
                }
            });

            saveToLocalStorage();
            displayFeed(getAggregatedNews());
            updateFeedFilter();

            showNotification('success', 'RSS-ленты успешно импортированы!');
            const importModal = bootstrap.Modal.getInstance(document.getElementById('importModal'));
            importModal.hide();
            importForm.reset();
        } catch (error) {
            console.error(error);
            showNotification('error', 'Не удалось импортировать RSS-ленты: ' + error.message);
        }
    };

    reader.readAsText(file);
});

// Функция для экспорта RSS-лент в JSON
function exportFeeds() {
    if (feeds.length === 0) {
        showNotification('error', 'Нет RSS-лент для экспорта.');
        return;
    }

    const dataStr = JSON.stringify(feeds, null, 2);
    const blob = new Blob([dataStr], { type: "application/json" });
    saveAs(blob, "rss_feeds.json");

    showNotification('success', 'RSS-ленты успешно экспортированы!');
}

// Фильтр поиска и категории
searchInput.addEventListener('input', () => {
    currentPage = 1;
    displayFeed(getAggregatedNews());
});

feedFilter.addEventListener('change', () => {
    currentPage = 1;
    displayFeed(getAggregatedNews());
});

categoryFilter.addEventListener('change', () => {
    currentPage = 1;
    displayFeed(getAggregatedNews());
});

// Функция для агрегирования новостей из всех RSS-лент
function getAggregatedNews() {
    let allNews = [];
    feeds.forEach(feed => {
        if (Array.isArray(feed.news)) {
            allNews = allNews.concat(feed.news.map(newsItem => ({
                ...newsItem,
                source: new URL(feed.url).hostname,
                                                                category: feed.category || 'Без категории'
            })));
        }
    });

    // Сортировка по дате публикации (новые сначала)
    allNews.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate));

    // Применение фильтра и поиска
    const searchQuery = searchInput.value.toLowerCase();
    const selectedFeed = feedFilter.value;
    const selectedCategory = categoryFilter.value;

    allNews = allNews.filter(item => {
        const matchesSearch = item.title.toLowerCase().includes(searchQuery) || item.description.toLowerCase().includes(searchQuery);
        const matchesFeed = selectedFeed === 'all' || item.source === selectedFeed;
        const matchesCategory = selectedCategory === 'all' || item.category === selectedCategory;
        return matchesSearch && matchesFeed && matchesCategory;
    });

    return allNews;
}

// Функция для сохранения всех новостей в CSV-документ
// Реализована выше

// Функция для сохранения данных в localStorage
function saveToLocalStorage() {
    localStorage.setItem('rssFeeds', JSON.stringify(feeds));
}

// Функция для загрузки данных из localStorage
function loadFromLocalStorage() {
    const storedFeeds = localStorage.getItem('rssFeeds');
    if (storedFeeds) {
        feeds = JSON.parse(storedFeeds);
        feeds.forEach(feed => {
            addFeedToList(feed.url, feed.category || 'Без категории');
        });
        displayFeed(getAggregatedNews());
        updateFeedFilter();
    }
}

// Функция для автоматического обновления RSS-лент
function autoRefreshFeeds() {
    const REFRESH_INTERVAL = 10 * 60 * 1000; // 10 минут

    setInterval(async () => {
        if (feeds.length === 0) return;

        showNotification('loading', 'Автоматическое обновление RSS-лент...');

        for (let i = 0; i < feeds.length; i++) {
            const feed = feeds[i];
            const newNews = await fetchRSS(feed.url);

            // Проверка на новые новости
            const existingTitles = feed.news.map(news => news.title);
            const uniqueNews = newNews.filter(news => !existingTitles.includes(news.title));

            if (uniqueNews.length > 0) {
                feeds[i].news = feeds[i].news.concat(uniqueNews);
                showNotification('success', `Найдено ${uniqueNews.length} новых новостей в RSS-ленте: ${feed.url}`);
            }
        }

        saveToLocalStorage();
        displayFeed(getAggregatedNews());
    }, REFRESH_INTERVAL);
}

// Функция для инициализации приложения
window.addEventListener('load', () => {
    loadFromLocalStorage();
    displayFeed(getAggregatedNews());
    updateFeedFilter();
    initializeTheme();
    autoRefreshFeeds();
});