Allegro+

Pakiet usprawnien do Allegro.pl

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name         Allegro+
// @namespace    http://tampermonkey.net/
// @version      1.5
// @description  Pakiet usprawnien do Allegro.pl
// @author       Paweł Kaczmarek
// @match        https://allegro.pl/uzytkownik/*/oceny*
// @match        https://allegro.pl/my-assortment*
// @match        https://allegro.pl/listing?string=*
// @match        https://allegro.pl/produkt/*
// @match        https://allegro.pl/kategoria/*
// @match        https://allegro.pl/oferty-produktu/*
// @match        https://allegro.pl/uzytkownik/*
// @match        https://allegro.pl/oferta/*
// @match        https://salescenter.allegro.com/campaigns*
// @match        https://salescenter.allegro.com/costs-summary*
// @grant        GM_download
// @grant        GM_xmlhttpRequest
// @grant        GM_setClipboard
// @require      https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js
// ==/UserScript==

// --- PANEL USTAWIEŃ ---
(function() {
    const vSprintFeatures = [
        { key: 'oceny', label: 'Raport z ocen' },
        { key: 'filtr', label: 'Lepszy filtr' },
        { key: 'info', label: 'vSprint info' },
        { key: 'img', label: 'vSprint Image Downloader' },
        { key: 'kampanie', label: 'Asystent Kampanii' },
        { key: 'kampFiltr', label: 'Filtr ofert w kampaniach' },
        { key: 'kopiujId', label: 'Kopiuj ID' },
        { key: 'edytuj', label: 'Edytuj' }
    ];
    function getVSprintSettings() {
        let settings = {};
        try { settings = JSON.parse(localStorage.getItem('vSprintPlusSettings') || '{}'); } catch (e) {}
        vSprintFeatures.forEach(f => { if (typeof settings[f.key] === 'undefined') settings[f.key] = true; });
        return settings;
    }
    window.vSprintPlusSettings = getVSprintSettings();
})();

// --- OCENY ANALIZATOR ---
(function() {
    'use strict';
    if (window.vSprintPlusSettings && window.vSprintPlusSettings.oceny === false) return;

    // Uruchamiaj tylko na stronie ocen użytkownika
    if (!window.location.href.match(/^https:\/\/allegro\.pl\/uzytkownik\/[^\/]+\/oceny/)) {
        return; // Przerywamy wykonywanie tego bloku
    }

    let sellerId = null;
    let isSecondPageVisited = false;
    let ratingsData = [];
    let fetchDetected = false;

    // Funkcja do wyciągnięcia ID sprzedawcy z URL
    function extractSellerId() {
        const match = window.location.pathname.match(/\/uzytkownik\/([^\/]+)\/oceny/);
        if (match) {
            // Tutaj będziemy musieli pobrać ID sprzedawcy z API
            // Na razie ustawiamy placeholder
            return '92089972'; // To będzie musiało być pobrane dynamicznie
        }
        return null;
    }

    // Funkcja do tworzenia przycisku Raport
    function createReportButton() {
        if (document.getElementById('allegro-report-btn')) return;

        const btn = document.createElement('button');
        btn.id = 'allegro-report-btn';
        btn.textContent = 'Raport';
        btn.style.position = 'fixed';
        btn.style.top = '10px';
        btn.style.right = '20px';
        btn.style.zIndex = '99999';
        btn.style.background = '#23272e';
        btn.style.color = '#fff';
        btn.style.border = '1.5px solid #ff5a00';
        btn.style.borderRadius = '8px';
        btn.style.padding = '10px 20px';
        btn.style.fontSize = '16px';
        btn.style.cursor = 'pointer';
        btn.style.boxShadow = '0 2px 8px rgba(0,0,0,0.10)';
        btn.style.fontWeight = 'bold';
        btn.style.transition = 'background 0.2s, color 0.2s';
        btn.onmouseenter = function() {
            btn.style.background = '#ff5a00';
            btn.style.color = '#fff';
        };
        btn.onmouseleave = function() {
            btn.style.background = '#23272e';
            btn.style.color = '#fff';
        };

        btn.onclick = function() {
            if (!fetchDetected || !sellerId) {
                alert('Przejdź na kolejną stronę aby móc wygenerować raport');
                return;
            }
            showReportModal();
        };

        document.body.appendChild(btn);
    }

    // Funkcja do wyświetlania modala raportu
    function showReportModal() {
        if (document.getElementById('allegro-report-modal')) return;

        const modal = document.createElement('div');
        modal.id = 'allegro-report-modal';
        modal.style.position = 'fixed';
        modal.style.top = '50%';
        modal.style.left = '50%';
        modal.style.transform = 'translate(-50%, -50%)';
        modal.style.background = '#fff';
        modal.style.border = '1px solid #ddd';
        modal.style.borderRadius = '10px';
        modal.style.boxShadow = '0 2px 16px rgba(0,0,0,0.18)';
        modal.style.padding = '24px';
        modal.style.zIndex = '100000';
        modal.style.minWidth = '320px';

        // Nagłówek
        const title = document.createElement('div');
        title.textContent = 'Raport Produktów z Ocen';
        title.style.fontWeight = '600';
        title.style.fontSize = '20px';
        title.style.marginBottom = '25px';
        title.style.color = '#2c3e50';
        title.style.textAlign = 'center';
        title.style.borderBottom = '2px solid #f8f9fa';
        title.style.paddingBottom = '15px';
        modal.appendChild(title);

        // Pole do wpisania liczby stron
        const label = document.createElement('label');
        label.textContent = 'Liczba stron do przetworzenia (max 20):';
        label.style.display = 'block';
        label.style.marginBottom = '10px';
        label.style.color = '#000';
        modal.appendChild(label);

        const input = document.createElement('input');
        input.type = 'number';
        input.min = '1';
        input.max = '20';
        input.value = '5';
        input.style.width = '100%';
        input.style.padding = '12px 16px';
        input.style.border = '2px solid #e1e5e9';
        input.style.borderRadius = '8px';
        input.style.marginBottom = '20px';
        input.style.fontSize = '16px';
        input.style.color = '#333';
        input.style.backgroundColor = '#fff';
        input.style.boxSizing = 'border-box';
        input.style.transition = 'border-color 0.2s ease, box-shadow 0.2s ease';
        input.style.outline = 'none';

        // Hover i focus efekty
        input.addEventListener('focus', function() {
            this.style.borderColor = '#ff5a00';
            this.style.boxShadow = '0 0 0 3px rgba(255, 90, 0, 0.1)';
        });

        input.addEventListener('blur', function() {
            this.style.borderColor = '#e1e5e9';
            this.style.boxShadow = 'none';
        });

        modal.appendChild(input);

        // Przycisk pobierz
        const downloadBtn = document.createElement('button');
        downloadBtn.textContent = 'Pobierz Raport';
        downloadBtn.style.background = '#ff5a00';
        downloadBtn.style.color = '#fff';
        downloadBtn.style.border = 'none';
        downloadBtn.style.borderRadius = '6px';
        downloadBtn.style.padding = '10px 20px';
        downloadBtn.style.fontSize = '16px';
        downloadBtn.style.cursor = 'pointer';
        downloadBtn.style.marginRight = '10px';
        downloadBtn.onclick = function() {
            const pages = parseInt(input.value);
            if (pages < 1 || pages > 20) {
                alert('Liczba stron musi być między 1 a 20');
                return;
            }
            generateReport(pages);
        };
        modal.appendChild(downloadBtn);

        // Przycisk zamknij
        const closeBtn = document.createElement('button');
        closeBtn.textContent = 'Zamknij';
        closeBtn.style.background = '#ccc';
        closeBtn.style.color = '#000';
        closeBtn.style.border = 'none';
        closeBtn.style.borderRadius = '6px';
        closeBtn.style.padding = '10px 20px';
        closeBtn.style.fontSize = '16px';
        closeBtn.style.cursor = 'pointer';
        closeBtn.onclick = function() {
            modal.remove();
        };
        modal.appendChild(closeBtn);

        document.body.appendChild(modal);
    }

    // Funkcja do generowania raportu Excel
    async function generateReport(pages) {
        if (!sellerId) {
            alert('Nie udało się pobrać ID sprzedawcy');
            return;
        }

        const modal = document.getElementById('allegro-report-modal');
        const downloadBtn = modal.querySelector('button');
        downloadBtn.textContent = 'Pobieranie...';
        downloadBtn.disabled = true;

        // Dodaj progress bar
        const progressContainer = document.createElement('div');
        progressContainer.style.marginTop = '15px';
        progressContainer.style.marginBottom = '15px';

        const progressText = document.createElement('div');
        progressText.textContent = 'Pobieranie danych... (0/' + pages + ')';
        progressText.style.textAlign = 'center';
        progressText.style.marginBottom = '10px';
        progressText.style.color = '#666';

        const progressBar = document.createElement('div');
        progressBar.style.width = '100%';
        progressBar.style.height = '20px';
        progressBar.style.backgroundColor = '#f0f0f0';
        progressBar.style.borderRadius = '10px';
        progressBar.style.overflow = 'hidden';

        const progressFill = document.createElement('div');
        progressFill.style.width = '0%';
        progressFill.style.height = '100%';
        progressFill.style.backgroundColor = '#ff5a00';
        progressFill.style.transition = 'width 0.3s ease';

        progressBar.appendChild(progressFill);
        progressContainer.appendChild(progressText);
        progressContainer.appendChild(progressBar);
        modal.appendChild(progressContainer);

        try {
            const allRatings = [];

            // Pobieramy dane ze wszystkich stron z opóźnieniami
            for (let page = 1; page <= pages; page++) {
                // Aktualizuj progress
                progressText.textContent = `Pobieranie danych... (${page}/${pages})`;
                progressFill.style.width = `${(page / pages) * 100}%`;

                const response = await fetch(`https://edge.allegro.pl/ratings-api/sellers/${sellerId}/ratings?page=${page}`, {
                    headers: {
                        "accept": "application/vnd.allegro.public.v5+json",
                        "accept-language": "pl-PL",
                        "content-type": "application/vnd.allegro.public.v5+json",
                        "priority": "u=1, i",
                        "sec-ch-ua": "\"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"",
                        "sec-ch-ua-mobile": "?0",
                        "sec-ch-ua-platform": "\"Windows\"",
                        "sec-fetch-dest": "empty",
                        "sec-fetch-mode": "cors",
                        "sec-fetch-site": "same-site"
                    },
                    referrer: "https://allegro.pl/",
                    method: "GET",
                    mode: "cors",
                    credentials: "include"
                });

                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                const data = await response.json();
                allRatings.push(...data.content);

                console.log(`✅ Pobrano stronę ${page}/${pages} (${data.content.length} ocen)`);

                // Dodaj losowe opóźnienie między requestami (1-4 sekundy)
                if (page < pages) {
                    const delay = Math.random() * 3000 + 1000; // 1000-4000ms
                    console.log(`⏳ Czekam ${Math.round(delay)}ms przed następnym requestem...`);
                    progressText.textContent = `Czekam... (${page}/${pages})`;
                    await new Promise(resolve => setTimeout(resolve, delay));
                }
            }

            // Analizujemy dane
            progressText.textContent = 'Analizowanie danych...';
            progressFill.style.width = '100%';

            const offerStats = {};

            allRatings.forEach(rating => {
                if (rating.offers && rating.offers.length > 1) {
                    // Sprawdzamy tylko oferty które nie są pierwsze (indeks > 0)
                    for (let i = 1; i < rating.offers.length; i++) {
                        const offer = rating.offers[i];
                        const key = `${offer.id}_${offer.title}`;

                        if (!offerStats[key]) {
                            offerStats[key] = {
                                id: offer.id,
                                title: offer.title,
                                count: 0
                            };
                        }
                        offerStats[key].count++;
                    }
                }
            });

            // Generujemy dane do Excel
            progressText.textContent = 'Generowanie raportu...';

            const excelData = [
                ['ID Oferty', 'Nazwa Oferty', 'Ilość Dobrań']
            ];

            Object.values(offerStats)
                .sort((a, b) => b.count - a.count)
                .forEach(offer => {
                    excelData.push([offer.id, offer.title, offer.count]);
                });

            // Tworzymy workbook i worksheet
            const wb = XLSX.utils.book_new();
            const ws = XLSX.utils.aoa_to_sheet(excelData);

            // Dodajemy worksheet do workbook
            XLSX.utils.book_append_sheet(wb, ws, 'Raport Oceny');

            // Generujemy plik Excel
            const excelBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
            const blob = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });

            // Pobieramy plik
            const link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = `raport_oceny_${new Date().toISOString().split('T')[0]}.xlsx`;
            link.click();

            progressText.textContent = 'Raport wygenerowany!';
            downloadBtn.textContent = 'Pobierz Raport';
            downloadBtn.disabled = false;

            console.log(`✅ Raport wygenerowany: ${Object.keys(offerStats).length} produktów`);

        } catch (error) {
            console.error('Błąd podczas generowania raportu:', error);
            alert('Wystąpił błąd podczas generowania raportu: ' + error.message);
            downloadBtn.textContent = 'Pobierz Raport';
            downloadBtn.disabled = false;
        }
    }

    // Funkcja do sprawdzania czy jesteśmy na drugiej stronie
    function checkIfSecondPage() {
        const urlParams = new URLSearchParams(window.location.search);
        const page = urlParams.get('page');
        if (page && parseInt(page) >= 2) {
            isSecondPageVisited = true;
            console.log('Wykryto drugą stronę, czekam na fetch...');
        }
    }

    // Funkcja do przechwytywania fetch requestów
    function interceptFetchRequests() {
        const originalFetch = window.fetch;
        window.fetch = function(...args) {
            const url = args[0];
            console.log('=== FETCH REQUEST WYKRYTY ===');
            console.log('URL:', url);
            console.log('Typ URL:', typeof url);

            // Sprawdzamy różne wzorce URL
            const patterns = [
                /edge\.allegro\.pl\/ratings-api\/sellers\/(\d+)\/ratings/,
                /ratings-api\/sellers\/(\d+)\/ratings/,
                /sellers\/(\d+)\/ratings/
            ];

            let match = null;
            for (const pattern of patterns) {
                if (typeof url === 'string') {
                    match = url.match(pattern);
                    if (match) {
                        console.log('Znaleziono match z patternem:', pattern);
                        break;
                    }
                }
            }

            if (match) {
                const newSellerId = match[1];
                console.log('Nowe ID sprzedawcy:', newSellerId);
                console.log('Aktualne ID sprzedawcy:', sellerId);

                if (!sellerId || sellerId !== newSellerId) {
                    sellerId = newSellerId;
                    fetchDetected = true;
                    console.log('✅ ID sprzedawcy zaktualizowane:', sellerId);

                    // Zmień kolor przycisku
                    const btn = document.getElementById('allegro-report-btn');
                    if (btn) {
                        btn.style.background = '#28a745';
                        btn.textContent = 'Raport (Pobierz)';
                        console.log('✅ Przycisk zmieniony na zielony');
                    } else {
                        console.log('❌ Przycisk nie został znaleziony');
                    }
                }
            } else {
                console.log('❌ Nie znaleziono ID sprzedawcy w URL:', url);
            }

            return originalFetch.apply(this, args);
        };
    }

    // Funkcja do przechwytywania XMLHttpRequest
    function interceptXHRRequests() {
        const originalOpen = XMLHttpRequest.prototype.open;
        XMLHttpRequest.prototype.open = function(method, url, ...args) {
            console.log('=== XHR REQUEST WYKRYTY ===');
            console.log('URL:', url);
            console.log('Method:', method);

            // Sprawdzamy różne wzorce URL
            const patterns = [
                /edge\.allegro\.pl\/ratings-api\/sellers\/(\d+)\/ratings/,
                /ratings-api\/sellers\/(\d+)\/ratings/,
                /sellers\/(\d+)\/ratings/
            ];

            let match = null;
            for (const pattern of patterns) {
                if (typeof url === 'string') {
                    match = url.match(pattern);
                    if (match) {
                        console.log('Znaleziono match z patternem (XHR):', pattern);
                        break;
                    }
                }
            }

            if (match) {
                const newSellerId = match[1];
                console.log('Nowe ID sprzedawcy (XHR):', newSellerId);

                if (!sellerId || sellerId !== newSellerId) {
                    sellerId = newSellerId;
                    fetchDetected = true;
                    console.log('✅ ID sprzedawcy zaktualizowane (XHR):', sellerId);

                    // Zmień kolor przycisku
                    const btn = document.getElementById('allegro-report-btn');
                    if (btn) {
                        btn.style.background = '#28a745';
                        btn.textContent = 'Raport (Pobierz)';
                        console.log('✅ Przycisk zmieniony na zielony (XHR)');
                    }
                }
            }

            return originalOpen.apply(this, [method, url, ...args]);
        };
    }

    // Funkcja do sprawdzania aktywnych requestów w Network tab
    function checkNetworkRequests() {
        console.log('🔍 Sprawdzam aktywnych requestów...');

        // Sprawdź czy są jakieś requesty do ratings API
        const performanceEntries = performance.getEntriesByType('resource');
        const ratingsRequests = performanceEntries.filter(entry =>
            entry.name.includes('ratings-api/sellers/') &&
            entry.name.includes('/ratings')
        );

        console.log('Znalezione requesty ratings:', ratingsRequests);

        if (ratingsRequests.length > 0) {
            const latestRequest = ratingsRequests[ratingsRequests.length - 1];
            const match = latestRequest.name.match(/sellers\/(\d+)\/ratings/);
            if (match) {
                const newSellerId = match[1];
                console.log('✅ Znaleziono ID sprzedawcy w Network:', newSellerId);

                if (!sellerId || sellerId !== newSellerId) {
                    sellerId = newSellerId;
                    fetchDetected = true;
                    console.log('✅ ID sprzedawcy zaktualizowane z Network:', sellerId);

                    // Zmień kolor przycisku
                    const btn = document.getElementById('allegro-report-btn');
                    if (btn) {
                        btn.style.background = '#28a745';
                        btn.textContent = 'Raport (Pobierz)';
                        console.log('✅ Przycisk zmieniony na zielony z Network');
                    }
                }
            }
        }
    }

    // Funkcja do nasłuchiwania zmian URL (historia przeglądarki)
    function listenForURLChanges() {
        let currentURL = window.location.href;

        // Sprawdzaj URL co 500ms
        setInterval(() => {
            if (window.location.href !== currentURL) {
                currentURL = window.location.href;
                console.log('🔄 URL zmieniony na:', currentURL);

                // Sprawdź czy to druga strona
                const urlParams = new URLSearchParams(window.location.search);
                const page = urlParams.get('page');
                if (page && parseInt(page) >= 2) {
                    console.log('📄 Wykryto przejście na stronę:', page);

                    // Sprawdź Network requesty po 500ms
                    setTimeout(() => {
                        checkNetworkRequests();
                    }, 500);

                    // Sprawdź ponownie po 1 sekundzie
                    setTimeout(() => {
                        if (!fetchDetected) {
                            console.log('⚠️ Fetch nie został wykryty po 1 sekundzie');
                            console.log('Aktualny sellerId:', sellerId);
                            console.log('fetchDetected:', fetchDetected);
                            checkNetworkRequests();
                        }
                    }, 1000);
                }
            }
        }, 500);
    }

    // Inicjalizacja
    function init() {
        sellerId = extractSellerId();
        createReportButton();
        checkIfSecondPage();
        interceptFetchRequests();
        interceptXHRRequests();
        listenForURLChanges();

        console.log('🚀 Skrypt Allegro Oceny Analizator zainicjalizowany');
        console.log('📊 Aktualny sellerId:', sellerId);
        console.log('👀 Czekam na fetch requesty...');
    }

    // Uruchomienie skryptu
    init();
})();

// --- ALLEGRO FILTR ---
(function() {
    'use strict';

    if (window.vSprintPlusSettings && window.vSprintPlusSettings.filtr === false) return;
      // Pomocnicza funkcja do debounce
      function debounce(func, wait) {
        let timeout;
        return function (...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }

    // Tworzy panel filtrów nad tabelą
    function createFilterPanel(table) {
        // Sprawdź czy panel już istnieje
        if (document.getElementById('allegro-id-filter-panel') || document.getElementById('allegro-vsearch-btn')) return;

        // --- Przycisk vSearch ---
        const vSearchBtn = document.createElement('button');
        vSearchBtn.id = 'allegro-vsearch-btn';
        vSearchBtn.innerText = 'vSearch';
        vSearchBtn.style.position = 'absolute';
        vSearchBtn.style.top = '10px';
        vSearchBtn.style.right = '30px';
        vSearchBtn.style.zIndex = '10001';
        vSearchBtn.style.background = '#23272e';
        vSearchBtn.style.color = '#fff';
        vSearchBtn.style.border = 'none';
        vSearchBtn.style.padding = '8px 18px';
        vSearchBtn.style.fontSize = '16px';
        vSearchBtn.style.borderRadius = '8px';
        vSearchBtn.style.boxShadow = '0 2px 8px rgba(0,0,0,0.18)';
        vSearchBtn.style.cursor = 'pointer';
        vSearchBtn.style.letterSpacing = '1px';
        vSearchBtn.style.fontWeight = 'bold';
        vSearchBtn.style.transition = 'background 0.2s';
        vSearchBtn.onmouseenter = () => vSearchBtn.style.background = '#ff5a00';
        vSearchBtn.onmouseleave = () => vSearchBtn.style.background = '#23272e';

        vSearchBtn.onclick = function() {
            vSearchBtn.style.display = 'none';
            panel.style.display = 'flex';
            setTimeout(() => input.focus(), 100);
        };

        // Wstaw przycisk nad tabelą (do najbliższego kontenera)
        table.parentElement.style.position = 'relative';
        table.parentElement.insertBefore(vSearchBtn, table);

        // --- Panel filtrów ---
        const panel = document.createElement('div');
        panel.id = 'allegro-id-filter-panel';
        panel.style.background = '#23272e';
        panel.style.border = '1px solid #ff5a00';
        panel.style.padding = '18px 24px';
        panel.style.margin = '16px 0';
        panel.style.marginTop = '60px';
        panel.style.borderRadius = '12px';
        panel.style.display = 'none';
        panel.style.alignItems = 'center';
        panel.style.gap = '16px';
        panel.style.boxShadow = '0 4px 24px rgba(0,0,0,0.18)';
        panel.style.position = 'relative';
        panel.style.zIndex = '10000';
        // Panel szerszy (usuwamy maxWidth)
        panel.style.removeProperty('max-width');
        panel.style.minWidth = '340px';

        // Zamykacz X
        const closeBtn = document.createElement('button');
        closeBtn.innerText = '✕';
        closeBtn.title = 'Zamknij';
        closeBtn.style.position = 'absolute';
        closeBtn.style.top = '2px'; // wyżej
        closeBtn.style.right = '2px'; // bardziej w prawo
        closeBtn.style.background = 'transparent';
        closeBtn.style.color = '#fff';
        closeBtn.style.border = 'none';
        closeBtn.style.fontSize = '22px';
        closeBtn.style.cursor = 'pointer';
        closeBtn.style.fontWeight = 'bold';
        closeBtn.style.padding = '4px 8px';
        closeBtn.onmouseenter = () => closeBtn.style.color = '#ff5a00';
        closeBtn.onmouseleave = () => closeBtn.style.color = '#fff';
        closeBtn.onclick = function() {
            panel.style.display = 'none';
            vSearchBtn.style.display = 'inline-block';
        };
        panel.appendChild(closeBtn);

        const label = document.createElement('label');
        label.innerText = 'Filtruj ID/SKU produktu:';
        label.style.fontWeight = 'bold';
        label.style.marginRight = '8px';
        label.style.color = '#fff';
        label.htmlFor = 'allegro-id-filter-input';

        const input = document.createElement('input');
        input.type = 'text';
        input.id = 'allegro-id-filter-input';
        input.placeholder = 'np. 1772318739, SKU1234';
        input.title = 'np. 1772318739, SKU1234';
        input.style.padding = '10px 16px';
        input.style.fontSize = '18px';
        input.style.border = '1px solid #ff5a00';
        input.style.borderRadius = '6px';
        input.style.flex = '1';
        input.style.background = '#181a1f';
        input.style.color = '#fff';
        input.style.outline = 'none';
        input.onfocus = () => input.style.border = '1.5px solid #ff5a00';
        input.onblur = () => input.style.border = '1px solid #ff5a00';

        const button = document.createElement('button');
        button.innerText = 'Filtruj';
        button.style.background = '#ff5a00';
        button.style.color = '#fff';
        button.style.border = 'none';
        button.style.padding = '10px 28px';
        button.style.fontSize = '14px';
        button.style.borderRadius = '6px';
        button.style.cursor = 'pointer';
        button.style.marginLeft = '8px';
        button.style.fontWeight = 'bold';
        button.style.boxShadow = '0 2px 8px rgba(0,0,0,0.10)';
        button.onmouseenter = () => button.style.background = '#23272e';
        button.onmouseleave = () => button.style.background = '#ff5a00';

        const reset = document.createElement('button');
        reset.innerText = 'Pokaż wszystko';
        reset.style.background = '#444';
        reset.style.color = '#fff';
        reset.style.border = 'none';
        reset.style.padding = '10px 18px';
        reset.style.fontSize = '14px';
        reset.style.borderRadius = '6px';
        reset.style.cursor = 'pointer';
        reset.style.marginLeft = '8px';
        reset.style.fontWeight = 'bold';
        reset.onmouseenter = () => reset.style.background = '#ff5a00';
        reset.onmouseleave = () => reset.style.background = '#444';

        panel.appendChild(label);
        panel.appendChild(input);
        panel.appendChild(button);
        panel.appendChild(reset);

        // Wstaw panel nad tabelą
        table.parentElement.insertBefore(panel, table);

        // --- Checkbox 'zaznacz wyszukane' ---
        const selectAllDiv = document.createElement('div');
        selectAllDiv.style.display = 'flex';
        selectAllDiv.style.alignItems = 'center';
        selectAllDiv.style.gap = '8px';
        selectAllDiv.style.margin = '0 0 8px 0';
        selectAllDiv.style.fontSize = '15px';
        selectAllDiv.style.fontWeight = 'bold';
        selectAllDiv.style.color = '#fff';
        selectAllDiv.style.background = 'transparent';
        selectAllDiv.style.userSelect = 'none';

        const selectAllCheckbox = document.createElement('input');
        selectAllCheckbox.type = 'checkbox';
        selectAllCheckbox.id = 'allegro-select-all-visible';
        selectAllCheckbox.style.width = '18px';
        selectAllCheckbox.style.height = '18px';
        selectAllCheckbox.style.cursor = 'pointer';
        selectAllCheckbox.style.accentColor = '#ff5a00';
        selectAllCheckbox.style.margin = '0';

        const selectAllLabel = document.createElement('label');
        selectAllLabel.innerText = 'zaznacz wyszukane';
        selectAllLabel.htmlFor = 'allegro-select-all-visible';
        selectAllLabel.style.cursor = 'pointer';

        selectAllDiv.appendChild(selectAllCheckbox);
        selectAllDiv.appendChild(selectAllLabel);
        // Wstawiamy pod panelem, nad tabelą
        table.parentElement.insertBefore(selectAllDiv, table);

        // Funkcja do zaznaczania/odznaczania widocznych checkboxów
        function setVisibleCheckboxes(checked) {
            const tbody = table.querySelector('tbody');
            if (!tbody) return;
            Array.from(tbody.querySelectorAll('tr')).forEach(tr => {
                if (tr.style.display === 'none') return;
                // Szukamy input[type=checkbox] w pierwszej kolumnie
                const td = tr.querySelector('td');
                if (!td) return;
                const input = td.querySelector('input[type="checkbox"]');
                if (input && !input.disabled) {
                    if (input.checked !== checked) {
                        input.click(); // wywołaj kliknięcie tylko jeśli stan się zmienia
                    }
                }
            });
        }
        selectAllCheckbox.addEventListener('change', function() {
            setVisibleCheckboxes(this.checked);
        });

        // Resetuj checkbox po zmianie filtra (odznacz, jeśli filtr się zmienia)
        function resetSelectAllCheckbox() {
            selectAllCheckbox.checked = false;
        }

        // Obsługa filtrowania
        function filterRows() {
            const val = input.value.trim();
            if (!val) {
                showAllRows(table);
                resetSelectAllCheckbox();
                return;
            }
            // Zamień wszystkie białe znaki na przecinki, rozdziel po przecinku
            const filters = val.replace(/\s+/g, ',').split(',').map(x => x.trim()).filter(Boolean);
            filterTableByIdsOrSku(table, filters);
            resetSelectAllCheckbox();
        }

        button.onclick = filterRows;
        input.addEventListener('keydown', function (e) {
            if (e.key === 'Enter') filterRows();
        });
        input.addEventListener('input', debounce(filterRows, 500));
        reset.onclick = function () {
            input.value = '';
            showAllRows(table);
        };
    }

    // Pokazuje wszystkie wiersze
    function showAllRows(table) {
        const tbody = table.querySelector('tbody');
        if (!tbody) return;
        Array.from(tbody.querySelectorAll('tr')).forEach(tr => {
            tr.style.display = '';
        });
    }

    // Filtruje wiersze tabeli po ID
    function filterTableByIds(table, ids) {
        const tbody = table.querySelector('tbody');
        if (!tbody) return;
        const idSet = new Set(ids);
        Array.from(tbody.querySelectorAll('tr')).forEach(tr => {
            // Ignoruj puste wiersze (np. z paddingiem na dole)
            const hasDataCy = tr.hasAttribute('data-cy');
            const idCell = tr.querySelector('span._b4f97_bk6uO');
            if (!hasDataCy && !idCell) {
                // Nie zmieniaj stylu, zostaw wiersz w spokoju
                return;
            }
            // 1. Spróbuj znaleźć ID w <span class="_b4f97_bk6uO">
            let id = idCell ? idCell.innerText.trim() : null;
            // 2. Jeśli nie ma, spróbuj z data-cy na <tr>
            if (!id && hasDataCy) {
                id = tr.getAttribute('data-cy');
            }
            // 3. Jeśli nie ma ID, ukryj wiersz
            if (!id) {
                tr.style.display = 'none';
                return;
            }
            // 4. Ukryj lub pokaż wiersz w zależności od tego, czy ID jest na liście
            if (idSet.has(id)) {
                tr.style.display = '';
            } else {
                tr.style.display = 'none';
            }
        });
    }

    // Nowa funkcja: filtruje po ID lub sygnaturze (SKU, częściowe dopasowanie)
    function filterTableByIdsOrSku(table, filters) {
        const tbody = table.querySelector('tbody');
        if (!tbody) return;
        Array.from(tbody.querySelectorAll('tr')).forEach(tr => {
            // Ignoruj puste wiersze (np. z paddingiem na dole)
            const hasDataCy = tr.hasAttribute('data-cy');
            const idCells = tr.querySelectorAll('span._b4f97_bk6uO');
            if (!hasDataCy && idCells.length === 0) {
                // Nie zmieniaj stylu, zostaw wiersz w spokoju
                return;
            }
            // 1. ID produktu
            let id = null;
            if (hasDataCy) id = tr.getAttribute('data-cy');
            // 2. Sygnatura (SKU) – drugi span._b4f97_bk6uO w pierwszej kolumnie
            let sku = null;
            if (idCells.length > 1) {
                sku = idCells[1].innerText.trim();
            } else if (idCells.length === 1) {
                sku = idCells[0].innerText.trim();
            }
            // 3. Sprawdź czy którykolwiek filtr pasuje do ID lub SKU (częściowe dopasowanie do SKU)
            let visible = false;
            for (const f of filters) {
                if ((id && id === f) || (sku && sku.toLowerCase().includes(f.toLowerCase()))) {
                    visible = true;
                    break;
                }
            }
            tr.style.display = visible ? '' : 'none';
        });
    }

    // Szuka tabeli ofert i wstawia panel filtrów
    function tryInjectPanel() {
        const table = document.querySelector('table[aria-label="lista ofert"]');
        if (table) {
            createFilterPanel(table);
            // Dodajemy MutationObserver na <tbody> do dynamicznego filtrowania
            const tbody = table.querySelector('tbody');
            if (tbody && !tbody._allegroFilterObserver) {
                const observer = new MutationObserver(() => {
                    // Pobierz aktualne ID z inputa
                    const input = document.getElementById('allegro-id-filter-input');
                    if (!input) return;
                    const val = input.value.trim();
                    if (!val) {
                        showAllRows(table);
                        return;
                    }
                    const filters = val.replace(/\s+/g, ',').split(',').map(x => x.trim()).filter(Boolean);
                    filterTableByIdsOrSku(table, filters);
                });
                observer.observe(tbody, { childList: true, subtree: true });
                tbody._allegroFilterObserver = observer;
            }
        }
    }

    // Dla dynamicznego ładowania
    const observer = new MutationObserver(() => {
        tryInjectPanel();
    });
    observer.observe(document.body, { childList: true, subtree: true });

    // Na wszelki wypadek po załadowaniu
    window.addEventListener('load', () => {
        setTimeout(tryInjectPanel, 1000);
    });
})();

// --- ALLEGRO INFO+ ---
(function() {
    'use strict';

    if (window.vSprintPlusSettings && window.vSprintPlusSettings.info === false) return;

function addStyles() {
    var styleContent = `

                .date-container {
                    margin-bottom: 20px;
                }
                .date-container label {
                    display: block;
                    margin-bottom: 5px;
                }
                .date-container input {
                    width: 95%;
                    padding: 12px;
                    border: 1px solid #ddd;
                    border-radius: 5px;
                    font-size: 16px;
                }
                #fetch-data-btn, #showEntriesBtn, .show-successful-stats, .show-total-stats, .product-btn {
                    padding: 10px 15px;
                    color: #fff;
                    border: none;
                    border-radius: 5px;
                    cursor: pointer;
                    text-decoration: none;
                }

                #fetch-data-btn{
                margin-left:5px;
                }



    .date-button {
            padding: 10px 15px;
            color: #fff;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            margin-left: 5px;
            margin-top: 5px;
    }

    .date-button:hover{
    background-color: #0056b3;}

    .DataButton-container{
    padding-bottom: 10px;
    }

    .prom-efficiency {
        margin: 40px 0px 20px 0px;
        font-family: Arial, sans-serif;
    }

    .prom-efficiency table {
        width: 100%;
        border-collapse: collapse;
        margin-top: 20px;
    }

    .prom-efficiency thead {
        background-color: #878c91;
        color: white;
    }

    .prom-efficiency th,
    .prom-efficiency td {
        padding: 12px 15px;
        text-align: left;
        border: 1px solid #ddd;
    }

    .prom-efficiency tr:nth-child(even) {
        background-color: #f2f2f2;
    }

    .prom-efficiency h3 {
        margin-bottom: 10px;
    }

    .prom-efficiency td:first-child {
        font-weight: bold;
    }
    #statystyka-content h3{
        background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
        color: white; /* Kolor tekstu */
        padding: 10px; /* Wypełnienie wewnętrzne */
        border-top-left-radius: 8px; /* Zaokrąglenie lewego górnego rogu */
        border-top-right-radius: 8px; /* Zaokrąglenie prawego górnego rogu */
        margin: -15px -15px 15px -15px; /* Negatywne marginesy, aby nagłówek wkomponował się w ramkę */
        font-size: 0.9em; /* Zwiększenie rozmiaru czcionki */
        font-weight: bold; /* Ustawienie czcionki na pogrubioną */
        text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); /* Cień tekstu */
        }

        #statystyka-content button, .product-btn {
            background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
        }

        #statystyka-content .date-button {
            background-color: grey !important;
            background: none;
        }


        .total-stats, .successful-stats{
            margin-top:40px;
        }

        .section-title {
            margin-top: 0;
            font-size: 1.2em;
            position: relative; /* Umożliwia pozycjonowanie pseudo-elementu */
        }

        .section-title::after {
            content: ""; /* Pusty zawartość, tworzy linię */
            display: block; /* Umożliwia ustawienie wysokości */
            width: 100%; /* Długość linii */
            height: 2px; /* Grubość linii */
            background: #ccc; /* Kolor linii */
            margin-top: 5px; /* Odstęp od nagłówka */
        }

        `;
    var style = document.createElement('style');
    style.textContent = styleContent;
    document.head.appendChild(style);
    }

    // Wywołanie funkcji do dodania stylów
    addStyles();

    // Funkcja do dodania przycisku do artykułów
    function addStatystykaButton() {
        // Pobieramy wszystkie artykuły w możliwych kontenerach
        var articles = document.querySelectorAll("div[data-role='rightItems'] article, .sponsored-article-selector article, li article");
        articles.forEach(function(article) {
            // Sprawdzamy, czy przyciski już istnieją, aby nie dodawać ich wielokrotnie
            if (article.querySelector("button.statystyka-btn")) return;

            // Sprawdź czy to oferta sponsorowana
            var isSponsored = article.textContent.includes('Sponsorowane');

            // Sprawdzamy czy przycisk "Edytuj" już istnieje (tylko jeśli funkcja jest włączona)
            if (window.vSprintPlusSettings && window.vSprintPlusSettings.edytuj !== false && article.querySelector("button.edytuj-btn")) return;

            // Sprawdzamy czy przycisk "Kopiuj ID" już istnieje (tylko jeśli funkcja jest włączona)
            if (window.vSprintPlusSettings && window.vSprintPlusSettings.kopiujId !== false && article.querySelector("button.copy-id-btn")) return;

            // Pobieramy auctionID z linku w artykule
            var auctionID = getAuctionID(article);
            var title = getArticleTitle(article); // Pobieramy tytuł artykułu

            // Debug dla ofert sponsorowanych
            if (isSponsored && !auctionID) {
                console.log("❌ Nie można pobrać ID z oferty sponsorowanej:", article);
                var links = article.querySelectorAll("a");
                console.log("🔗 Znalezione linki:", links.length);
                links.forEach(function(link, index) {
                    console.log(`Link ${index}:`, link.href);
                });
            }

            // Jeśli nie udało się uzyskać ID, pomiń artykuł
            if (!auctionID) return;

            // Tworzymy przycisk "Edytuj" tylko jeśli funkcja jest włączona
            var edytujButton = null;
            if (window.vSprintPlusSettings && window.vSprintPlusSettings.edytuj !== false) {
                edytujButton = document.createElement("button");
                edytujButton.className = "edytuj-btn";
                edytujButton.innerHTML = "Edytuj";
                edytujButton.style.position = "absolute";
                edytujButton.style.right = "0px";
                edytujButton.style.bottom = "142px"; // Nad przyciskiem Kopiuj ID
                edytujButton.style.padding = "10px 16px";
                edytujButton.style.backgroundColor = "#6c757d";
                edytujButton.style.color = "#fff";
                edytujButton.style.border = "none";
                edytujButton.style.borderRadius = "5px";
                edytujButton.style.cursor = "pointer";
                edytujButton.style.zIndex = "200";
                edytujButton.style.fontSize = "12px";
            }

            // Tworzymy przycisk "Kopiuj ID" tylko jeśli funkcja jest włączona
            var copyIdButton = null;
            if (window.vSprintPlusSettings && window.vSprintPlusSettings.kopiujId !== false) {
                copyIdButton = document.createElement("button");
            copyIdButton.className = "copy-id-btn";
            copyIdButton.innerHTML = "Kopiuj ID";
            copyIdButton.style.position = "absolute";
            copyIdButton.style.right = "0px";
            copyIdButton.style.bottom = "102px"; // Nad przyciskiem Statystyka
            copyIdButton.style.padding = "10px 16px";
            copyIdButton.style.backgroundColor = "#28a745";
            copyIdButton.style.color = "#fff";
            copyIdButton.style.border = "none";
            copyIdButton.style.borderRadius = "5px";
            copyIdButton.style.cursor = "pointer";
            copyIdButton.style.zIndex = "200";
            copyIdButton.style.fontSize = "12px";
            }

            // Tworzymy nowy element przycisku Statystyka
            var button = document.createElement("button");
            button.className = "statystyka-btn"; // Dodajemy klasę do identyfikacji
            button.innerHTML = "Statystyka";
            button.style.position = "absolute";
            button.style.right = "0px";
            button.style.bottom = "62px";
            button.style.padding = "10px 20px";
            button.style.backgroundColor = "#007bff";
            button.style.color = "#fff";
            button.style.border = "none";
            button.style.borderRadius = "5px";
            button.style.cursor = "pointer";
            button.style.zIndex = "200"; // Ustawienie przycisku na wierzchu

            // Ustawiamy pozycję przycisków w obrębie article
            article.style.position = "relative";
            if (edytujButton) {
                article.appendChild(edytujButton);
            }
            if (copyIdButton) {
                article.appendChild(copyIdButton);
            }
            article.appendChild(button);

            // Dodajemy funkcjonalność przycisku Edytuj
            if (edytujButton) {
                edytujButton.addEventListener("click", function(event) {
                    event.stopPropagation(); // Zapobiegamy propagacji kliknięcia
                    openEditPage(auctionID); // Otwieramy stronę edycji oferty
                });
            }

            // Dodajemy funkcjonalność przycisku Kopiuj ID
            if (copyIdButton) {
                copyIdButton.addEventListener("click", function(event) {
                    event.stopPropagation(); // Zapobiegamy propagacji kliknięcia
                    copyToClipboard(auctionID); // Kopiujemy ID do schowka
                });
            }

            // Dodajemy funkcjonalność przycisku Statystyka
            button.addEventListener("click", function(event) {
                event.stopPropagation(); // Zapobiegamy propagacji kliknięcia
                openModal(auctionID, title); // Otwieramy modalne okno
            });
        });
    }

    // Funkcja do pobrania auctionID z linku w artykule
    function getAuctionID(article) {
        // Najpierw spróbuj standardowego linku
        var linkElement = article.querySelector("a[href*='/oferta/']");
        if (linkElement) {
            var link = linkElement.getAttribute("href");
            var auctionID = link.split("-").pop();
            return auctionID;
        }

        // Dla ofert sponsorowanych - szukaj linków z redirect=
        var allLinks = article.querySelectorAll("a");
        for (var i = 0; i < allLinks.length; i++) {
            var href = allLinks[i].getAttribute("href");
            if (href && href.includes("redirect=")) {
                // Dekoduj URL i wyciągnij ID
                try {
                    var decodedUrl = decodeURIComponent(href);
                    var match = decodedUrl.match(/allegro\.pl\/oferta\/([^?]+)/);
                    if (match) {
                        var auctionID = match[1].split("-").pop();
                        return auctionID;
                    }
                } catch (e) {
                    // Ignoruj błędy dekodowania
                }
            }
        }

        return null;
    }

    // Funkcja do pobrania tytułu artykułu
    function getArticleTitle(article) {
        var h2Element = article.querySelector("h2");
        return h2Element ? h2Element.textContent.trim() : "";
    }

    // Funkcja do kopiowania ID do schowka
    function copyToClipboard(text) {
        // Sprawdzamy czy GM_setClipboard jest dostępne (Tampermonkey)
        if (typeof GM_setClipboard !== 'undefined') {
            GM_setClipboard(text);
            showCopyNotification('ID skopiowane do schowka!');
        } else {
            // Fallback dla przeglądarek bez GM_setClipboard
            if (navigator.clipboard && window.isSecureContext) {
                navigator.clipboard.writeText(text).then(function() {
                    showCopyNotification('ID skopiowane do schowka!');
                }).catch(function(err) {
                    console.error('Błąd kopiowania do schowka:', err);
                    fallbackCopyTextToClipboard(text);
                });
            } else {
                fallbackCopyTextToClipboard(text);
            }
        }
    }

    // Fallback funkcja kopiowania dla starszych przeglądarek
    function fallbackCopyTextToClipboard(text) {
        var textArea = document.createElement("textarea");
        textArea.value = text;
        textArea.style.top = "0";
        textArea.style.left = "0";
        textArea.style.position = "fixed";
        textArea.style.opacity = "0";
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();

        try {
            var successful = document.execCommand('copy');
            if (successful) {
                showCopyNotification('ID skopiowane do schowka!');
            } else {
                showCopyNotification('Nie udało się skopiować ID', 'error');
            }
        } catch (err) {
            console.error('Błąd kopiowania:', err);
            showCopyNotification('Nie udało się skopiować ID', 'error');
        }

        document.body.removeChild(textArea);
    }

    // Funkcja do wyświetlania powiadomienia o kopiowaniu
    function showCopyNotification(message, type) {
        // Usuń poprzednie powiadomienie jeśli istnieje
        var existingNotification = document.querySelector('.copy-notification');
        if (existingNotification) {
            existingNotification.remove();
        }

        var notification = document.createElement('div');
        notification.className = 'copy-notification';
        notification.textContent = message;
        notification.style.position = 'fixed';
        notification.style.top = '20px';
        notification.style.right = '20px';
        notification.style.backgroundColor = type === 'error' ? '#dc3545' : '#28a745';
        notification.style.color = '#fff';
        notification.style.padding = '12px 20px';
        notification.style.borderRadius = '5px';
        notification.style.zIndex = '10001';
        notification.style.fontSize = '14px';
        notification.style.fontWeight = 'bold';
        notification.style.boxShadow = '0 2px 10px rgba(0,0,0,0.3)';
        notification.style.transition = 'opacity 0.3s ease';

        document.body.appendChild(notification);

        // Usuń powiadomienie po 3 sekundach
        setTimeout(function() {
            notification.style.opacity = '0';
            setTimeout(function() {
                if (notification.parentNode) {
                    notification.parentNode.removeChild(notification);
                }
            }, 300);
        }, 3000);
    }

    // Funkcja do otwierania strony edycji oferty
    function openEditPage(auctionID) {
        if (!auctionID) {
            showCopyNotification('Nie udało się pobrać ID oferty', 'error');
            return;
        }

        const editUrl = `https://salescenter.allegro.com/offer/${auctionID}`;

        // Otwieramy link w nowej karcie
        window.open(editUrl, '_blank');

        // Wyświetlamy powiadomienie o otwarciu
        showCopyNotification('Otwieranie strony edycji oferty...', 'success');
    }

// Funkcja do tworzenia i wyświetlania modalnego okna
// Funkcja do tworzenia i wyświetlania modalnego okna
function openModal(auctionID, title) {
    // Tworzymy modalne okno, jeśli jeszcze nie istnieje
    var existingModal = document.querySelector("#statystyka-modal");
    if (!existingModal) {
        var modal = document.createElement("div");
        modal.id = "statystyka-modal";
        modal.style.position = "fixed";
        modal.style.top = "0";
        modal.style.right = "0";
        modal.style.width = "35%";
        modal.style.height = "100%";
        modal.style.backgroundColor = "#ffffff";
        modal.style.overflowY = "auto";
        modal.style.boxShadow = "0 0 10px rgba(0, 0, 0, 0.2)";
        modal.style.transform = "translateX(100%)";
        modal.style.transition = "transform 0.3s ease";
        modal.style.zIndex = "10000";
        modal.style.color = "#333";
        modal.style.fontFamily = "Arial, sans-serif";

        var content = document.createElement("div");
        content.style.padding = "20px";
        content.style.position = "relative";
        content.style.lineHeight = "1.6";

        var closeButton = document.createElement("span");
        closeButton.innerHTML = "&times;";
        closeButton.style.position = "absolute";
        closeButton.style.top = "10px";
        closeButton.style.right = "10px";
        closeButton.style.cursor = "pointer";
        closeButton.style.fontSize = "24px";
        closeButton.style.color = "#007bff";
        closeButton.addEventListener("click", function () {
            modal.style.transform = "translateX(100%)";
            setTimeout(function () {
                modal.remove();
            }, 300);
        });

        var modalContent = document.createElement("div");
        modalContent.id = "statystyka-content";

        // Sprawdzamy czy skrypty już są załadowane
        if (!window.flatpickr || !window.Chart) {
            // Dodaj Flatpickr i lokalizację polską tylko jeśli nie są już załadowane
            var script = document.createElement('script');
            var chartscript = document.createElement('script');
            script.src = 'https://cdn.jsdelivr.net/npm/flatpickr';
            chartscript.src="https://cdn.jsdelivr.net/npm/chart.js"

            document.head.appendChild(script);
            document.head.appendChild(chartscript);

            var localeScript = document.createElement('script');
            localeScript.src = 'https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/pl.js';
            document.head.appendChild(localeScript);

            // Upewnij się, że oba skrypty są załadowane, zanim zainicjalizujesz Flatpickr
            Promise.all([
                new Promise(resolve => { script.onload = resolve; }),
                new Promise(resolve => { localeScript.onload = resolve; })
            ]).then(() => {
                initializeModalContent();
            });
        } else {
            // Skrypty już są załadowane, od razu inicjalizuj
            initializeModalContent();
        }

        function initializeModalContent() {
            // Sprawdzenie, czy elementy #start-date i #end-date istnieją przed inicjalizacją Flatpickr
            var startDateInput = document.querySelector("#start-date");
            var endDateInput = document.querySelector("#end-date");

            // Funkcja do zapisywania dat do localStorage
            function saveDateToLocalStorage() {
                if (startDateInput && endDateInput) {
                    localStorage.setItem("start-date", startDateInput.value);
                    localStorage.setItem("end-date", endDateInput.value);
                }
            }

            // Funkcja do ładowania dat z localStorage
            function loadDateFromLocalStorage() {
                var storedStartDate = localStorage.getItem("start-date");
                var storedEndDate = localStorage.getItem("end-date");

                if (storedStartDate) {
                    startDateInput.value = storedStartDate;
                }
                if (storedEndDate) {
                    endDateInput.value = storedEndDate;
                }
            }

            if (startDateInput) {
                flatpickr(startDateInput, {
                    dateFormat: "Y-m-d",
                    disableMobile: true,
                    locale: 'pl', // Ustawienie lokalizacji na polski
                    allowInput: false, // Zablokuj ręczne wpisywanie dat
                    onChange: saveDateToLocalStorage // Zapisuj datę po każdej zmianie
                });
            }

            if (endDateInput) {
                flatpickr(endDateInput, {
                    dateFormat: "Y-m-d",
                    disableMobile: true,
                    locale: 'pl', // Ustawienie lokalizacji na polski
                    allowInput: false, // Zablokuj ręczne wpisywanie dat
                    onChange: saveDateToLocalStorage // Zapisuj datę po każdej zmianie
                });
            }

            // Załaduj daty z localStorage przy ładowaniu modala
            loadDateFromLocalStorage();

// Dodanie przycisku "Poprzedni tydzień"
var prevWeekButton = document.createElement("button");
prevWeekButton.innerText = "Poprzedni tydzień";
prevWeekButton.className = "date-button"; // Dodajemy klasę CSS

// Funkcja do obliczenia dat poprzedniego tygodnia
prevWeekButton.addEventListener("click", function () {
    var today = new Date();
    var lastSunday = new Date(today.setDate(today.getDate() - today.getDay() - 7)); // Ostatnia niedziela sprzed tygodnia
    var lastMonday = new Date(today.setDate(today.getDate() - 6)); // Poniedziałek przed ostatnią niedzielą

    startDateInput.value = lastMonday.toISOString().split('T')[0]; // Ustaw pierwszy dzień tygodnia (poniedziałek)
    endDateInput.value = lastSunday.toISOString().split('T')[0]; // Ustaw ostatni dzień tygodnia (niedziela)
});

// Dodanie przycisku "Ostatnie 7 dni"
var last7DaysButton = document.createElement("button");
last7DaysButton.innerText = "Ostatnie 7 dni";
last7DaysButton.className = "date-button"; // Dodajemy klasę CSS

// Dodanie przycisku "Ostatnie 14 dni"
var last14DaysButton = document.createElement("button");
last14DaysButton.innerText = "Ostatnie 14 dni";
last14DaysButton.className = "date-button"; // Dodajemy klasę CSS

// Dodanie przycisku "Ostatnie 30 dni (maksymalny zakres)"
var last30DaysButton = document.createElement("button");
last30DaysButton.innerText = "Ostatnie 30 dni (maksymalny zakres)";
last30DaysButton.className = "date-button"; // Dodajemy klasę CSS

// Funkcja do obliczenia dat ostatnich 7 dni
last7DaysButton.addEventListener("click", function () {
    var yesterday = new Date();
    yesterday.setDate(yesterday.getDate() - 1); // Ustaw wczoraj

    var startDate = new Date(yesterday);
    startDate.setDate(startDate.getDate() - 6); // 7 dni wstecz od wczoraj

    startDateInput.value = startDate.toISOString().split('T')[0]; // Ustaw pierwszy dzień
    endDateInput.value = yesterday.toISOString().split('T')[0]; // Ustaw wczorajszy dzień
});

// Funkcja do obliczenia dat ostatnich 14 dni
last14DaysButton.addEventListener("click", function () {
    var yesterday = new Date();
    yesterday.setDate(yesterday.getDate() - 1); // Ustaw wczoraj

    var startDate = new Date(yesterday);
    startDate.setDate(startDate.getDate() - 13); // 14 dni wstecz od wczoraj

    startDateInput.value = startDate.toISOString().split('T')[0]; // Ustaw pierwszy dzień
    endDateInput.value = yesterday.toISOString().split('T')[0]; // Ustaw wczorajszy dzień
});

// Funkcja do obliczenia dat ostatnich 30 dni
last30DaysButton.addEventListener("click", function () {
    var today = new Date();
    var startDate = new Date(today);
    startDate.setDate(startDate.getDate() - 29); // 30 dni wstecz od dzisiaj (włącznie z dzisiaj)

    startDateInput.value = startDate.toISOString().split('T')[0]; // Ustaw pierwszy dzień
    endDateInput.value = today.toISOString().split('T')[0]; // Ustaw dzisiaj jako datę końcową
});

// Dodanie przycisku "Wczoraj"
var yesterdayButton = document.createElement("button");
yesterdayButton.innerText = "Wczoraj";
yesterdayButton.className = "date-button"; // Dodajemy klasę CSS

// Funkcja do ustawiania daty wczorajszej
yesterdayButton.addEventListener("click", function () {
    var yesterday = new Date();
    yesterday.setDate(yesterday.getDate() - 1); // Ustaw wczoraj

    startDateInput.value = yesterday.toISOString().split('T')[0]; // Ustaw dzień wczorajszy jako datę początkową
    endDateInput.value = yesterday.toISOString().split('T')[0]; // Ustaw dzień wczorajszy jako datę końcową
});

// Tworzenie kontenera na przyciski
var DataButtonContainer = document.createElement("div");
DataButtonContainer.className = "DataButton-container"; // Możesz dodać klasę CSS do stylizacji

// Dodaj przyciski do kontenera
DataButtonContainer.appendChild(yesterdayButton);
DataButtonContainer.appendChild(prevWeekButton);
DataButtonContainer.appendChild(last7DaysButton);
DataButtonContainer.appendChild(last14DaysButton);
DataButtonContainer.appendChild(last30DaysButton);

// Zidentyfikuj przycisk "Pobierz dane"
var fetchDataButton = dateForm.querySelector("#fetch-data-btn");

// Dodaj kontener z przyciskami przed przyciskiem "Pobierz dane"
dateForm.insertBefore(DataButtonContainer, fetchDataButton);

// Dodaj formularz do modalnego okna
modalContent.appendChild(dateForm);
        }

        // Dodanie formularza wyboru dat
        var dateForm = document.createElement("div");
        dateForm.innerHTML = `
            <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">

            <div class="date-container">
                <label for="start-date">Data początkowa:</label>
                <input type="text" id="start-date" placeholder="Wybierz datę">
            </div>
            <div class="date-container">
                <label for="end-date">Data końcowa:</label>
                <input type="text" id="end-date" placeholder="Wybierz datę">
            </div>
            <button id="fetch-data-btn">Pobierz dane</button>
        `;
        dateForm.style.marginBottom = "20px";

        content.appendChild(closeButton);
        content.appendChild(dateForm);
        content.appendChild(modalContent);
        modal.appendChild(content);
        document.body.appendChild(modal);

        // Otwórz modalne okno z animacją
        setTimeout(function () {
            modal.style.transform = "translateX(0)";
        }, 10);

        // Wywołujemy funkcję do pobrania danych i wypełnienia modalnego okna
        document.querySelector("#fetch-data-btn").addEventListener("click", function () {
            var startDate = document.querySelector("#start-date").value;
            var endDate = document.querySelector("#end-date").value;
            fetchModalData(auctionID, title, startDate, endDate);
        });
    } else {
        existingModal.style.transform = "translateX(0)"; // Upewniamy się, że modalne okno jest widoczne
    }
}




// Funkcja do pobierania danych i wypełniania modalnego okna
async function fetchModalData(auctionID, title, startDate, endDate) {
    var modalContent = document.querySelector("#statystyka-content");
    if (!modalContent) return;

    // Wyświetlamy progress bar z statusem dla każdego fetcha
    modalContent.innerHTML = `
        <h2 style="margin-top: 0;">Statystyki dla oferty ${auctionID}</h2>

        <div id="fetch-progress" style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px; background-color: #f8f9fa;">
            <h3 style="position: relative;">
                Pobieranie danych...
                <button id="retry-failed-fetches" style="display: none; position: absolute; right: 0; top: 50%; transform: translateY(-50%); background-color: #28a745; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; font-size: 14px; font-weight: bold;">
                    🔄 Spróbuj ponownie
                </button>
            </h3>

            <div id="fetch-status-deals" class="fetch-status" style="display: flex; align-items: center; padding: 12px 0; border-bottom: 1px solid #eee;">
                <span style="flex: 1;">📊 Dane sprzedaży</span>
                <span id="status-deals" style="color: #6c757d; margin-left: 15px; padding-right: 5px;">⏳ Oczekiwanie...</span>
            </div>

            <div id="fetch-status-prices" class="fetch-status" style="display: flex; align-items: center; padding: 12px 0; border-bottom: 1px solid #eee;">
                <span style="flex: 1;">💰 Historia cen</span>
                <span id="status-prices" style="color: #6c757d; margin-left: 15px; padding-right: 5px;">⏳ Oczekiwanie...</span>
            </div>

            <div id="fetch-status-conversion" class="fetch-status" style="display: flex; align-items: center; padding: 12px 0; border-bottom: 1px solid #eee;">
                <span style="flex: 1;">🔄 Konwersja oferty</span>
                <span id="status-conversion" style="color: #6c757d; margin-left: 15px; padding-right: 5px;">⏳ Oczekiwanie...</span>
            </div>

            <div id="fetch-status-product" class="fetch-status" style="display: flex; align-items: center; padding: 12px 0; border-bottom: 1px solid #eee;">
                <span style="flex: 1;">📈 Konwersja produktu</span>
                <span id="status-product" style="color: #6c757d; margin-left: 15px; padding-right: 5px;">⏳ Oczekiwanie...</span>
            </div>

            <div id="fetch-status-promotion" class="fetch-status" style="display: flex; align-items: center; padding: 12px 0; border-bottom: 1px solid #eee;">
                <span style="flex: 1;">🎯 Promowania</span>
                <span id="status-promotion" style="color: #6c757d; margin-left: 15px; padding-right: 5px;">⏳ Oczekiwanie...</span>
            </div>

            <div id="fetch-status-keywords" class="fetch-status" style="display: flex; align-items: center; padding: 12px 0;">
                <span style="flex: 1;">🔑 Słowa kluczowe</span>
                <span id="status-keywords" style="color: #6c757d; margin-left: 15px; padding-right: 5px;">⏳ Oczekiwanie...</span>
            </div>
        </div>


        <div id="loading-spinner" style="display: flex; justify-content: center; align-items: center;">
            <div style="border: 4px solid #f3f3f3; border-radius: 50%; border-top: 4px solid #007bff; width: 40px; height: 40px; animation: spin 1s linear infinite;"></div>
        </div>
        <style>
            @keyframes spin {
                0% { transform: rotate(0deg); }
                100% { transform: rotate(360deg); }
            }
            .fetch-status {
                transition: all 0.3s ease;
            }
        </style>
    `;

    // Inicjalizujemy obiekt do przechowywania danych z obsługą błędów
    const dataResults = {
        salesData: null,
        priceMonitorData: null,
        conversionData: null,
        conversionDataExtended: null,
        promotionData: null,
        keywordsData: null,
        errors: [],
        failedFetches: [] // Śledzenie nieudanych fetchów
    };

    // Funkcja do formatowania błędów HTTP
    function formatHttpError(status) {
        switch (status) {
            case 401:
                return 'Brak dostępu, zaloguj się na właściwe konto Analytics';
            case 429:
                return 'Za dużo zapytań';
            case 403:
                return 'Błąd 403';
            case 404:
                return 'Nie znaleziono';
            case 500:
                return 'Błąd serwera';
            case 503:
                return 'Serwis niedostępny';
            default:
                return `Błąd HTTP: ${status}`;
        }
    }

    // Funkcja do aktualizowania statusu fetcha
    function updateFetchStatus(fetchName, status, message) {
        const statusElement = document.getElementById(`status-${fetchName}`);
        const fetchElement = document.getElementById(`fetch-status-${fetchName}`);

        if (statusElement && fetchElement) {
            let icon, color;
            switch (status) {
                case 'loading':
                    icon = '⏳';
                    color = '#007bff';
                    break;
                case 'success':
                    icon = '✅';
                    color = '#28a745';
                    // Usuń z listy nieudanych fetchów jeśli był tam
                    dataResults.failedFetches = dataResults.failedFetches.filter(f => f !== fetchName);
                    break;
                case 'error':
                    icon = '❌';
                    color = '#dc3545';
                    // Dodaj do listy nieudanych fetchów
                    if (!dataResults.failedFetches.includes(fetchName)) {
                        dataResults.failedFetches.push(fetchName);
                    }
                    break;
                case 'skipped':
                    icon = '⏭️';
                    color = '#6c757d';
                    // Nie dodawaj do listy nieudanych fetchów dla "Niemożliwe"
                    if (message !== 'Niemożliwe' && !dataResults.failedFetches.includes(fetchName)) {
                        dataResults.failedFetches.push(fetchName);
                    }
                    break;
                default:
                    icon = '⏳';
                    color = '#6c757d';
            }

            statusElement.innerHTML = `${icon} ${message}`;
            statusElement.style.color = color;

            if (status === 'success') {
                fetchElement.style.backgroundColor = '#d4edda';
                fetchElement.style.borderLeft = '4px solid #28a745';
            } else if (status === 'error') {
                fetchElement.style.backgroundColor = '#f8d7da';
                fetchElement.style.borderLeft = '4px solid #dc3545';
            } else if (status === 'skipped') {
                fetchElement.style.backgroundColor = '#e2e3e5';
                fetchElement.style.borderLeft = '4px solid #6c757d';
            }

            // Pokaż/ukryj przycisk retry (tylko jeśli przycisk już istnieje)
            setTimeout(() => updateRetryButton(), 100);
        }
    }

    // Funkcja do aktualizowania przycisku retry
    function updateRetryButton() {
        const retryButton = document.getElementById('retry-failed-fetches');
        if (retryButton) {
            if (dataResults.failedFetches.length > 0) {
                retryButton.style.display = 'block';
                retryButton.textContent = `🔄 Spróbuj ponownie (${dataResults.failedFetches.length})`;
            } else {
                retryButton.style.display = 'none';
            }
        }
    }

    try {
        // Fetch 1: Dane sprzedażowe (niezależny)
        updateFetchStatus('deals', 'loading', 'Pobieranie...');
        try {
            const response1 = await fetch("https://edge.allegro.pl/analytics/auction/deals", {
                "credentials": "include",
                "headers": {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
                    "Accept": "application/vnd.allegro.internal.v1+json",
                    "Accept-Language": "pl-PL",
                    "Content-Type": "application/vnd.allegro.internal.v1+json",
                    "Sec-Fetch-Dest": "empty",
                    "Sec-Fetch-Mode": "cors",
                    "Sec-Fetch-Site": "same-site",
                    "Priority": "u=0",
                    "Pragma": "no-cache",
                    "Cache-Control": "no-cache"
                },
                "referrer": "https://allegro.pl/",
                "body": JSON.stringify({
                    "includePhrasesMode": "OfferOrProduct",
                    "excludePhrasesMode": "OfferOrProduct",
                    "auctionId": auctionID,
                    "sellerIds": [],
                    "marketplaceIds": ["allegro-pl"],
                    "startDate": startDate,
                    "endDate": endDate,
                    "startDateTime": startDate + "T00:00:00.000Z",
                    "endDateTime": endDate + "T23:59:59.999Z",
                    "reportCode": "TOP7D"
                }),
                "method": "POST",
                "mode": "cors"
            });

            if (response1.ok) {
                const data1 = await response1.json();
                if (data1 && data1.result && data1.result.saleInfo) {
                    dataResults.salesData = data1;
                    updateFetchStatus('deals', 'success', 'Pobrano pomyślnie');
                    console.log("✅ Pobrano dane sprzedaży:", data1);
                    console.log("🔍 pmdProductIds:", data1.result.pmdProductIds);
                } else {
                    updateFetchStatus('deals', 'error', 'Nieprawidłowa struktura danych');
                    dataResults.errors.push("Nieprawidłowa struktura danych sprzedaży");
                }
            } else {
                updateFetchStatus('deals', 'error', formatHttpError(response1.status));
                dataResults.errors.push(`Błąd HTTP sprzedaży: ${response1.status}`);
            }
        } catch (error) {
            updateFetchStatus('deals', 'error', `Błąd: ${error.message}`);
            dataResults.errors.push(`Błąd pobierania danych sprzedaży: ${error.message}`);
            console.error("Błąd pobierania danych sprzedaży:", error);
        }

        // Fetch 2: Monitorowanie cen (niezależny)
        updateFetchStatus('prices', 'loading', 'Pobieranie...');
        try {
            const response2 = await fetch("https://edge.allegro.pl/analytics/reports/auctions/pricemonitor/pricejournal", {
                "credentials": "include",
                "headers": {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
                    "Accept": "application/vnd.allegro.internal.v1+json",
                    "Accept-Language": "pl-PL",
                    "Content-Type": "application/vnd.allegro.internal.v1+json",
                    "Priority": "u=4",
                    "Pragma": "no-cache",
                    "Cache-Control": "no-cache",
                    "Sec-Fetch-Dest": "empty",
                    "Sec-Fetch-Mode": "cors",
                    "Sec-Fetch-Site": "same-site"
                },
                "referrer": "https://allegro.pl/",
                "body": JSON.stringify({
                    "includePhrases": title,
                    "includePhrasesMode": "OfferOrProduct",
                    "excludePhrasesMode": "OfferOrProduct",
                    "auctionType": 1,
                    "sellerIds": [],
                    "skip": 0,
                    "take": 1000,
                    "marketplaceIds": ["allegro-pl"],
                    "startDate": startDate + "T00:00:00.000Z",
                    "endDate": endDate + "T00:00:00.000Z",
                    "startDateTime": startDate + "T00:00:00.000Z",
                    "endDateTime": endDate + "T23:59:59.999Z",
                    "reportCode": "TOP7D"
                }),
                "method": "POST",
                "mode": "cors"
            });

            if (response2.ok) {
                const data2 = await response2.json();
                if (data2 && data2.entries) {
                    dataResults.priceMonitorData = data2;
                    updateFetchStatus('prices', 'success', 'Pobrano pomyślnie');
                    console.log("✅ Pobrano dane monitorowania cen:", data2);
                } else {
                    updateFetchStatus('prices', 'error', 'Nieprawidłowa struktura danych');
                    dataResults.errors.push("Nieprawidłowa struktura danych monitorowania cen");
                }
            } else {
                updateFetchStatus('prices', 'error', formatHttpError(response2.status));
                dataResults.errors.push(`Błąd HTTP monitorowania cen: ${response2.status}`);
            }
        } catch (error) {
            updateFetchStatus('prices', 'error', `Błąd: ${error.message}`);
            dataResults.errors.push(`Błąd pobierania danych monitorowania cen: ${error.message}`);
            console.error("Błąd pobierania danych monitorowania cen:", error);
        }

        // Fetch 3: Konwersja (zależy od productid z salesData)
        console.log("🔍 Sprawdzanie productid:", dataResults.salesData?.result?.pmdProductIds);
        if (dataResults.salesData && dataResults.salesData.result.pmdProductIds && dataResults.salesData.result.pmdProductIds.length > 0) {
            updateFetchStatus('conversion', 'loading', 'Pobieranie...');
            try {
                const productid = dataResults.salesData.result.pmdProductIds[0];
                const response3 = await fetch("https://edge.allegro.pl/analytics/reports/sale/byconversion", {
                    "credentials": "include",
                    "headers": {
                        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0",
                        "Accept": "application/vnd.allegro.internal.v1+json",
                        "Accept-Language": "pl-PL",
                        "Content-Type": "application/vnd.allegro.internal.v1+json",
                        "Sec-Fetch-Dest": "empty",
                        "Sec-Fetch-Mode": "cors",
                        "Sec-Fetch-Site": "same-site",
                        "Priority": "u=0",
                        "Pragma": "no-cache",
                        "Cache-Control": "no-cache"
                    },
                    "referrer": "https://allegro.pl/",
                    "body": JSON.stringify({
                        "includePhrases": productid,
                        "includePhrasesMode": "AnyId",
                        "excludePhrasesMode": "AnyId",
                        "sellerIds": [],
                        "includeCancelledAndReturned": true,
                        "skip": 0,
                        "take": 1000,
                        "marketplaceIds": ["allegro-pl"],
                        "startDate": startDate + "T00:00:00.000Z",
                        "endDate": endDate + "T00:00:00.000Z",
                        "startDateTime": startDate + "T00:00:00.000Z",
                        "endDateTime": endDate + "T23:59:59.999Z",
                        "reportCode": "TOP7D"
                    }),
                    "method": "POST",
                    "mode": "cors"
                });

                if (response3.ok) {
                    const data3 = await response3.json();
                    if (data3 && data3.result && data3.result.entries) {
                        dataResults.conversionData = data3;
                        updateFetchStatus('conversion', 'success', 'Pobrano pomyślnie');
                        console.log("✅ Pobrano dane konwersji:", data3);
                    } else {
                        updateFetchStatus('conversion', 'error', 'Nieprawidłowa struktura danych');
                        dataResults.errors.push("Nieprawidłowa struktura danych konwersji");
                    }
                } else {
                    updateFetchStatus('conversion', 'error', formatHttpError(response3.status));
                    dataResults.errors.push(`Błąd HTTP konwersji: ${response3.status}`);
                }
            } catch (error) {
                updateFetchStatus('conversion', 'error', `Błąd: ${error.message}`);
                dataResults.errors.push(`Błąd pobierania danych konwersji: ${error.message}`);
                console.error("Błąd pobierania danych konwersji:", error);
            }
        } else {
            const productIds = dataResults.salesData?.result?.pmdProductIds;
            if (!productIds) {
                updateFetchStatus('conversion', 'skipped', 'Niemożliwe');
                dataResults.errors.push("Brak pmdProductIds w odpowiedzi - pominięto pobieranie danych konwersji");
            } else if (productIds.length === 0) {
                updateFetchStatus('conversion', 'skipped', 'Niemożliwe');
                dataResults.errors.push("Pusta tablica pmdProductIds - pominięto pobieranie danych konwersji");
            } else {
                updateFetchStatus('conversion', 'skipped', 'Niemożliwe');
                dataResults.errors.push("Nieprawidłowe pmdProductIds - pominięto pobieranie danych konwersji");
            }
        }

        // Fetch 4: Rozszerzone dane konwersji (zależy od pmdProductName z conversionData)
        if (dataResults.conversionData && dataResults.conversionData.result && dataResults.conversionData.result.entries) {
            const conversionDataAfter = dataResults.conversionData.result.entries.filter(entry => entry.ids.includes(auctionID));
            const pmdProductName = conversionDataAfter.length ? conversionDataAfter[0].pmdProductName : null;

            if (pmdProductName) {
                updateFetchStatus('product', 'loading', 'Pobieranie...');
                try {
                    const response4 = await fetch("https://edge.allegro.pl/analytics/reports/sale/byconversion", {
                        "credentials": "include",
                        "headers": {
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0",
                            "Accept": "application/vnd.allegro.internal.v1+json",
                            "Accept-Language": "pl-PL",
                            "Content-Type": "application/vnd.allegro.internal.v1+json",
                            "Sec-Fetch-Dest": "empty",
                            "Sec-Fetch-Mode": "cors",
                            "Sec-Fetch-Site": "same-site"
                        },
                        "referrer": "https://allegro.pl/",
                        "body": JSON.stringify({
                            "includePhrases": pmdProductName,
                            "includePhrasesMode": "Product",
                            "excludePhrasesMode": "Product",
                            "auctionType": 1,
                            "sellerIds": [],
                            "skip": 0,
                            "take": 1000,
                            "marketplaceIds": ["allegro-pl"],
                            "startDate": startDate + "T00:00:00.000Z",
                            "endDate": endDate + "T00:00:00.000Z",
                            "startDateTime": startDate + "T00:00:00.000Z",
                            "endDateTime": endDate + "T23:59:59.999Z",
                            "reportCode": "TOP7D"
                        }),
                        "method": "POST",
                        "mode": "cors"
                    });

                    if (response4.ok) {
                        const data4 = await response4.json();
                        if (data4 && data4.result) {
                            dataResults.conversionDataExtended = data4;
                            updateFetchStatus('product', 'success', 'Pobrano pomyślnie');
                            console.log("✅ Pobrano rozszerzone dane konwersji:", data4);
                        } else {
                            updateFetchStatus('product', 'error', 'Nieprawidłowa struktura danych');
                            dataResults.errors.push("Nieprawidłowa struktura rozszerzonych danych konwersji");
                        }
                    } else {
                        updateFetchStatus('product', 'error', formatHttpError(response4.status));
                        dataResults.errors.push(`Błąd HTTP rozszerzonych danych konwersji: ${response4.status}`);
                    }
                } catch (error) {
                    updateFetchStatus('product', 'error', `Błąd: ${error.message}`);
                    dataResults.errors.push(`Błąd pobierania rozszerzonych danych konwersji: ${error.message}`);
                    console.error("Błąd pobierania rozszerzonych danych konwersji:", error);
                }
            } else {
                updateFetchStatus('product', 'skipped', 'Niemożliwe');
                dataResults.errors.push("Brak pmdProductName - pominięto rozszerzone dane konwersji");
            }
        } else {
            updateFetchStatus('product', 'skipped', 'Niemożliwe');
            dataResults.errors.push("Brak danych konwersji - pominięto rozszerzone dane konwersji");
        }

        // Fetch 5: Dane promocji (zależny od danych sprzedaży)
        updateFetchStatus('promotion', 'loading', 'Pobieranie...');
        try {
            // Sprawdzamy czy mamy dane sprzedaży z pmdProductIds
            if (!dataResults.salesData || !dataResults.salesData.result.pmdProductIds || dataResults.salesData.result.pmdProductIds.length === 0) {
                updateFetchStatus('promotion', 'skipped', 'Niemożliwe');
                dataResults.errors.push("Brak pmdProductIds - pominięto pobieranie danych promocji");
            } else {
                const productId = dataResults.salesData.result.pmdProductIds[0];
                const sellerId = dataResults.salesData.result.seller?.id;

                const response5 = await fetch("https://edge.allegro.pl/analytics/reports/sale/bypromotion", {
                    "credentials": "include",
                    "headers": {
                        "Accept": "application/vnd.allegro.internal.v1+json",
                        "Accept-Language": "pl-PL",
                        "Content-Type": "application/vnd.allegro.internal.v1+json",
                        "Priority": "u=1, i",
                        "Sec-CH-UA": "\"Google Chrome\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"",
                        "Sec-CH-UA-Mobile": "?0",
                        "Sec-CH-UA-Platform": "\"Windows\"",
                        "Sec-Fetch-Dest": "empty",
                        "Sec-Fetch-Mode": "cors",
                        "Sec-Fetch-Site": "same-site"
                    },
                    "referrer": "https://allegro.pl/",
                    "referrerPolicy": "strict-origin-when-cross-origin",
                    "body": JSON.stringify({
                        "includePhrases": productId,
                        "includePhrasesMode": "AnyId",
                        "excludePhrasesMode": "AnyId",
                        "sellerIds": [],
                        "marketplaceIds": ["allegro-pl"],
                        "startDate": startDate + "T00:00:00.000Z",
                        "endDate": endDate + "T00:00:00.000Z",
                        "startDateTime": startDate + "T02:00:00.000Z",
                        "endDateTime": endDate + "T23:59:59.999Z",
                        "reportCode": "LASTFULL7DAYS"
                    }),
                    "method": "POST",
                    "mode": "cors"
                });

                if (response5.ok) {
                    const data5 = await response5.json();
                    if (data5 && data5.result && data5.result.entries) {
                        dataResults.promotionData = data5;
                        updateFetchStatus('promotion', 'success', 'Pobrano pomyślnie');
                        console.log("✅ Pobrano dane promocji:", data5);
                    } else {
                        updateFetchStatus('promotion', 'error', 'Nieprawidłowa struktura danych');
                        dataResults.errors.push("Nieprawidłowa struktura danych promocji");
                    }
                } else {
                    updateFetchStatus('promotion', 'error', formatHttpError(response5.status));
                    dataResults.errors.push(`Błąd HTTP promocji: ${response5.status}`);
                }
            }
        } catch (error) {
            updateFetchStatus('promotion', 'error', `Błąd: ${error.message}`);
            dataResults.errors.push(`Błąd pobierania danych promocji: ${error.message}`);
            console.error("Błąd pobierania danych promocji:", error);
        }

        // Fetch 6: Słowa kluczowe (zależy od productid z salesData)
        if (dataResults.salesData && dataResults.salesData.result.pmdProductIds && dataResults.salesData.result.pmdProductIds.length > 0) {
            updateFetchStatus('keywords', 'loading', 'Pobieranie...');
            try {
                const productId = dataResults.salesData.result.pmdProductIds[0];

                const response6 = await fetch("https://edge.allegro.pl/analytics/reports/sale/bykeyword", {
                    "credentials": "include",
                    "headers": {
                        "Accept": "application/vnd.allegro.internal.v1+json",
                        "Accept-Language": "pl-PL",
                        "Content-Type": "application/vnd.allegro.internal.v1+json",
                        "Priority": "u=1, i",
                        "Sec-CH-UA": "\"Chromium\";v=\"140\", \"Not=A?Brand\";v=\"24\", \"Google Chrome\";v=\"140\"",
                        "Sec-CH-UA-Mobile": "?0",
                        "Sec-CH-UA-Platform": "\"Windows\"",
                        "Sec-Fetch-Dest": "empty",
                        "Sec-Fetch-Mode": "cors",
                        "Sec-Fetch-Site": "same-site"
                    },
                    "referrer": "https://allegro.pl/",
                    "body": JSON.stringify({
                        "includePhrases": productId,
                        "includePhrasesMode": "AnyId",
                        "excludePhrasesMode": "OfferOrProduct",
                        "auctionId": auctionID,
                        "skip": 0,
                        "take": 1000,
                        "marketplaceIds": ["allegro-pl"],
                        "startDate": startDate + "T00:00:00.000Z",
                        "endDate": endDate + "T00:00:00.000Z",
                        "startDateTime": startDate + "T02:00:00.000Z",
                        "endDateTime": endDate + "T04:38:00.000Z",
                        "reportCode": "LASTFULL7DAYS"
                    }),
                    "method": "POST",
                    "mode": "cors"
                });

                if (response6.ok) {
                    const data6 = await response6.json();
                    if (data6 && data6.result && data6.result.entries) {
                        dataResults.keywordsData = data6;
                        updateFetchStatus('keywords', 'success', 'Pobrano pomyślnie');
                        console.log("✅ Pobrano dane słów kluczowych:", data6);
                    } else {
                        updateFetchStatus('keywords', 'error', 'Nieprawidłowa struktura danych');
                        dataResults.errors.push("Nieprawidłowa struktura danych słów kluczowych");
                    }
                } else {
                    updateFetchStatus('keywords', 'error', formatHttpError(response6.status));
                    dataResults.errors.push(`Błąd HTTP słów kluczowych: ${response6.status}`);
                }
            } catch (error) {
                updateFetchStatus('keywords', 'error', `Błąd: ${error.message}`);
                dataResults.errors.push(`Błąd pobierania danych słów kluczowych: ${error.message}`);
                console.error("Błąd pobierania danych słów kluczowych:", error);
            }
        } else {
            updateFetchStatus('keywords', 'skipped', 'Niemożliwe');
            dataResults.errors.push("Brak pmdProductIds - pominięto pobieranie danych słów kluczowych");
        }

        // Sprawdzamy czy mamy przynajmniej jakieś dane do wyświetlenia
        if (!dataResults.salesData && !dataResults.priceMonitorData && !dataResults.conversionData && !dataResults.promotionData) {
            // Sprawdź czy wystąpił błąd 401
            const has401Error = dataResults.errors.some(errorMsg => errorMsg.includes('401'));
            const errorMessage = has401Error ?
                'Brak dostępu, zaloguj się na właściwe konto Analytics' :
                'Nie udało się pobrać żadnych danych. Sprawdź połączenie internetowe i spróbuj ponownie.';
            throw new Error(errorMessage);
        }

        // Wyodrębniamy dane z dostępnych źródeł z obsługą błędów
        var totalSale = 0, todaySale = 0, yesterdaySale = 0, promotionCycles = [];
        var offerStartDate = '', startingQuantity = 0, currentQuantity = 0, seller = '';
        var productid = [], filtProductId = null;

        if (dataResults.salesData) {
            const salesData = dataResults.salesData.result;
            totalSale = salesData.saleInfo?.totalSale || 0;
            todaySale = salesData.saleInfo?.todaySale || 0;
            yesterdaySale = salesData.saleInfo?.yesterdaySale || 0;
            promotionCycles = salesData.promotionCyclesHistory || [];
            offerStartDate = salesData.overallItemInfo?.startDate || '';
            startingQuantity = salesData.startingQuantity || 0;
            currentQuantity = salesData.currentQuantity || 0;
            seller = salesData.seller?.name || '';
            productid = salesData.pmdProductIds || [];
            if (productid.length > 0) filtProductId = productid[0];
        }

        // Filtrowanie danych monitorowania cen
        var filteredEntries = [];
        if (dataResults.priceMonitorData && dataResults.priceMonitorData.entries) {
            filteredEntries = dataResults.priceMonitorData.entries
                .filter(entry => entry.id == auctionID)
                .sort((a, b) => new Date(a.priceChange) - new Date(b.priceChange));
        }

        // Przetwarzanie danych konwersji
        var conversionData = [];
        var conversionDataAfter = [];
        var pmdProductName = null;
        var wholeConversion = [];

        if (dataResults.conversionData && dataResults.conversionData.result && dataResults.conversionData.result.entries) {
            conversionData = dataResults.conversionData.result.entries.filter(entry => entry.ids.includes(auctionID));
            conversionDataAfter = dataResults.conversionData.result.entries.filter(entry => entry.ids.includes(auctionID));
            pmdProductName = conversionDataAfter.length ? conversionDataAfter[0].pmdProductName : null;
        }

        // Przetwarzanie rozszerzonych danych konwersji
        if (dataResults.conversionDataExtended && dataResults.conversionDataExtended.result) {
            wholeConversion = dataResults.conversionDataExtended.result.entries.filter(entry => entry.pmdProductId === String(filtProductId));
        }

        // Przetwarzanie danych promocji
        var entries = [];
        if (dataResults.promotionData && dataResults.promotionData.result && dataResults.promotionData.result.entries) {
            entries = dataResults.promotionData.result.entries;
        }

// Zmienne do przechowywania danych
var FreeDeliveryAndPromotion = {};
var FreeDelivery = {};
var Promotion = {}; // Nowa zmienna dla entries.options === 4

// Funkcja do przekształcania efficiencyClass na odpowiednią wartość tekstową
function getEfficiencyClassText(efficiencyClass) {
    switch (efficiencyClass) {
        case 4:
            return 'Bardzo wysoki';
        case 3:
            return 'Wysoki';
        case 2:
            return 'Średni';
        case 1:
            return 'Niski';
        case 0:
            return 'Bardzo niski';
        default:
            return 'Nieznany';
    }
}

// Funkcja do przekształcania wartości dziesiętnej na procenty (np. 0.6146 na 61,46%)
function toPercentage(value) {
    return (value * 100).toFixed(2) + '%';
}

// Przejdź przez wszystkie elementy w "entries" i wyciągnij potrzebne dane
entries.forEach(entry => {
    if (entry.options === 68) {
        FreeDeliveryAndPromotion.efficiencyClass = getEfficiencyClassText(entry.efficiencyClass);
        FreeDeliveryAndPromotion.sale = toPercentage(entry.saleParticipation.sale);
        FreeDeliveryAndPromotion.transactions = toPercentage(entry.saleParticipation.transactions);
    } else if (entry.options === 64) {
        FreeDelivery.efficiencyClass = getEfficiencyClassText(entry.efficiencyClass);
        FreeDelivery.sale = toPercentage(entry.saleParticipation.sale);
        FreeDelivery.transactions = toPercentage(entry.saleParticipation.transactions);
    } else if (entry.options === 4) { // Dodane dla Promotion
        Promotion.efficiencyClass = getEfficiencyClassText(entry.efficiencyClass);
        Promotion.sale = toPercentage(entry.saleParticipation.sale);
        Promotion.transactions = toPercentage(entry.saleParticipation.transactions);
    }
});


// Wyświetl zmienne w konsoli
console.log("Dane dla FreeDeliveryAndPromotion:", FreeDeliveryAndPromotion);
console.log("Dane dla FreeDelivery:", FreeDelivery);
console.log("Dane dla Promotion:", Promotion);



// Teraz masz dostępne zmienne:
// FreeDeliveryAndPromotion.efficiencyClass
// FreeDeliveryAndPromotion.sale
// FreeDeliveryAndPromotion.transactions

// FreeDelivery.efficiencyClass
// FreeDelivery.sale
// FreeDelivery.transactions

console.log(FreeDeliveryAndPromotion);
console.log(FreeDelivery);




// Suma wszystkich transactions
var totalTransactions = wholeConversion.length > 0 ? wholeConversion.reduce((sum, entry) => sum + entry.transactions, 0) : 0;

// Średnia liczba transakcji
var averageTransactions = wholeConversion.length > 0 ? totalTransactions / wholeConversion.length : 0;

// Średnia konwersji
var totalConversion = wholeConversion.length > 0 ? wholeConversion.reduce((sum, entry) => sum + entry.conversion, 0) : 0;
var averageConversion = wholeConversion.length > 0 ? totalConversion / wholeConversion.length : 0;

// Średnia liczba wizyt
var totalViewsCount = wholeConversion.length > 0 ? wholeConversion.reduce((sum, entry) => sum + entry.viewsCount, 0) : 0;
var averageViewsCount = wholeConversion.length > 0 ? totalViewsCount / wholeConversion.length : 0;

// Średnia liczba sprzedanych sztuk
var totalAverageSoldItems = wholeConversion.length > 0 ? wholeConversion.reduce((sum, entry) => sum + entry.averageSoldItems, 0) : 0;
var averageSoldItems = wholeConversion.length > 0 ? totalAverageSoldItems / wholeConversion.length : 0;
//-----------------------------------------------//

// Filtrowanie danych w wholeConversion dla transactions > 0
var successfulConversions = wholeConversion.length > 0 ? wholeConversion.filter(entry => entry.transactions > 0) : [];

// Obliczenia na podstawie przefiltrowanych danych
var totalSuccessfulTransactions = successfulConversions.length > 0 ? successfulConversions.reduce((sum, entry) => sum + entry.transactions, 0) : 0;
var averageSuccessfulTransactions = successfulConversions.length > 0 ? totalSuccessfulTransactions / successfulConversions.length : 0;
var averageSuccessfulConversion = successfulConversions.length > 0 ? successfulConversions.reduce((sum, entry) => sum + entry.conversion, 0) / successfulConversions.length : 0;
var averageSuccessfulViewsCount = successfulConversions.length > 0 ? successfulConversions.reduce((sum, entry) => sum + entry.viewsCount, 0) / successfulConversions.length : 0;
var averageSuccessfulSoldItems = successfulConversions.length > 0 ? successfulConversions.reduce((sum, entry) => sum + entry.averageSoldItems, 0) / successfulConversions.length : 0;
var SccessfulViewsCount = successfulConversions.length > 0 ? successfulConversions.reduce((sum, entry) => sum + entry.viewsCount, 0) : 0;


    const calculatePercentageDiff = (currentValue, referenceValue) => {
    if (referenceValue === 0) return 0; // Unikaj dzielenia przez zero
    return ((currentValue - referenceValue) / referenceValue * 100).toFixed(2);
};

            const calculatePointsDifference = (currentPercentage, referencePercentage) => {
    // Obliczamy różnicę w punktach procentowych
    return (currentPercentage - referencePercentage).toFixed(2); // Zwracamy różnicę z dwoma miejscami po przecinku
};

function calculateDiffClass(value) {
    return value >= 0 ? 'text-success' : 'text-danger'; // Zwraca klasę w zależności od wartości
}
            const calculateProportionPercentage = (x, y) => {
    if (x === 0) return 0; // Unikaj dzielenia przez zero
    return ((y / x) * 100).toFixed(2); // Oblicza procent, jakim y jest względem x
};


const style = document.createElement('style');
style.innerHTML = `
    .text-success {
        color: green; /* Zielony kolor dla wartości dodatnich */
    }
    .text-danger {
        color: red; /* Czerwony kolor dla wartości ujemnych */
    }
`;
document.head.appendChild(style);

 /* Tworzenie przycisku "Pobierz do Excela"
let downloadButton = document.createElement('button');
downloadButton.textContent = 'Pobierz do Excela';
downloadButton.style.position = 'fixed';
downloadButton.style.top = '50px';
downloadButton.style.right = '10px';
downloadButton.style.zIndex = '9999';
downloadButton.style.padding = '10px 20px';
downloadButton.style.backgroundColor = '#4CAF50';
downloadButton.style.color = 'white';
downloadButton.style.border = 'none';
downloadButton.style.borderRadius = '5px';
downloadButton.style.cursor = 'pointer';
document.body.appendChild(downloadButton);*/




        // Wyświetlamy dane w modalnym oknie
        let modalHTML = '';

        // Sekcja danych sprzedażowych (tylko jeśli dostępne)
        if (dataResults.salesData) {
            modalHTML += `
                <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;" class="conversion">
                    <h3>📊 Wartość sprzedaży:</h3>
                    <p><strong>Sprzedaż w wybranym okresie:</strong> ${formatCurrency(totalSale)}</p>
                    <p><strong>Sprzedaż dzisiaj:</strong> ${formatCurrency(todaySale)}</p>
                    <p><strong>Sprzedaż wczoraj:</strong> ${formatCurrency(yesterdaySale)}</p>
                    <br>
                    <h4 class="section-title">Dodatkowe informacje</h4>
                    <p><strong>Tytuł:</strong> ${dataResults.salesData.result.itemName || 'Brak danych'} (${(dataResults.salesData.result.itemName || '').length} znaków)</p>
                    <p><strong>Data rozpoczęcia oferty:</strong> ${formatDaty(offerStartDate)}</p>
                    <p><strong>Początkowa ilość:</strong> ${startingQuantity}</p>
                    <p><strong>Obecna ilość:</strong> ${currentQuantity}</p>
                    <p><strong>Sprzedawca:</strong> ${seller}</p>
                    ${filtProductId ? `<a class="product-btn" href="https://allegro.pl/moje-allegro/sprzedaz/produkt/zglos-blad/${filtProductId}" target="_blank">Sprawdź / zgłoś produkt</a>` : ''}
                </div>
            `;
        } else {
            modalHTML += `
                <div style="border: 1px solid #ffa500; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(255,165,0,0.1); margin-bottom: 20px; background-color: #fff8e1;">
                    <h3 style="color: #f57c00;">⚠️ Dane sprzedaży niedostępne</h3>
                    <p>Nie udało się pobrać danych sprzedażowych dla tej oferty.</p>
                </div>
            `;
        }



        // Sekcja cykli promowania (tylko jeśli dostępne)
        if (dataResults.salesData && promotionCycles.length > 0) {
            modalHTML += `
                <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;">
                    <h3>🎯 Cykle promowania oferty:</h3>
                    ${promotionCycles.map((cycle) => {
                        let promotionOptions;
                        switch (cycle.promotionOptions) {
                            case 4:
                                promotionOptions = 'Wyróżnienie ';
                                break;
                            case 68:
                                promotionOptions = 'Wyróżnienie + darmowa dostawa';
                                break;
                            default:
                                promotionOptions = 'Wyróżnienie';
                        }
                        return `<p><strong>${promotionOptions}</strong>: ${formatDate(cycle.startDate)} do ${formatDate(cycle.endDate)}</p>`;
                    }).join('')}
                </div>
            `;
        }

        // Sekcja potencjału wyróżnień (tylko jeśli dostępne)
        if (dataResults.promotionData && entries.length > 0) {
            modalHTML += `
                <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;">
                    <h3 style="margin-top: 0; color: #fff; background-color: #007bff; padding: 10px 15px; border-radius: 4px; margin: -15px -15px 15px -15px;">🎯 Potencjał wyróżnień dla tego produktu</h3>
                    <div class="prom-efficiency">
                        <table>
                            <thead>
                                <tr>
                                    <th>Typ</th>
                                    <th>Potencjał</th>
                                    <th>Udział sprzedaży</th>
                                    <th>Udział transakcji</th>
                                </tr>
                            </thead>
                            <tbody>
                                ${Object.keys(FreeDeliveryAndPromotion).length > 0 ? `
                                <tr>
                                    <td>Wyróżnienie + Darmowa dostawa</td>
                                    <td>${FreeDeliveryAndPromotion.efficiencyClass}</td>
                                    <td>${FreeDeliveryAndPromotion.sale}</td>
                                    <td>${FreeDeliveryAndPromotion.transactions}</td>
                                </tr>
                                ` : ''}

                                ${Object.keys(FreeDelivery).length > 0 ? `
                                <tr>
                                    <td>Darmowa dostawa</td>
                                    <td>${FreeDelivery.efficiencyClass}</td>
                                    <td>${FreeDelivery.sale}</td>
                                    <td>${FreeDelivery.transactions}</td>
                                </tr>
                                ` : ''}

                                ${Object.keys(Promotion).length > 0 ? `
                                <tr>
                                    <td>Wyróżnienie</td>
                                    <td>${Promotion.efficiencyClass}</td>
                                    <td>${Promotion.sale}</td>
                                    <td>${Promotion.transactions}</td>
                                </tr>
                                ` : ''}
                            </tbody>
                        </table>
                    </div>
                </div>
            `;
        } else if (dataResults.promotionData === null) {
            modalHTML += `
                <div style="border: 1px solid #ffa500; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(255,165,0,0.1); margin-bottom: 20px; background-color: #fff8e1;">
                    <h3 style="color: #f57c00;">⚠️ Dane promocji niedostępne</h3>
                    <p>Nie udało się pobrać danych o potencjale wyróżnień dla tej oferty.</p>
                </div>
            `;
        }



        // Sekcja monitorowania cen (tylko jeśli dostępne)
        if (dataResults.priceMonitorData && filteredEntries.length > 0) {
            modalHTML += `
                <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;">
                    <h3>💰 Monitorowanie cen:</h3>
                    ${filteredEntries.map(entry =>
                        `<div style="margin-bottom: 10px;">
                            <p>${formatDate(entry.priceChange)}: Stara cena: <strong>${formatCurrency(entry.oldPrice)}</strong> | Nowa cena: <strong>${formatCurrency(entry.newPrice)}</strong></p>
                        </div>`
                    ).join('')}
                    <button id="chart-button" style="margin-top: 10px; padding: 10px 15px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer;">
                        Pokaż wykres
                    </button>
                    <canvas id="price-chart" style="display: none; margin-top: 15px;"></canvas>
                </div>
            `;
        } else if (dataResults.priceMonitorData === null) {
            modalHTML += `
                <div style="border: 1px solid #ffa500; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(255,165,0,0.1); margin-bottom: 20px; background-color: #fff8e1;">
                    <h3 style="color: #f57c00;">⚠️ Dane monitorowania cen niedostępne</h3>
                    <p>Nie udało się pobrać danych o zmianach cen dla tej oferty.</p>
                </div>
            `;
        } else {
            modalHTML += `
                <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;">
                    <h3>💰 Monitorowanie cen:</h3>
                    <p>Brak danych o cenach dla tego ID.</p>
                </div>
            `;
        }

        // Sekcja słów kluczowych (tylko jeśli dostępne)
        if (dataResults.keywordsData && dataResults.keywordsData.result && dataResults.keywordsData.result.entries) {
            const keywords = dataResults.keywordsData.result.entries
                .filter(entry => entry.saleParticipation && entry.saleParticipation.sale > 0.3)
                .sort((a, b) => b.saleParticipation.sale - a.saleParticipation.sale);

            if (keywords.length > 0) {
                modalHTML += `
                    <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;">
                        <h3>🔑 Słowa kluczowe</h3>
                        <div style="margin-bottom: 15px;">
                            <label style="margin-right: 15px;">
                                <input type="radio" name="keyword-filter" value="2" checked> 2+ znaki
                            </label>
                            <label>
                                <input type="radio" name="keyword-filter" value="3"> 3+ znaki
                            </label>
                        </div>
                        <div id="keywords-container">
                            <div style="display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 2px solid #007bff; font-weight: bold; background-color: #f8f9fa;">
                                <span>Słowo kluczowe</span>
                                <span>Udział</span>
                            </div>
                            <div id="keywords-list">
                                ${keywords.slice(0, 5).map(keyword => `
                                    <div style="display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid #eee;">
                                        <span style="font-weight: bold;">${keyword.keyword}</span>
                                        <span style="color: #007bff;">${(keyword.saleParticipation.sale * 100).toFixed(1)}%</span>
                                    </div>
                                `).join('')}
                                ${keywords.length > 5 ? `
                                    <div id="all-keywords" style="display: none;">
                                        ${keywords.slice(5).map(keyword => `
                                            <div style="display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid #eee;">
                                                <span style="font-weight: bold;">${keyword.keyword}</span>
                                                <span style="color: #007bff;">${(keyword.saleParticipation.sale * 100).toFixed(1)}%</span>
                                            </div>
                                        `).join('')}
                                    </div>
                                    <button id="show-more-keywords" style="margin-top: 10px; padding: 8px 15px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;">
                                        Pokaż więcej (${keywords.length - 5} więcej)
                                    </button>
                                ` : ''}
                            </div>
                        </div>
                    </div>
                `;
            } else {
                modalHTML += `
                    <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;">
                        <h3>🔑 Słowa kluczowe</h3>
                        <p>Brak słów kluczowych z udziałem powyżej 30%.</p>
                    </div>
                `;
            }
        } else if (dataResults.keywordsData === null) {
            modalHTML += `
                <div style="border: 1px solid #ffa500; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(255,165,0,0.1); margin-bottom: 20px; background-color: #fff8e1;">
                    <h3 style="color: #f57c00;">⚠️ Dane słów kluczowych niedostępne</h3>
                    <p>Nie udało się pobrać danych o słowach kluczowych dla tej oferty.</p>
                </div>
            `;
        }


        // Sekcja danych konwersji (tylko jeśli dostępne)
        if (dataResults.conversionData && conversionData.length > 0) {
            modalHTML += `
                <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;" class="conversion">
                    <h3>🔄 Dane konwersji:</h3>
                    ${conversionData.map((data, index) => `
                        <div style="margin-bottom: 10px;" class="original-conversion">
                            <p>Transakcje: <strong>${data.transactions}</strong>
                                <span style="display: none;" class="transaction-diff ${calculateDiffClass(calculateProportionPercentage(totalTransactions, data.transactions))}">
                                    (${calculateProportionPercentage(totalTransactions, data.transactions)}% wszystkich transakcji)
                                </span>
                                <span style="display: none;" class="successful-transaction-diff ${calculateDiffClass(calculateProportionPercentage(totalSuccessfulTransactions, data.transactions))}">
                                    (${calculateProportionPercentage(totalSuccessfulTransactions, data.transactions)}% wszystkich transakcji)
                                </span>
                            </p>
                            <p>Średnia liczba sprzedanych sztuk: <strong>${data.averageSoldItems}</strong>
                                <span style="display: none;" class="average-sold-items-diff ${calculateDiffClass(calculatePercentageDiff(data.averageSoldItems, averageSoldItems.toFixed(2)))}">
                                    (${calculatePercentageDiff(data.averageSoldItems, averageSoldItems.toFixed(2))}%)
                                </span>
                                <span style="display: none;" class="average-sold-items-successful-diff ${calculateDiffClass(calculatePercentageDiff(data.averageSoldItems, averageSuccessfulSoldItems.toFixed(2)))}">
                                    (${calculatePercentageDiff(data.averageSoldItems, averageSuccessfulSoldItems.toFixed(2))}%)
                                </span>
                            </p>
                            <p>Liczba odsłon: <strong>${data.viewsCount}</strong>
                                <span style="display: none;" class="views-count-diff ${calculateDiffClass(calculatePercentageDiff(data.viewsCount, averageViewsCount.toFixed(2)))}">
                                    (${calculateProportionPercentage(totalViewsCount.toFixed(2), data.viewsCount)}% wszystkich odsłon)
                                </span>
                                <span style="display: none;" class="views-count-successful-diff ${calculateDiffClass(calculatePercentageDiff(data.viewsCount, averageSuccessfulViewsCount.toFixed(2)))}">
                                    (${calculateProportionPercentage(SccessfulViewsCount, data.viewsCount)}% wszystkich odsłon)
                                </span>
                            </p>
                            <p>Współczynnik konwersji: <strong>${(data.conversion * 100).toFixed(2)}%</strong>
                                <span style="display: none;" class="conversion-diff ${calculateDiffClass(calculatePointsDifference((data.conversion * 100).toFixed(2), (averageConversion * 100).toFixed(2)))}">
                                    (${calculatePointsDifference((data.conversion * 100).toFixed(2), (averageConversion * 100).toFixed(2))} pkt %)
                                </span>
                                <span style="display: none;" class="successful-conversion-diff ${calculateDiffClass(calculatePointsDifference((data.conversion * 100).toFixed(2), (averageSuccessfulConversion * 100).toFixed(2)))}">
                                    (${calculatePointsDifference((data.conversion * 100).toFixed(2), (averageSuccessfulConversion * 100).toFixed(2))} pkt %)
                                </span>
                            </p>
                            <p>Dodania do ulubionych: <strong>${data.favoriteAdditionsCount}</strong></p>
                            <p>Dodania do koszyka: <strong>${data.cartAdditionsCount}</strong></p>
                            <button class="show-total-stats" data-index="${index}" style="margin-top: 10px;">Pokaż całe statystyki</button>
                            <button class="show-successful-stats" data-index="${index}" style="margin-top: 10px;">Pokaż udane transakcje</button>
                            <div id="more-info-${index}" style="display: none; margin-top: 10px;">
                                <div class="total-stats" style="display: none;">
                                    <h3>Statystyki ofert które miały wizyty</h3>
                                    <p>Średnia liczba sprzedanych sztuk: <strong>${averageSoldItems.toFixed(2)}</strong></p>
                                    <p>Wszystkich transakcji: <strong>${totalTransactions}</strong></p>
                                    <p>Średnia liczba transakcji: <strong>${averageTransactions.toFixed(2)}</strong></p>
                                    <p>Liczba wyświetleń: <strong>${totalViewsCount}</strong></p>
                                    <p>Średnia konwersja: <strong>${(averageConversion * 100).toFixed(2)}%</strong></p>
                                    <p>Średnia liczba odsłon: <strong>${averageViewsCount.toFixed(2)}</strong></p>
                                </div>
                                <div class="successful-stats" style="display: none;">
                                    <h3>Statystyki ofert które miały transakcje</h3>
                                    <p>Średnia liczba sprzedanych sztuk: <strong>${averageSuccessfulSoldItems.toFixed(2)}</strong></p>
                                    <p>Wszystkich transakcji: <strong>${totalSuccessfulTransactions}</strong></p>
                                    <p>Średnia liczba transakcji: <strong>${averageSuccessfulTransactions.toFixed(2)}</strong></p>
                                    <p>Liczba wyświetleń: <strong>${SccessfulViewsCount}</strong></p>
                                    <p>Średnia konwersja: <strong>${(averageSuccessfulConversion * 100).toFixed(2)}%</strong></p>
                                    <p>Średnia liczba odsłon: <strong>${averageSuccessfulViewsCount.toFixed(2)}</strong></p>
                                </div>
                            </div>
                        </div>
                    `).join('')}
                    <button id="showEntriesBtn">Pokaż statystyki ofert</button>
                </div>
            `;
        } else if (dataResults.conversionData === null) {
            modalHTML += `
                <div style="border: 1px solid #ffa500; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(255,165,0,0.1); margin-bottom: 20px; background-color: #fff8e1;">
                    <h3 style="color: #f57c00;">⚠️ Dane konwersji niedostępne</h3>
                    <p>Nie udało się pobrać danych konwersji dla tej oferty.</p>
                </div>
            `;
        } else {
            modalHTML += `
                <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;">
                    <h3>Dane konwersji:</h3>
                    <p>Brak danych konwersji.</p>
                </div>
            `;
        }

        // Wstawiamy HTML do modala (zachowując progress bar)
        const progressBar = document.getElementById('fetch-progress');
        const spinner = document.querySelector("#loading-spinner");

        // Ukrywamy spinner
        if (spinner) spinner.style.display = 'none';

        // Aktualizujemy przycisk retry po zakończeniu wszystkich fetchów
        updateRetryButton();

        // Dodajemy dane po progress barze
        if (progressBar) {
            progressBar.insertAdjacentHTML('afterend', modalHTML);
        } else {
            // Fallback - jeśli progress bar nie istnieje, dodajemy wszystko
            modalContent.innerHTML = modalHTML;
        }

        // Obsługa przycisków (tylko jeśli dane konwersji są dostępne)
        if (conversionData.length > 0) {
            conversionData.forEach((data, index) => {
                // Wybierz przycisk do pokazywania całych statystyk
                const totalStatsButton = document.querySelector(`.show-total-stats[data-index="${index}"]`);
                const successfulStatsButton = document.querySelector(`.show-successful-stats[data-index="${index}"]`);

                if (totalStatsButton && successfulStatsButton) {
                    totalStatsButton.addEventListener('click', function() {
                        const moreInfoDiv = document.getElementById(`more-info-${index}`);
                        moreInfoDiv.style.display = 'block';
                        moreInfoDiv.querySelector('.total-stats').style.display = 'block';
                        totalStatsButton.style.backgroundColor = '#ff5a00';
                        successfulStatsButton.style.backgroundColor = '#007bff';

                        moreInfoDiv.querySelector('.successful-stats').style.display = 'none'; // Ukryj udane statystyki

                        // Uzyskaj element <span> z różnicą
                        const transactionDiffSpan = document.querySelector(`.transaction-diff`);
                        const averageSoldItemsDiffSpan = document.querySelector(`.average-sold-items-diff`);
                        const viewsCountDiffSpan = document.querySelector(`.views-count-diff`);
                        const conversionDiffSpan = document.querySelector(`.conversion-diff`);

                        // Uczyń <span> widocznymi
                        if (transactionDiffSpan) transactionDiffSpan.style.display = 'inline';
                        if (averageSoldItemsDiffSpan) averageSoldItemsDiffSpan.style.display = 'inline';
                        if (viewsCountDiffSpan) viewsCountDiffSpan.style.display = 'inline';
                        if (conversionDiffSpan) conversionDiffSpan.style.display = 'inline';

                        // Dodajemy const dla drugich spanów
                        const successfulTransactionDiffSpan = document.querySelector(`.successful-transaction-diff`);
                        const averageSoldItemsSuccessfulDiffSpan = document.querySelector(`.average-sold-items-successful-diff`);
                        const viewsCountSuccessfulDiffSpan = document.querySelector(`.views-count-successful-diff`);
                        const successfulConversionDiffSpan = document.querySelector(`.successful-conversion-diff`);

                        if (successfulTransactionDiffSpan) successfulTransactionDiffSpan.style.display = 'none';
                        if (averageSoldItemsSuccessfulDiffSpan) averageSoldItemsSuccessfulDiffSpan.style.display = 'none';
                        if (viewsCountSuccessfulDiffSpan) viewsCountSuccessfulDiffSpan.style.display = 'none';
                        if (successfulConversionDiffSpan) successfulConversionDiffSpan.style.display = 'none';
                    });

                    successfulStatsButton.addEventListener('click', function() {
                        const moreInfoDiv = document.getElementById(`more-info-${index}`);
                        moreInfoDiv.style.display = 'block';
                        moreInfoDiv.querySelector('.total-stats').style.display = 'none'; // Ukryj całe statystyki
                        moreInfoDiv.querySelector('.successful-stats').style.display = 'block';
                        successfulStatsButton.style.backgroundColor = '#ff5a00';
                        totalStatsButton.style.backgroundColor = '#007bff';

                        // Uzyskaj element <span> z różnicą
                        const transactionDiffSpan = document.querySelector(`.transaction-diff`);
                        const averageSoldItemsDiffSpan = document.querySelector(`.average-sold-items-diff`);
                        const viewsCountDiffSpan = document.querySelector(`.views-count-diff`);
                        const conversionDiffSpan = document.querySelector(`.conversion-diff`);

                        // Uczyń <span> niewidocznymi
                        if (transactionDiffSpan) transactionDiffSpan.style.display = 'none';
                        if (averageSoldItemsDiffSpan) averageSoldItemsDiffSpan.style.display = 'none';
                        if (viewsCountDiffSpan) viewsCountDiffSpan.style.display = 'none';
                        if (conversionDiffSpan) conversionDiffSpan.style.display = 'none';

                        // Dodajemy const dla drugich spanów
                        const successfulTransactionDiffSpan = document.querySelector(`.successful-transaction-diff`);
                        const averageSoldItemsSuccessfulDiffSpan = document.querySelector(`.average-sold-items-successful-diff`);
                        const viewsCountSuccessfulDiffSpan = document.querySelector(`.views-count-successful-diff`);
                        const successfulConversionDiffSpan = document.querySelector(`.successful-conversion-diff`);

                        // Uczyń <span> widocznymi
                        if (successfulTransactionDiffSpan) successfulTransactionDiffSpan.style.display = 'inline';
                        if (averageSoldItemsSuccessfulDiffSpan) averageSoldItemsSuccessfulDiffSpan.style.display = 'inline';
                        if (viewsCountSuccessfulDiffSpan) viewsCountSuccessfulDiffSpan.style.display = 'inline';
                        if (successfulConversionDiffSpan) successfulConversionDiffSpan.style.display = 'inline';
                    });
                }
            });
        }

        // Generujemy wykres na podstawie dostępnych danych (tylko jeśli są dane)
        if (filteredEntries.length > 0) {
            generatePriceChart(filteredEntries);

            // Dodajemy event listener do przycisku "Wykres"
            const chartButton = document.querySelector("#chart-button");
            if (chartButton) {
                chartButton.addEventListener("click", function() {
                    const canvas = document.getElementById('price-chart');
                    if (canvas) {
                        // Zmieniamy widoczność canvasu
                        if (canvas.style.display === "none") {
                            canvas.style.display = "block"; // Pokaż wykres
                        } else {
                            canvas.style.display = "none"; // Ukryj wykres
                        }
                    }
                });
            }
        }

        // Dodajemy event listener do przycisku "Pokaż wszystkie wpisy"
        const showEntriesBtn = document.querySelector("#showEntriesBtn");
        if (showEntriesBtn && wholeConversion.length > 0) {
            showEntriesBtn.addEventListener("click", function() {
                openEntriesModal(wholeConversion); // Użyj danych z wholeConversion
            });
        }

        // Dodajemy event listenery dla słów kluczowych
        if (dataResults.keywordsData && dataResults.keywordsData.result && dataResults.keywordsData.result.entries) {
            const keywords = dataResults.keywordsData.result.entries
                .filter(entry => entry.saleParticipation && entry.saleParticipation.sale > 0.3)
                .sort((a, b) => b.saleParticipation.sale - a.saleParticipation.sale);

            // Event listener dla filtrów długości słów
            const filterRadios = document.querySelectorAll('input[name="keyword-filter"]');
            filterRadios.forEach(radio => {
                radio.addEventListener('change', function() {
                    const minLength = parseInt(this.value);
                    const filteredKeywords = keywords.filter(keyword => keyword.keyword.length >= minLength);

                    const keywordsList = document.getElementById('keywords-list');
                    const allKeywords = document.getElementById('all-keywords');
                    const showMoreBtn = document.getElementById('show-more-keywords');

                    if (keywordsList) {
                        keywordsList.innerHTML = filteredKeywords.slice(0, 5).map(keyword => `
                            <div style="display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid #eee;">
                                <span style="font-weight: bold;">${keyword.keyword}</span>
                                <span style="color: #007bff;">${(keyword.saleParticipation.sale * 100).toFixed(1)}%</span>
                            </div>
                        `).join('') + (filteredKeywords.length > 5 ? `
                            <div id="all-keywords" style="display: none;">
                                ${filteredKeywords.slice(5).map(keyword => `
                                    <div style="display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid #eee;">
                                        <span style="font-weight: bold;">${keyword.keyword}</span>
                                        <span style="color: #007bff;">${(keyword.saleParticipation.sale * 100).toFixed(1)}%</span>
                                    </div>
                                `).join('')}
                            </div>
                            <button id="show-more-keywords" style="margin-top: 10px; padding: 8px 15px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer;">
                                Pokaż więcej (${filteredKeywords.length - 5} więcej)
                            </button>
                        ` : '');
                    }
                });
            });

            // Event listener dla przycisku "Pokaż więcej" - delegacja zdarzeń
            document.addEventListener('click', function(e) {
                if (e.target && e.target.id === 'show-more-keywords') {
                    const allKeywords = document.getElementById('all-keywords');
                    if (allKeywords) {
                        if (allKeywords.style.display === 'none') {
                            allKeywords.style.display = 'block';
                            e.target.textContent = 'Pokaż mniej';
                        } else {
                            allKeywords.style.display = 'none';
                            e.target.textContent = `Pokaż więcej (${keywords.length - 5} więcej)`;
                        }
                    }
                }
            });
        }

        // Dodajemy event listener do przycisku retry
        const retryButton = document.getElementById('retry-failed-fetches');
        if (retryButton) {
            retryButton.addEventListener('click', async function() {
                retryButton.disabled = true;
                retryButton.textContent = '🔄 Ponawianie...';

                // Ponów tylko nieudane fetche
                for (const fetchName of dataResults.failedFetches) {
                    await retryFailedFetch(fetchName, auctionID, title, startDate, endDate);
                }

                // Po udanym retry, odśwież całą zawartość modala
                if (dataResults.failedFetches.length === 0) {
                    // Odśwież zawartość modala z aktualnymi danymi
                    refreshModalContent(auctionID, title, startDate, endDate);
                }

                retryButton.disabled = false;
                updateRetryButton();
            });
        }



    // Funkcja do odświeżania zawartości modala po retry
    function refreshModalContent(auctionID, title, startDate, endDate) {
        // Usuń starą zawartość modala (zachowując progress bar)
        const progressBar = document.getElementById('fetch-progress');
        if (progressBar) {
            // Usuń wszystkie elementy po progress barze
            let nextElement = progressBar.nextElementSibling;
            while (nextElement) {
                const toRemove = nextElement;
                nextElement = nextElement.nextElementSibling;
                toRemove.remove();
            }
        }

        // Wywołaj ponownie generowanie zawartości modala
        generateModalContent(auctionID, title, startDate, endDate);
    }

    // Funkcja do generowania zawartości modala (uproszczona - tylko odświeża sekcję danych sprzedaży)
    function generateModalContent(auctionID, title, startDate, endDate) {
        // Wyodrębniamy dane sprzedaży
        var totalSale = 0, todaySale = 0, yesterdaySale = 0;
        var offerStartDate = '', startingQuantity = 0, currentQuantity = 0, seller = '';
        var productid = [], filtProductId = null;

        if (dataResults.salesData) {
            const salesData = dataResults.salesData.result;
            totalSale = salesData.saleInfo?.totalSale || 0;
            todaySale = salesData.saleInfo?.todaySale || 0;
            yesterdaySale = salesData.saleInfo?.yesterdaySale || 0;
            offerStartDate = salesData.overallItemInfo?.startDate || '';
            startingQuantity = salesData.startingQuantity || 0;
            currentQuantity = salesData.currentQuantity || 0;
            seller = salesData.seller?.name || '';
            productid = salesData.pmdProductIds || [];
            if (productid.length > 0) filtProductId = productid[0];
        }

        // Generujemy tylko sekcję danych sprzedaży
        let salesHTML = '';

        if (dataResults.salesData) {
            salesHTML = `
                <div style="border: 1px solid #ddd; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 20px;" class="conversion">
                    <h3>Wartość sprzedaży:</h3>
                    <p><strong>Sprzedaż w wybranym okresie:</strong> ${formatCurrency(totalSale)}</p>
                    <p><strong>Sprzedaż dzisiaj:</strong> ${formatCurrency(todaySale)}</p>
                    <p><strong>Sprzedaż wczoraj:</strong> ${formatCurrency(yesterdaySale)}</p>
                    <br>
                    <h4 class="section-title">Dodatkowe informacje</h4>
                    <p><strong>Tytuł:</strong> ${dataResults.salesData.result.itemName || 'Brak danych'} (${(dataResults.salesData.result.itemName || '').length} znaków)</p>
                    <p><strong>Data rozpoczęcia oferty:</strong> ${formatDaty(offerStartDate)}</p>
                    <p><strong>Początkowa ilość:</strong> ${startingQuantity}</p>
                    <p><strong>Obecna ilość:</strong> ${currentQuantity}</p>
                    <p><strong>Sprzedawca:</strong> ${seller}</p>
                    ${filtProductId ? `<a class="product-btn" href="https://allegro.pl/moje-allegro/sprzedaz/produkt/zglos-blad/${filtProductId}" target="_blank">Sprawdź / zgłoś produkt</a>` : ''}
                </div>
            `;
        } else {
            salesHTML = `
                <div style="border: 1px solid #ffa500; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(255,165,0,0.1); margin-bottom: 20px; background-color: #fff8e1;">
                    <h3 style="color: #f57c00;">⚠️ Dane sprzedaży niedostępne</h3>
                    <p>Nie udało się pobrać danych sprzedażowych dla tej oferty.</p>
                </div>
            `;
        }

        // Znajdź i zastąp sekcję danych sprzedaży
        const progressBar = document.getElementById('fetch-progress');
        if (progressBar) {
            // Znajdź pierwszą sekcję po progress barze (powinna być sekcją danych sprzedaży)
            const firstSection = progressBar.nextElementSibling;
            if (firstSection && firstSection.classList.contains('conversion')) {
                firstSection.outerHTML = salesHTML;
            } else {
                // Jeśli nie ma sekcji danych sprzedaży, dodaj ją
                progressBar.insertAdjacentHTML('afterend', salesHTML);
            }
        }
    }

    // Funkcja do ponawiania nieudanych fetchów
    async function retryFailedFetch(fetchName, auctionID, title, startDate, endDate) {
        updateFetchStatus(fetchName, 'loading', 'Ponawianie...');

        try {
            switch (fetchName) {
                case 'deals':
                    await retryDealsFetch(auctionID, startDate, endDate);
                    break;
                case 'prices':
                    await retryPricesFetch(title, startDate, endDate);
                    break;
                case 'conversion':
                    await retryConversionFetch(auctionID, startDate, endDate);
                    break;
                case 'product':
                    await retryProductFetch(auctionID, startDate, endDate);
                    break;
                case 'promotion':
                    await retryPromotionFetch(startDate, endDate);
                    break;
                case 'keywords':
                    await retryKeywordsFetch(auctionID, startDate, endDate);
                    break;
            }
        } catch (error) {
            updateFetchStatus(fetchName, 'error', `Błąd: ${error.message}`);
            console.error(`Błąd ponawiania ${fetchName}:`, error);
        }
    }

    // Funkcje retry dla każdego typu fetcha
    async function retryDealsFetch(auctionID, startDate, endDate) {
        const response = await fetch("https://edge.allegro.pl/analytics/auction/deals", {
            "credentials": "include",
            "headers": {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
                "Accept": "application/vnd.allegro.internal.v1+json",
                "Accept-Language": "pl-PL",
                "Content-Type": "application/vnd.allegro.internal.v1+json",
                "Sec-Fetch-Dest": "empty",
                "Sec-Fetch-Mode": "cors",
                "Sec-Fetch-Site": "same-site",
                "Priority": "u=0",
                "Pragma": "no-cache",
                "Cache-Control": "no-cache"
            },
            "referrer": "https://allegro.pl/",
            "body": JSON.stringify({
                "includePhrasesMode": "OfferOrProduct",
                "excludePhrasesMode": "OfferOrProduct",
                "auctionId": auctionID,
                "sellerIds": [],
                "marketplaceIds": ["allegro-pl"],
                "startDate": startDate,
                "endDate": endDate,
                "startDateTime": startDate + "T00:00:00.000Z",
                "endDateTime": endDate + "T23:59:59.999Z",
                "reportCode": "TOP7D"
            }),
            "method": "POST",
            "mode": "cors"
        });

        if (response.ok) {
            const data = await response.json();
            if (data && data.result && data.result.saleInfo) {
                dataResults.salesData = data;
                updateFetchStatus('deals', 'success', 'Pobrano pomyślnie');
            } else {
                updateFetchStatus('deals', 'error', 'Nieprawidłowa struktura danych');
            }
        } else {
            updateFetchStatus('deals', 'error', `Błąd HTTP: ${response.status}`);
        }
    }

    async function retryPricesFetch(title, startDate, endDate) {
        const response = await fetch("https://edge.allegro.pl/analytics/reports/auctions/pricemonitor/pricejournal", {
            "credentials": "include",
            "headers": {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
                "Accept": "application/vnd.allegro.internal.v1+json",
                "Accept-Language": "pl-PL",
                "Content-Type": "application/vnd.allegro.internal.v1+json",
                "Priority": "u=4",
                "Pragma": "no-cache",
                "Cache-Control": "no-cache",
                "Sec-Fetch-Dest": "empty",
                "Sec-Fetch-Mode": "cors",
                "Sec-Fetch-Site": "same-site"
            },
            "referrer": "https://allegro.pl/",
            "body": JSON.stringify({
                "includePhrases": title,
                "includePhrasesMode": "OfferOrProduct",
                "excludePhrasesMode": "OfferOrProduct",
                "auctionType": 1,
                "sellerIds": [],
                "skip": 0,
                "take": 1000,
                "marketplaceIds": ["allegro-pl"],
                "startDate": startDate + "T00:00:00.000Z",
                "endDate": endDate + "T00:00:00.000Z",
                "startDateTime": startDate + "T00:00:00.000Z",
                "endDateTime": endDate + "T23:59:59.999Z",
                "reportCode": "TOP7D"
            }),
            "method": "POST",
            "mode": "cors"
        });

        if (response.ok) {
            const data = await response.json();
            if (data && data.entries) {
                dataResults.priceMonitorData = data;
                updateFetchStatus('prices', 'success', 'Pobrano pomyślnie');
            } else {
                updateFetchStatus('prices', 'error', 'Nieprawidłowa struktura danych');
            }
        } else {
            updateFetchStatus('prices', 'error', `Błąd HTTP: ${response.status}`);
        }
    }

    async function retryConversionFetch(auctionID, startDate, endDate) {
        if (!dataResults.salesData || !dataResults.salesData.result.pmdProductIds || dataResults.salesData.result.pmdProductIds.length === 0) {
            updateFetchStatus('conversion', 'skipped', 'Brak productid');
            return;
        }

        const productid = dataResults.salesData.result.pmdProductIds[0];
        const response = await fetch("https://edge.allegro.pl/analytics/reports/sale/byconversion", {
            "credentials": "include",
            "headers": {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0",
                "Accept": "application/vnd.allegro.internal.v1+json",
                "Accept-Language": "pl-PL",
                "Content-Type": "application/vnd.allegro.internal.v1+json",
                "Sec-Fetch-Dest": "empty",
                "Sec-Fetch-Mode": "cors",
                "Sec-Fetch-Site": "same-site",
                "Priority": "u=0",
                "Pragma": "no-cache",
                "Cache-Control": "no-cache"
            },
            "referrer": "https://allegro.pl/",
            "body": JSON.stringify({
                "includePhrases": productid,
                "includePhrasesMode": "AnyId",
                "excludePhrasesMode": "AnyId",
                "sellerIds": [],
                "includeCancelledAndReturned": true,
                "skip": 0,
                "take": 1000,
                "marketplaceIds": ["allegro-pl"],
                "startDate": startDate + "T00:00:00.000Z",
                "endDate": endDate + "T00:00:00.000Z",
                "startDateTime": startDate + "T00:00:00.000Z",
                "endDateTime": endDate + "T23:59:59.999Z",
                "reportCode": "TOP7D"
            }),
            "method": "POST",
            "mode": "cors"
        });

        if (response.ok) {
            const data = await response.json();
            if (data && data.result && data.result.entries) {
                dataResults.conversionData = data;
                updateFetchStatus('conversion', 'success', 'Pobrano pomyślnie');
            } else {
                updateFetchStatus('conversion', 'error', 'Nieprawidłowa struktura danych');
            }
        } else {
            updateFetchStatus('conversion', 'error', `Błąd HTTP: ${response.status}`);
        }
    }

    async function retryProductFetch(auctionID, startDate, endDate) {
        if (!dataResults.conversionData || !dataResults.conversionData.result || !dataResults.conversionData.result.entries) {
            updateFetchStatus('product', 'skipped', 'Brak danych konwersji');
            return;
        }

        const conversionDataAfter = dataResults.conversionData.result.entries.filter(entry => entry.ids.includes(auctionID));
        const pmdProductName = conversionDataAfter.length ? conversionDataAfter[0].pmdProductName : null;

        if (!pmdProductName) {
            updateFetchStatus('product', 'skipped', 'Brak pmdProductName');
            return;
        }

        const response = await fetch("https://edge.allegro.pl/analytics/reports/sale/byconversion", {
            "credentials": "include",
            "headers": {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0",
                "Accept": "application/vnd.allegro.internal.v1+json",
                "Accept-Language": "pl-PL",
                "Content-Type": "application/vnd.allegro.internal.v1+json",
                "Sec-Fetch-Dest": "empty",
                "Sec-Fetch-Mode": "cors",
                "Sec-Fetch-Site": "same-site"
            },
            "referrer": "https://allegro.pl/",
            "body": JSON.stringify({
                "includePhrases": pmdProductName,
                "includePhrasesMode": "Product",
                "excludePhrasesMode": "Product",
                "auctionType": 1,
                "sellerIds": [],
                "skip": 0,
                "take": 1000,
                "marketplaceIds": ["allegro-pl"],
                "startDate": startDate + "T00:00:00.000Z",
                "endDate": endDate + "T00:00:00.000Z",
                "startDateTime": startDate + "T00:00:00.000Z",
                "endDateTime": endDate + "T23:59:59.999Z",
                "reportCode": "TOP7D"
            }),
            "method": "POST",
            "mode": "cors"
        });

        if (response.ok) {
            const data = await response.json();
            if (data && data.result) {
                dataResults.conversionDataExtended = data;
                updateFetchStatus('product', 'success', 'Pobrano pomyślnie');
            } else {
                updateFetchStatus('product', 'error', 'Nieprawidłowa struktura danych');
            }
        } else {
            updateFetchStatus('product', 'error', `Błąd HTTP: ${response.status}`);
        }
    }

    async function retryPromotionFetch(startDate, endDate) {
        const response = await fetch("https://edge.allegro.pl/analytics/reports/sale/bypromotion", {
            "credentials": "include",
            "headers": {
                "Accept": "application/vnd.allegro.internal.v1+json",
                "Accept-Language": "pl-PL",
                "Content-Type": "application/vnd.allegro.internal.v1+json",
                "Priority": "u=1, i",
                "Sec-CH-UA": "\"Google Chrome\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"",
                "Sec-CH-UA-Mobile": "?0",
                "Sec-CH-UA-Platform": "\"Windows\"",
                "Sec-Fetch-Dest": "empty",
                "Sec-Fetch-Mode": "cors",
                "Sec-Fetch-Site": "same-site"
            },
            "referrer": "https://allegro.pl/",
            "referrerPolicy": "strict-origin-when-cross-origin",
            "body": JSON.stringify({
                "includePhrases": "2c3f3821-4408-42b8-9ce3-94103d84715e",
                "includePhrasesMode": "AnyId",
                "sellerIds": [],
                "marketplaceIds": ["allegro-pl"],
                "startDate": startDate + "T00:00:00.000Z",
                "endDate": endDate + "T00:00:00.000Z",
                "startDateTime": startDate + "T02:00:00.000Z",
                "endDateTime": endDate + "T23:53:00.000Z",
                "reportCode": "LASTFULL7DAYS"
            }),
            "method": "POST",
            "mode": "cors"
        });

        if (response.ok) {
            const data = await response.json();
            if (data && data.result && data.result.entries) {
                dataResults.promotionData = data;
                updateFetchStatus('promotion', 'success', 'Pobrano pomyślnie');
            } else {
                updateFetchStatus('promotion', 'error', 'Nieprawidłowa struktura danych');
            }
        } else {
            updateFetchStatus('promotion', 'error', `Błąd HTTP: ${response.status}`);
        }
    }

    async function retryKeywordsFetch(auctionID, startDate, endDate) {
        if (!dataResults.salesData || !dataResults.salesData.result.pmdProductIds || dataResults.salesData.result.pmdProductIds.length === 0) {
            updateFetchStatus('keywords', 'skipped', 'Niemożliwe');
            return;
        }

        const productId = dataResults.salesData.result.pmdProductIds[0];

        const response = await fetch("https://edge.allegro.pl/analytics/reports/sale/bykeyword", {
            "credentials": "include",
            "headers": {
                "Accept": "application/vnd.allegro.internal.v1+json",
                "Accept-Language": "pl-PL",
                "Content-Type": "application/vnd.allegro.internal.v1+json",
                "Priority": "u=1, i",
                "Sec-CH-UA": "\"Chromium\";v=\"140\", \"Not=A?Brand\";v=\"24\", \"Google Chrome\";v=\"140\"",
                "Sec-CH-UA-Mobile": "?0",
                "Sec-CH-UA-Platform": "\"Windows\"",
                "Sec-Fetch-Dest": "empty",
                "Sec-Fetch-Mode": "cors",
                "Sec-Fetch-Site": "same-site"
            },
            "referrer": "https://allegro.pl/",
            "body": JSON.stringify({
                "includePhrases": productId,
                "includePhrasesMode": "AnyId",
                "excludePhrasesMode": "OfferOrProduct",
                "auctionId": auctionID,
                "skip": 0,
                "take": 1000,
                "marketplaceIds": ["allegro-pl"],
                "startDate": startDate + "T00:00:00.000Z",
                "endDate": endDate + "T00:00:00.000Z",
                "startDateTime": startDate + "T02:00:00.000Z",
                "endDateTime": endDate + "T04:38:00.000Z",
                "reportCode": "LASTFULL7DAYS"
            }),
            "method": "POST",
            "mode": "cors"
        });

        if (response.ok) {
            const data = await response.json();
            if (data && data.result && data.result.entries) {
                dataResults.keywordsData = data;
                updateFetchStatus('keywords', 'success', 'Pobrano pomyślnie');
            } else {
                updateFetchStatus('keywords', 'error', 'Nieprawidłowa struktura danych');
            }
        } else {
            updateFetchStatus('keywords', 'error', `Błąd HTTP: ${response.status}`);
        }
    }

// Funkcja do otwierania modalnego okna z tabelą
function openEntriesModal(entries) {
    // Sprawdzenie, czy entries są dostępne
    if (!entries || entries.length === 0) {
        alert("Brak danych do wyświetlenia.");
        return;
    }

    // Tworzenie zawartości tabeli
    const tableRows = entries.map(entry => `
        <tr>
<td style="text-align: center;">
    <a href="https://allegro.pl/oferta/${entry.ids.join(', ')}" target="_blank">${entry.ids.join(', ')}</a>
</td>
<td style="text-align: center;">
    <a href="https://allegro.pl/uzytkownik/${entry.seller.name}" target="_blank">${entry.seller.name}</a>
</td>

            <td style="text-align: center;">${entry.transactions}</td>
            <td style="text-align: center;">${entry.averageSoldItems}</td>
            <td style="text-align: center;">${entry.viewsCount}</td>
            <td style="text-align: center;">${(entry.conversion * 100).toFixed(2)}%</td>
            <td style="text-align: center;">${entry.offerPrice.toFixed(2)} zł</td>
            <td style="text-align: center;">${entry.favoriteAdditionsCount}</td>
            <td style="text-align: center;">${entry.cartAdditionsCount}</td>
        </tr>
    `).join('');

    // Tworzenie modalnego okna
    const modalEntriesContent = `
        <div id="modal-entries" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.8); display: flex; justify-content: center; align-items: center; z-index: 10001;max-width:100%">
            <div style="background: white; padding: 30px; border-radius: 8px; width: 90%; max-width: 100%; overflow-y: auto; max-height: 80%; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);">
                <div style="display: flex; justify-content: space-between; align-items: center;">
                    <h2 style="margin-top: 0; text-align: center; color: #333;">Wszystkie oferty</h2>
                    <button id="closeEntriesModalBtn" style="padding: 10px 15px; background-color: #dc3545; color: white; border: none; border-radius: 5px; cursor: pointer;">Zamknij</button>
                </div>
                <table style="width: 100%; border-collapse: collapse; margin-top: 20px; font-family: Arial, sans-serif;">
                    <thead style="background-color: #007bff; color: white;">
                        <tr>
                            <th style="padding: 15px; text-align: center;">Oferty</th>
                            <th style="padding: 15px; text-align: center;">Sprzedawca</th>
                            <th style="padding: 15px; text-align: center;">Transakcji <span class="filter-icon" data-col="2">🔽</span></th>
                            <th style="padding: 15px; text-align: center;">Śr. sprzedanych sztuk <span class="filter-icon" data-col="3">🔽</span></th>
                            <th style="padding: 15px; text-align: center;">Odsłon <span class="filter-icon" data-col="4">🔽</span></th>
                            <th style="padding: 15px; text-align: center;">Konwersja <span class="filter-icon" data-col="5">🔽</span></th>
                            <th style="padding: 15px; text-align: center;">Cena <span class="filter-icon" data-col="6">🔽</span></th>
                            <th style="padding: 15px; text-align: center;">Dodanych do ulubionych <span class="filter-icon" data-col="7">🔽</span></th>
                            <th style="padding: 15px; text-align: center;">Dodanych do koszyka <span class="filter-icon" data-col="8">🔽</span></th>
                        </tr>
                    </thead>
                    <tbody id="entriesTableBody">
                        ${tableRows}
                    </tbody>
                </table>
            </div>
        </div>
    `;

    // Wstawiamy modal do body
    document.body.insertAdjacentHTML('beforeend', modalEntriesContent);

    // Dodajemy style do wierszy tabeli
    const style = document.createElement('style');
    style.textContent = `
        table {
            border-radius: 8px;
            overflow: hidden;
        }
        tbody tr:nth-child(even) {
            background-color: #f2f2f2; /* Jasnoszare tło dla parzystych wierszy */
        }
        tbody tr:hover {
            background-color: #e0e0e0; /* Jasnoszare tło przy najechaniu */
        }
        th, td {
            padding: 12px; /* Większe odstępy w komórkach */
            border-bottom: 1px solid #ddd; /* Dolna granica */
            text-align: center; /* Wyśrodkowanie tekstu */
        }
        th {
            font-weight: bold; /* Pogrubione nagłówki */
        }
        .filter-icon {
            cursor: pointer;
            font-size: 14px;
            margin-left: 5px;
            vertical-align: middle; /* Wyrównanie strzałki w pionie */
        }
        .ascending::before {
            content: '🔼'; /* Strzałka w górę */
        }
        .descending::before {
            content: '🔽'; /* Strzałka w dół */
        }
    `;
    document.head.appendChild(style);

    // Obsługa zamykania modalnego okna z tabelą
    document.getElementById('closeEntriesModalBtn').addEventListener('click', () => {
        const modal = document.getElementById('modal-entries');
        if (modal) {
            modal.remove(); // Usuwamy modal
        }
    });

    // Obsługa filtrowania/sortowania
    const filterIcons = document.querySelectorAll('.filter-icon');
    filterIcons.forEach(icon => {
        icon.addEventListener('click', () => {
            const colIndex = parseInt(icon.getAttribute('data-col'));
            const ascending = icon.classList.toggle('ascending'); // Ustalanie kierunku sortowania

            // Resetowanie kierunku sortowania dla pozostałych kolumn
            filterIcons.forEach(otherIcon => {
                if (otherIcon !== icon) {
                    otherIcon.classList.remove('ascending', 'descending');
                }
            });

            // Ustawianie kierunku sortowania
            if (ascending) {
                icon.classList.add('ascending');
            } else {
                icon.classList.add('descending');
            }

            const sortedEntries = [...entries].sort((a, b) => {
                let aValue, bValue;

                switch (colIndex) {
                    case 2: // Transakcji
                        aValue = a.transactions;
                        bValue = b.transactions;
                        break;
                    case 3: // Śr. sprzedanych sztuk
                        aValue = a.averageSoldItems;
                        bValue = b.averageSoldItems;
                        break;
                    case 4: // Odsłon
                        aValue = a.viewsCount;
                        bValue = b.viewsCount;
                        break;
                    case 5: // Konwersja
                        aValue = a.conversion;
                        bValue = b.conversion;
                        break;
                    case 6: // Cena
                        aValue = a.offerPrice;
                        bValue = b.offerPrice;
                        break;
                    case 7: // Dodanych do ulubionych
                        aValue = a.favoriteAdditionsCount;
                        bValue = b.favoriteAdditionsCount;
                        break;
                    case 8: // Dodanych do koszyka
                        aValue = a.cartAdditionsCount;
                        bValue = b.cartAdditionsCount;
                        break;
                    default:
                        return 0; // Nie sortuj, jeśli kolumna nie jest obsługiwana
                }

                return ascending ? (aValue - bValue) : (bValue - aValue);
            });

            // Uaktualniamy tabelę
            const newTableRows = sortedEntries.map(entry => `
                <tr>
<td style="text-align: center;">
    <a href="https://allegro.pl/oferta/${entry.ids.join(', ')}" target="_blank">${entry.ids.join(', ')}</a>
</td>
<td style="text-align: center;">
    <a href="https://allegro.pl/uzytkownik/${entry.seller.name}" target="_blank">${entry.seller.name}</a>
</td>

                    <td style="text-align: center;">${entry.transactions}</td>
                    <td style="text-align: center;">${entry.averageSoldItems}</td>
                    <td style="text-align: center;">${entry.viewsCount}</td>
                    <td style="text-align: center;">${(entry.conversion * 100).toFixed(2)}%</td>
                    <td style="text-align: center;">${entry.offerPrice.toFixed(2)} zł</td>
                    <td style="text-align: center;">${entry.favoriteAdditionsCount}</td>
                    <td style="text-align: center;">${entry.cartAdditionsCount}</td>
                </tr>
            `).join('');

            document.getElementById('entriesTableBody').innerHTML = newTableRows;
        });
    });
}
    } catch (error) {
        console.error("Wystąpił błąd podczas pobierania danych:", error);

        // Sprawdź czy wystąpił błąd 401
        const has401Error = dataResults.errors.some(errorMsg => errorMsg.includes('401'));
        const errorMessage = has401Error ?
            'Brak dostępu, zaloguj się na właściwe konto Analytics' :
            error.message;
        const errorDescription = has401Error ?
            'Zaloguj się na konto z dostępem do Analytics i spróbuj ponownie.' :
            'Sprawdź połączenie internetowe i spróbuj ponownie.';

        modalContent.innerHTML = `
            <h2 style="margin-top: 0;">Statystyki dla oferty ${auctionID}</h2>
            <div style="border: 1px solid #ff6b6b; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(255,107,107,0.1); margin-bottom: 20px; background-color: #ffe0e0;">
                <h3 style="color: #d63031; margin-top: 0;">❌ Błąd krytyczny</h3>
                <p style="color: #d63031;">Wystąpił błąd podczas pobierania danych: ${errorMessage}</p>
                <p>${errorDescription}</p>
            </div>
        `;
    } finally {
        // Spinner jest już ukrywany w głównej części funkcji
    }
}


function formatCurrency(amount) {
    return new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN' }).format(amount);
}



// Funkcja do generowania wykresu na podstawie zmian cen
// Funkcja do generowania wykresu na podstawie zmian cen
// Funkcja do generowania wykresu na podstawie zmian cen
// Funkcja do generowania wykresu na podstawie zmian cen
function generatePriceChart(priceEntries) {
    console.log("Funkcja generatePriceChart została wywołana.");
    console.log("Dane wejściowe:", priceEntries);

    var labels, data;
    var maxY; // Zmienna dla maksymalnej wartości osi Y

    if (priceEntries.length > 0) {
        // Jeśli są dane, używamy ich do generowania wykresu
        labels = priceEntries.map(entry => formatDate(entry.priceChange));
        data = priceEntries.map(entry => entry.newPrice);

        // Obliczamy maksymalną wartość dla osi Y
        const maxPrice = Math.max(...data);
        maxY = Math.ceil(maxPrice * 1.2); // Ustawiamy maksymalną wartość na 20% wyższą
    } else {
        // Jeśli nie ma danych, używamy przykładowych danych
        labels = ['No data'];
        data = [0, 1];
        maxY = 2; // Ustawiamy maksymalną wartość na 2 w przypadku braku danych
    }

    console.log("Etykiety:", labels);
    console.log("Dane:", data);
    console.log("Maksymalna wartość osi Y:", maxY); // Debugging

    var canvas = document.getElementById('price-chart');
    var ctx = canvas.getContext('2d');

    // Ustawienie wymiarów canvas
    canvas.width = 400;
    canvas.height = 200;

    // Inicjalizujemy wykres
    new Chart(ctx, {
        type: 'line',
        data: {
            labels: labels,
            datasets: [{
                label: 'Cena',
                data: data,
                backgroundColor: 'rgba(75, 192, 192, 0.2)',
                borderColor: 'rgba(75, 192, 192, 1)',
                borderWidth: 1,
                pointRadius: 5,
                pointHoverRadius: 8
            }]
        },
        options: {
            scales: {
                y: {
                    beginAtZero: true,
                    max: maxY // Ustawiamy maksymalną wartość osi Y
                }
            },
            plugins: {
                tooltip: {
                    padding: 10, // Powiększa padding wewnętrzny
                    backgroundColor: 'rgba(0, 0, 0, 0.7)', // Tło tooltipa
                    titleColor: '#fff', // Kolor tytułu tooltipa
                    bodyColor: '#fff', // Kolor ciała tooltipa
                    titleFont: {
                        size: 16, // Zwiększamy rozmiar czcionki tytułu tooltipa
                    },
                    bodyFont: {
                        size: 14, // Zwiększamy rozmiar czcionki ciała tooltipa
                    },
                    callbacks: {
                        label: function(tooltipItem) {
                            const currentPrice = tooltipItem.raw; // Cena bieżącego punktu
                            const index = tooltipItem.dataIndex; // Indeks bieżącego punktu

                            // Obliczanie procentowej zmiany w stosunku do poprzedniego punktu
                            let percentChange = 0;
                            if (index > 0) { // Jeśli to nie pierwszy punkt
                                const previousPrice = data[index - 1];
                                percentChange = ((currentPrice - previousPrice) / previousPrice) * 100;
                            }

                            return [
                                `Cena: ${currentPrice.toFixed(2)} zł`,
                                `Zmiana: ${percentChange.toFixed(2)}%`
                            ];
                        }
                    }
                }
            }
        }
    });
}


    // Funkcja do formatowania wartości w złotówkach
    function formatCurrency(value) {
        return new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN' }).format(value);
    }

    // Funkcja do formatowania dat w formacie dd.mm
    function formatDate(dateString) {
        var date = new Date(dateString);
        var day = String(date.getDate()).padStart(2, '0');
        var month = String(date.getMonth() + 1).padStart(2, '0');
        return `${day}.${month}`;
    }
function formatDaty(isoDateString) {
    var parsedDate = new Date(isoDateString);
    var formattedDay = String(parsedDate.getDate()).padStart(2, '0');
    var formattedMonth = String(parsedDate.getMonth() + 1).padStart(2, '0');
    var formattedYear = parsedDate.getFullYear(); // Wyciąganie roku
    var formattedHours = String(parsedDate.getHours()).padStart(2, '0');
    var formattedMinutes = String(parsedDate.getMinutes()).padStart(2, '0');

    // Zwrócenie daty w formacie: dd-mm-rrrr | hh:mm
    return `${formattedDay}-${formattedMonth}-${formattedYear} | ${formattedHours}:${formattedMinutes}`;
}



    // Funkcja do obliczania dat
    function getDateString(date) {
        return date.toISOString().split('T')[0]; // Tylko data w formacie YYYY-MM-DD
    }

    // Funkcja do ustawienia interwału dodawania przycisków
    function setupButtonAdditionInterval() {
        // Dodaj przyciski co 1 sekundę
        setInterval(addStatystykaButton, 1000);
    }

    // Czekamy, aż dokument zostanie w pełni załadowany
    window.addEventListener('load', function() {
        addStatystykaButton(); // Początkowe dodanie przycisków
        setupButtonAdditionInterval(); // Ustawienie interwału do dodawania przycisków

        // Dodajemy obserwatora MutationObserver z debounce dla wydajności
        let updateTimeout;
        const observer = new MutationObserver(function(mutations) {
            // Sprawdź czy są rzeczywiście nowe artykuły
            let hasNewArticles = false;
            mutations.forEach(function(mutation) {
                if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                    for (let node of mutation.addedNodes) {
                        if (node.nodeType === 1 && (node.matches && (node.matches('article') || node.matches('li') || node.querySelector('article')))) {
                            hasNewArticles = true;
                            break;
                        }
                    }
                }
            });

            if (hasNewArticles) {
                // Debounce - czekaj 300ms przed aktualizacją
                clearTimeout(updateTimeout);
                updateTimeout = setTimeout(() => {
                    addStatystykaButton();
                }, 300);
            }
        });

        // Obserwujemy tylko konkretne kontenery, nie całe body
        const rightItemsDiv = document.querySelector("div[data-role='rightItems']");
        if (rightItemsDiv) {
            observer.observe(rightItemsDiv, {
                childList: true,
                subtree: true,
                attributes: false,
                characterData: false
            });
        }

        // Obserwuj też główny kontener z ofertami (jeśli istnieje)
        const mainContainer = document.querySelector("main, [data-role='main'], .opbox-listing");
        if (mainContainer) {
            observer.observe(mainContainer, {
                childList: true,
                subtree: true,
                attributes: false,
                characterData: false
            });
        }
    });
})();

// --- Allegro Image Downloader ---
(function() {
    'use strict';

    'use strict';
    if (window.vSprintPlusSettings && window.vSprintPlusSettings.img === false) return;
    // --- KOPIOWANIE OPISU ---
    function extractCleanText(container) {
        const allowedTags = ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'OL', 'LI', 'STRONG', 'EM', 'SPAN'];
        let result = '';
        function walk(node) {
            if (allowedTags.includes(node.tagName)) {
                const text = node.innerText.trim();
                if (text) {
                    result += text + '\n';
                }
            }
            for (let child of node.children) {
                walk(child);
            }
        }
        walk(container);
        return result.trim();
    }

    function addCopyButton() {
        const descBox = document.querySelector('div[data-box-name="Description card"]');
        if (!descBox) return;
        if (document.getElementById('kopiuj-opis-btn')) return;
        const button = document.createElement('button');
        button.id = 'kopiuj-opis-btn';
        button.innerText = '📋 Kopiuj opis';
        button.style.position = "relative";
        button.style.zIndex = "9999";
        button.style.marginBottom = "10px";
        button.style.padding = "10px 20px";
        button.style.backgroundColor = "#ff5a00";
        button.style.color = "#fff";
        button.style.border = "none";
        button.style.cursor = "pointer";
        button.style.fontSize = "16px";
        button.style.borderRadius = "5px";
        button.addEventListener('click', () => {
            const text = extractCleanText(descBox);
            if (text) {
                GM_setClipboard(text);
                // Pokaż krótką informację przy przycisku
                const originalText = button.innerText;
                button.innerText = '✅ Skopiowano!';
                button.style.backgroundColor = '#28a745';
                setTimeout(() => {
                    button.innerText = originalText;
                    button.style.backgroundColor = '#ff5a00';
                }, 2000);
            } else {
                // Pokaż błąd przy przycisku
                const originalText = button.innerText;
                button.innerText = '❌ Brak tekstu';
                button.style.backgroundColor = '#dc3545';
                setTimeout(() => {
                    button.innerText = originalText;
                    button.style.backgroundColor = '#ff5a00';
                }, 2000);
            }
        });
        descBox.parentElement.insertBefore(button, descBox);
    }
    window.addEventListener('load', () => {
        setTimeout(addCopyButton, 2000);
    });

    // --- POBIERANIE ZDJĘĆ ---
    function tuTworzymyButton() {
        let button = document.createElement("button");
        button.innerText = "Pobierz zdjęcia";
        button.style.position = "relative";
        button.style.zIndex = "9999";
        button.style.marginTop = "10px";
        button.style.padding = "10px 20px";
        button.style.backgroundColor = "#ff5a00";
        button.style.color = "#fff";
        button.style.border = "none";
        button.style.cursor = "pointer";
        button.style.fontSize = "16px";
        button.style.borderRadius = "5px";
        button.onclick = tuPokazujemyModal;
        return button;
    }

    function tuPokazujemyModal() {
        let modal = document.createElement("div");
        modal.style.position = "fixed";
        modal.style.top = "50%";
        modal.style.left = "50%";
        modal.style.transform = "translate(-50%, -50%)";
        modal.style.backgroundColor = "#fff";
        modal.style.padding = "35px";
        modal.style.zIndex = "10000";
        modal.style.boxShadow = "0px 0px 10px rgba(0, 0, 0, 0.5)";
        modal.style.maxHeight = "80%";
        modal.style.maxWidth = "80%";
        modal.style.overflowY = "auto";
        modal.style.display = "grid";
        modal.style.gridTemplateColumns = "repeat(auto-fill, minmax(150px, 1fr))";
        modal.style.gridGap = "10px";
        modal.style.paddingBottom = "60px";

        let tuZamykamy = document.createElement("button");
        tuZamykamy.innerText = "x";
        tuZamykamy.style.position = "absolute";
        tuZamykamy.style.top = "5px";
        tuZamykamy.style.right = "5px";
        tuZamykamy.style.backgroundColor = "#ff5a00";
        tuZamykamy.style.color = "#fff";
        tuZamykamy.style.border = "none";
        tuZamykamy.style.cursor = "pointer";
        tuZamykamy.style.fontSize = "16px";
        tuZamykamy.style.borderRadius = "50%";
        tuZamykamy.style.width = "30px";
        tuZamykamy.style.height = "30px";
        tuZamykamy.style.zIndex = "9999";
        tuZamykamy.onclick = function() { document.body.removeChild(modal); };
        modal.appendChild(tuZamykamy);

        let images = tuObrazki();
        images.forEach(src => {
            let imgWrapper = document.createElement("div");
            imgWrapper.style.position = "relative";
            imgWrapper.style.overflow = "hidden";
            imgWrapper.style.border = "1px solid #ddd";
            imgWrapper.style.borderRadius = "5px";
            imgWrapper.style.padding = "5px";
            imgWrapper.style.backgroundColor = "#f9f9f9";

            let img = document.createElement("img");
            img.src = src;
            img.style.width = "150px";
            img.style.height = "230px";
            img.style.objectFit = "cover";
            imgWrapper.appendChild(img);

            let tuPobieramy = document.createElement("button");
            tuPobieramy.innerText = "Pobierz";
            tuPobieramy.style.position = "absolute";
            tuPobieramy.style.bottom = "10px";
            tuPobieramy.style.left = "50%";
            tuPobieramy.style.transform = "translateX(-50%)";
            tuPobieramy.style.padding = "5px 10px";
            tuPobieramy.style.backgroundColor = "#ff5a00";
            tuPobieramy.style.color = "#fff";
            tuPobieramy.style.border = "none";
            tuPobieramy.style.cursor = "pointer";
            tuPobieramy.style.borderRadius = "3px";
            tuPobieramy.onclick = function() { GM_download(src, tuMagia(src)); };
            imgWrapper.appendChild(tuPobieramy);

            modal.appendChild(imgWrapper);
        });

        let przyciskContainer = document.createElement("div");
        przyciskContainer.style.width = "100%";
        przyciskContainer.style.display = "flex";
        przyciskContainer.style.justifyContent = "center";
        przyciskContainer.style.position = "absolute";
        przyciskContainer.style.bottom = "10px";

        let tuWiecejPobieramy = document.createElement("button");
        tuWiecejPobieramy.innerText = "Pobierz wszystkie";
        tuWiecejPobieramy.style.padding = "10px 20px";
        tuWiecejPobieramy.style.backgroundColor = "rgb(255, 90, 0)";
        tuWiecejPobieramy.style.color = "rgb(255, 255, 255)";
        tuWiecejPobieramy.style.border = "none";
        tuWiecejPobieramy.style.cursor = "pointer";
        tuWiecejPobieramy.style.fontSize = "16px";
        tuWiecejPobieramy.style.borderRadius = "5px";
        tuWiecejPobieramy.onclick = function() {
            images.forEach(src => GM_download(src, tuMagia(src)));
        };

        przyciskContainer.appendChild(tuWiecejPobieramy);
        modal.appendChild(przyciskContainer);

        document.body.appendChild(modal);
    }

    function tuObrazki() {
        let images = [];
        let galleryDiv = document.querySelector('div[data-box-name="showoffer.gallery"]');
        if (galleryDiv) {
            let buttons = galleryDiv.querySelectorAll('button:not([aria-label])');
            buttons.forEach(button => {
                let img = button.querySelector('img');
                if (img) {
                    let src = img.src.replace('/s128/', '/original/') + '.jpg';
                    images.push(src);
                }
            });
        }
        return images;
    }

    function tuMagia(src) {
        return src.split('/').pop();
    }

    function tuPatrzymy() {
        let observer = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                if (mutation.addedNodes.length > 0) {
                    let galleryDiv = document.querySelector('div[data-box-name="showoffer.gallery"]');
                    if (galleryDiv && !galleryDiv.querySelector("button.download-button")) {
                        let tuPobieramy = tuTworzymyButton();
                        tuPobieramy.classList.add("download-button");
                        galleryDiv.appendChild(tuPobieramy);
                    }
                }
            });
        });
        let config = { childList: true, subtree: true };
        observer.observe(document.body, config);
    }
    tuPatrzymy();
})();

// --- Allegro Kampanie ---
(function() {
    'use strict';
    if (window.vSprintPlusSettings && window.vSprintPlusSettings.kampanie === false) return;
    // Uruchamiaj tylko na stronie kampanii
    if (!window.location.href.match(/^https:\/\/salescenter\.allegro\.com\/campaigns/)) {
        return; // Przerywamy wykonywanie tego bloku
    }

    let listenForNextEligibleRequest = false;
    let isCheckboxChecked = false; // Domyślnie checkbox jest odznaczony
    let collectedRows = []; // Tablica do zbierania danych ze wszystkich stron
    let pagesCollected = 0; // Licznik zebranych stron
    let baseUrl = ''; // Bazowy URL do kolejnych żądań
    let isAutoFetching = false; // Flaga czy trwa automatyczne pobieranie
    let fetchOptions = null; // Opcje żądania fetch (headers, credentials, etc.)
    let useXHR = false; // Flaga czy używać XMLHttpRequest czy fetch

    // Zapisz oryginalny fetch przed jego nadpisaniem
    const originalFetch = window.fetch;
    const originalXHROpen = XMLHttpRequest.prototype.open;
    const originalXHRSend = XMLHttpRequest.prototype.send;

    // Funkcja dodająca przycisk i checkbox w prawym górnym rogu
    function addDownloadPanel() {
        const panel = document.createElement('div');
        panel.style.position = 'fixed';
        panel.style.top = '10px';
        panel.style.right = '10px';
        panel.style.zIndex = '9999';
        panel.style.background = '#23272e';
        panel.style.padding = '16px 20px';
        panel.style.borderRadius = '10px';
        panel.style.boxShadow = '0 4px 24px rgba(0,0,0,0.18)';
        panel.style.display = 'flex';
        panel.style.alignItems = 'center';
        panel.style.gap = '16px';
        panel.style.fontFamily = 'inherit';

        // Przycisk
        const button = document.createElement('button');
        button.innerText = 'Pobierz raport';
        button.style.background = '#23272e';
        button.style.color = '#fff';
        button.style.border = '1.5px solid #ff5a00';
        button.style.padding = '10px 20px'; // rozmiar jak w oceny.js
        button.style.fontSize = '16px';
        button.style.borderRadius = '8px';
        button.style.cursor = 'pointer';
        button.style.fontWeight = 'bold';
        button.style.boxShadow = '0 2px 8px rgba(0,0,0,0.10)';
        button.style.transition = 'background 0.2s, color 0.2s';
        button.onmouseenter = () => {
            button.style.background = '#ff5a00';
            button.style.color = '#fff';
        };
        button.onmouseleave = () => {
            button.style.background = '#23272e';
            button.style.color = '#fff';
        };
        button.style.top = '10px'; // pozycja jak w oceny.js
        button.style.right = '20px';

        // Checkbox
        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.checked = isCheckboxChecked;
        checkbox.style.width = '20px';
        checkbox.style.height = '20px';
        checkbox.style.cursor = 'pointer';
        checkbox.style.accentColor = '#ff5a00';
        checkbox.style.margin = '0 0 0 8px';
        checkbox.title = 'Aktywuj/dezaktywuj zbieranie danych';

        // Etykieta do checkboxa
        const checkboxLabel = document.createElement('label');
        checkboxLabel.innerText = 'Aktywne';
        checkboxLabel.style.color = '#fff';
        checkboxLabel.style.fontSize = '15px';
        checkboxLabel.style.marginLeft = '4px';
        checkboxLabel.style.cursor = 'pointer';
        checkboxLabel.htmlFor = 'allegro-days-checkbox';
        checkbox.id = 'allegro-days-checkbox';

        // Instrukcja
        const info = document.createElement('div');
        info.style.position = 'absolute';
        info.style.top = '54px'; // pod przyciskiem
        info.style.left = '0';
        info.style.width = '220px';
        info.style.height = '220px';
        info.style.display = 'none';
        info.style.background = '#23272e';
        info.style.border = '1.5px solid #ff5a00';
        info.style.fontSize = '15px';
        info.style.padding = '24px';
        info.style.fontWeight = 'bold';
        info.style.textAlign = 'center';
        info.style.display = 'none';
        info.style.alignItems = 'center';
        info.style.justifyContent = 'center';
        info.style.lineHeight = '1.5';
        info.style.pointerEvents = 'none';
        info.style.userSelect = 'none';
        info.style.whiteSpace = 'pre-line';
        info.style.transition = 'opacity 0.2s';
        info.style.opacity = '1';
        info.style.color = '#fff'; // Biały tekst na ciemnym tle
        info.innerText = "aby pobrać raport,\nwybierz kampanię AlleObniżka,\nzjedź na sam dół i kliknij,\naby wyświetlało 200 ofert\nna jednej stronie (po lewej stronie).";
        panel.style.position = 'fixed'; // upewnij się, że panel jest fixed
        panel.appendChild(info);

        // Obsługa checkboxa
        checkbox.addEventListener('change', function() {
            isCheckboxChecked = checkbox.checked;
            console.log('Checkbox jest teraz:', isCheckboxChecked ? 'zaznaczony' : 'odznaczony');
        });

        // Obsługa przycisku
        button.onclick = function() {
            info.style.display = 'flex';
            info.style.opacity = '1';
            setTimeout(() => {
                info.style.opacity = '0';
                setTimeout(() => { info.style.display = 'none'; }, 300);
            }, 15000);
        };

        // Panel: przycisk, checkbox, label
        panel.appendChild(button);
        panel.appendChild(checkbox);
        panel.appendChild(checkboxLabel);
        panel.appendChild(info);

        document.body.appendChild(panel);
    }

    // Czekamy na załadowanie strony
    window.addEventListener('load', function() {
        addDownloadPanel();
    });

    // Nasłuchuj kliknięcia w przycisk value=200
    document.addEventListener('click', function(event) {
        const button = event.target.closest('button[value="200"]');
        if (button) {
            if (isCheckboxChecked) {
                console.log('Checkbox jest zaznaczony – przygotowuję się do przechwycenia żądania...');
                listenForNextEligibleRequest = true;
                collectedRows = []; // Resetuj zebrane dane przy starcie nowego pobierania
                pagesCollected = 0;
                baseUrl = ''; // Resetuj bazowy URL
                isAutoFetching = false; // Resetuj flagę automatycznego pobierania
                fetchOptions = null; // Resetuj opcje fetch
                useXHR = false; // Resetuj flagę XHR
                console.log('[ZBIERACZ] Rozpoczynam automatyczne zbieranie danych z wielu stron...');
            } else {
                console.log('Checkbox NIE jest zaznaczony – skrypt nie zostanie uruchomiony.');
                listenForNextEligibleRequest = false;
                isAutoFetching = false;
            }
        }
    });

    // Funkcja pomocnicza do przetwarzania danych
    function processItems(items) {
        return items.map(item => {
            // Oblicz procentową obniżkę
            const price = parseFloat(item.buyNowPrice.amount.replace(',', '.'));
            const discountPrice = parseFloat(item.cofinanceInfo.requiredMerchantPrice.amount.replace(',', '.'));
            const discountPercentage = ((price - discountPrice) / price) * 100;

            // Zapisujemy procent jako liczbę (np. 13.43) zamiast tekstu
            const discountPercentageRounded = parseFloat(discountPercentage.toFixed(2)); // Zaokrąglamy i zostawiamy jako liczbę

            // Oblicz dodatek Allegro
            const merchantDiscount = parseFloat(item.cofinanceInfo.merchantPriceDiscount.points);
            const discountAddition = (merchantDiscount / 100) * discountPrice;

            // Sprawdź czy oferta się kwalifikuje
            const kwalifikuje = item.notMetConditions && item.notMetConditions.length > 0
                ? item.notMetConditions.join('; ')
                : 'tak';

            // Zwróć dane w odpowiedniej strukturze
            return {
                id: item.offerId,
                sku: item.externalId,
                ean: item.ean,
                nazwa: item.offerTitle,
                cena: price,  // Zapisujemy liczbę jako liczbę
                wymagana_obnizka: discountPrice,  // Zapisujemy liczbę jako liczbę
                procent_obnizki: discountPercentageRounded, // Zapisujemy liczbę jako liczbę
                limit: item.cofinanceInfo.purchaseLimit,
                obnizka_allegro: discountAddition,  // Zapisujemy liczbę jako liczbę
                czy_sie_kwalifikuje: kwalifikuje,
            };
        });
    }

    // Funkcja do wyświetlania modala
    function showModal(message) {
        // Usuń istniejący modal jeśli jest
        const existingModal = document.getElementById('allegro-download-modal');
        if (existingModal) {
            existingModal.remove();
        }

        // Tworzenie overlay
        const overlay = document.createElement('div');
        overlay.id = 'allegro-download-modal';
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
        overlay.style.zIndex = '10000';
        overlay.style.display = 'flex';
        overlay.style.alignItems = 'center';
        overlay.style.justifyContent = 'center';

        // Tworzenie modala
        const modal = document.createElement('div');
        modal.style.background = '#23272e';
        modal.style.padding = '30px 40px';
        modal.style.borderRadius = '12px';
        modal.style.boxShadow = '0 8px 32px rgba(0,0,0,0.3)';
        modal.style.border = '2px solid #ff5a00';
        modal.style.maxWidth = '400px';
        modal.style.textAlign = 'center';
        modal.style.color = '#fff';
        modal.style.fontSize = '16px';
        modal.style.fontFamily = 'inherit';

        // Tekst w modalu
        const text = document.createElement('div');
        text.innerText = message;
        text.style.marginBottom = '20px';
        text.style.lineHeight = '1.5';

        // Przycisk zamknięcia
        const closeBtn = document.createElement('button');
        closeBtn.innerText = 'Zamknij';
        closeBtn.style.background = '#ff5a00';
        closeBtn.style.color = '#fff';
        closeBtn.style.border = 'none';
        closeBtn.style.padding = '12px 30px';
        closeBtn.style.fontSize = '16px';
        closeBtn.style.borderRadius = '8px';
        closeBtn.style.cursor = 'pointer';
        closeBtn.style.fontWeight = 'bold';
        closeBtn.style.transition = 'background 0.2s';
        closeBtn.onmouseenter = () => {
            closeBtn.style.background = '#e04a00';
        };
        closeBtn.onmouseleave = () => {
            closeBtn.style.background = '#ff5a00';
        };
        closeBtn.onclick = () => {
            overlay.remove();
        };

        modal.appendChild(text);
        modal.appendChild(closeBtn);
        overlay.appendChild(modal);

        // Kliknięcie poza modalem zamyka go
        overlay.onclick = (e) => {
            if (e.target === overlay) {
                overlay.remove();
            }
        };

        document.body.appendChild(overlay);
    }

    // Funkcja do wyświetlania okienka pobierania
    let downloadingModal = null;
    function showDownloadingModal(pagesCount, itemsCount) {
        // Usuń istniejące okienko jeśli jest
        if (downloadingModal) {
            downloadingModal.remove();
        }

        // Tworzenie overlay
        const overlay = document.createElement('div');
        overlay.id = 'allegro-downloading-modal';
        downloadingModal = overlay;
        overlay.style.position = 'fixed';
        overlay.style.top = '0';
        overlay.style.left = '0';
        overlay.style.width = '100%';
        overlay.style.height = '100%';
        overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.6)';
        overlay.style.zIndex = '10000';
        overlay.style.display = 'flex';
        overlay.style.alignItems = 'center';
        overlay.style.justifyContent = 'center';

        // Tworzenie okienka
        const box = document.createElement('div');
        box.style.background = '#23272e';
        box.style.padding = '30px 40px';
        box.style.borderRadius = '12px';
        box.style.boxShadow = '0 8px 32px rgba(0,0,0,0.3)';
        box.style.border = '2px solid #ff5a00';
        box.style.minWidth = '300px';
        box.style.textAlign = 'center';
        box.style.color = '#fff';
        box.style.fontSize = '16px';
        box.style.fontFamily = 'inherit';

        // Ikona/animacja ładowania
        const spinner = document.createElement('div');
        spinner.style.width = '40px';
        spinner.style.height = '40px';
        spinner.style.border = '4px solid rgba(255, 90, 0, 0.3)';
        spinner.style.borderTop = '4px solid #ff5a00';
        spinner.style.borderRadius = '50%';
        spinner.style.animation = 'spin 1s linear infinite';
        spinner.style.margin = '0 auto 20px';

        // Dodaj animację spin
        if (!document.getElementById('allegro-spinner-style')) {
            const style = document.createElement('style');
            style.id = 'allegro-spinner-style';
            style.textContent = `
                @keyframes spin {
                    0% { transform: rotate(0deg); }
                    100% { transform: rotate(360deg); }
                }
            `;
            document.head.appendChild(style);
        }

        // Tekst
        const text = document.createElement('div');
        text.id = 'allegro-downloading-text';
        text.innerText = `Pobieranie danych...\nStrona: ${pagesCount} | Ofert: ${itemsCount}`;
        text.style.marginBottom = '10px';
        text.style.lineHeight = '1.8';
        text.style.whiteSpace = 'pre-line';

        box.appendChild(spinner);
        box.appendChild(text);
        overlay.appendChild(box);
        document.body.appendChild(overlay);
    }

    // Funkcja do aktualizacji okienka pobierania
    function updateDownloadingModal(pagesCount, itemsCount) {
        const textElement = document.getElementById('allegro-downloading-text');
        if (textElement) {
            textElement.innerText = `Pobieranie danych...\nStrona: ${pagesCount} | Ofert: ${itemsCount}`;
        }
    }

    // Funkcja do zamykania okienka pobierania
    function hideDownloadingModal() {
        if (downloadingModal) {
            downloadingModal.remove();
            downloadingModal = null;
        }
    }

    // Funkcja do zapisywania zebranych danych do Excela
    function saveCollectedData() {
        if (collectedRows.length === 0) {
            console.warn('[ZBIERACZ] Brak danych do zapisania.');
            hideDownloadingModal();
            return;
        }

        console.log(`[ZBIERACZ] Zapisuję dane z ${pagesCollected} stron (łącznie ${collectedRows.length} ofert)...`);

        // Zapis do pliku Excel
        const ws = XLSX.utils.json_to_sheet(collectedRows);
        const wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, "Dane");

        // Ustawienia formatu komórek w Excelu
        const cellFormat = {
            cellDates: true,
            cellText: false
        };

        // Formatuj kolumnę procent_obnizki jako procentową
        const percentStyle = {
            font: { bold: false },
            alignment: { horizontal: 'right' },
            numberFormat: '0.00%'
        };

        // Aplikuj formatowanie dla procentów
        ws['!cols'] = ws['!cols'] || [];
        ws['!cols'][2] = percentStyle; // Kolumna 2 (procent_obnizki) jako procentowa

        // Zapisujemy plik z nową nazwą
        XLSX.writeFile(wb, "AllegroDays - zestawienie.xlsx", cellFormat);

        // Zamknij okienko pobierania
        hideDownloadingModal();

        // Wyświetl informację o liczbie stron w modalu
        showModal(`Pobrano raport z ${pagesCollected} stron (łącznie ${collectedRows.length} ofert).`);

        // Po pobraniu raportu odznacz checkbox
        const cb = document.getElementById('allegro-days-checkbox');
        if (cb) cb.checked = false, isCheckboxChecked = false;

        // Resetuj zebrane dane
        collectedRows = [];
        pagesCollected = 0;
        listenForNextEligibleRequest = false;
        isAutoFetching = false;
        baseUrl = '';
        fetchOptions = null;
        useXHR = false;
    }

    // Funkcja do automatycznego pobierania kolejnych stron przez fetch
    function fetchNextPage(offset) {
        if (!baseUrl || isAutoFetching === false || !fetchOptions) {
            return;
        }

        // Utwórz URL z nowym offsetem
        let nextUrl = baseUrl;
        if (nextUrl.includes('offset=')) {
            // Zamień istniejący offset
            nextUrl = nextUrl.replace(/offset=\d+/, `offset=${offset}`);
        } else {
            // Dodaj offset do URL
            const separator = nextUrl.includes('?') ? '&' : '?';
            nextUrl = `${nextUrl}${separator}offset=${offset}`;
        }

        console.log(`[ZBIERACZ] Automatyczne pobieranie strony z offset=${offset}: ${nextUrl}`);

        // Skopiuj opcje
        const options = { ...fetchOptions };
        if (!options.credentials || options.credentials === 'same-origin') {
            options.credentials = 'include';
        }
        if (options.headers && !(options.headers instanceof Headers)) {
            options.headers = { ...options.headers };
        }

        // Wykonaj żądanie z zapisanymi opcjami używając originalFetch, aby uniknąć przechwycenia
        originalFetch(nextUrl, options)
            .then(response => {
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                return response.json();
            })
            .then(data => {
                console.log(`[ZBIERACZ] Automatyczna odpowiedź (offset=${offset}):`, data);

                // Sprawdź, czy odpowiedź zawiera pole 'items'
                if (data.items && Array.isArray(data.items)) {
                    // Jeśli brak ofert (pusta tablica), zapisz zebrane dane
                    if (data.items.length === 0) {
                        console.log('[ZBIERACZ] Otrzymano pustą odpowiedź - kończę automatyczne pobieranie i zapisuję dane.');
                        isAutoFetching = false;
                        saveCollectedData();
                        return;
                    }

                    // Przetwarzanie danych na odpowiedni format dla Excela
                    const rows = processItems(data.items);

                    // Dodaj dane do zebranych
                    collectedRows = collectedRows.concat(rows);
                    pagesCollected++;

                    // Aktualizuj okienko pobierania
                    updateDownloadingModal(pagesCollected, collectedRows.length);

                    console.log(`[ZBIERACZ] Automatycznie zebrano stronę ${pagesCollected} (${data.items.length} ofert). Łącznie: ${collectedRows.length} ofert.`);

                    // Pobierz następną stronę z offsetem zwiększonym o limit (200)
                    setTimeout(() => {
                        fetchNextPage(offset + 200);
                    }, 500); // Małe opóźnienie aby nie przeciążać serwera
                } else {
                    // Jeśli nie ma items, oznacza to koniec - zapisz zebrane dane
                    console.log('[ZBIERACZ] Brak pola "items" w odpowiedzi - kończę automatyczne pobieranie i zapisuję dane.');
                    isAutoFetching = false;
                    if (collectedRows.length > 0) {
                        saveCollectedData();
                    } else {
                        console.warn('[ZBIERACZ] Brak danych do zapisania.');
                        listenForNextEligibleRequest = false;
                    }
                }
            })
            .catch(error => {
                console.error('[ZBIERACZ] Błąd podczas automatycznego pobierania:', error);
                isAutoFetching = false;
                // Zapisz to co udało się zebrać
                if (collectedRows.length > 0) {
                    saveCollectedData();
                }
            });
    }

    // Funkcja do automatycznego pobierania kolejnych stron przez XMLHttpRequest
    function fetchNextPageXHR(offset) {
        if (!baseUrl || isAutoFetching === false || !fetchOptions) {
            return;
        }

        // Utwórz URL z nowym offsetem
        let nextUrl = baseUrl;
        if (nextUrl.includes('offset=')) {
            // Zamień istniejący offset
            nextUrl = nextUrl.replace(/offset=\d+/, `offset=${offset}`);
        } else {
            // Dodaj offset do URL
            const separator = nextUrl.includes('?') ? '&' : '?';
            nextUrl = `${nextUrl}${separator}offset=${offset}`;
        }

        console.log(`[ZBIERACZ][XHR] Automatyczne pobieranie strony z offset=${offset}: ${nextUrl}`);

        // Utwórz nowe żądanie XMLHttpRequest
        const xhr = new XMLHttpRequest();

        // Otwórz żądanie z metodą GET
        originalXHROpen.call(xhr, 'GET', nextUrl, true);

        // Ustaw nagłówki z zapisanych opcji
        if (fetchOptions.headers) {
            Object.keys(fetchOptions.headers).forEach(key => {
                xhr.setRequestHeader(key, fetchOptions.headers[key]);
            });
        }

        xhr.withCredentials = true;

        // Obsługa odpowiedzi
        xhr.onload = function() {
            try {
                if (xhr.status >= 200 && xhr.status < 300) {
                    const data = JSON.parse(xhr.responseText);
                    console.log(`[ZBIERACZ][XHR] Automatyczna odpowiedź (offset=${offset}):`, data);

                    // Sprawdź, czy odpowiedź zawiera pole 'items'
                    if (data.items && Array.isArray(data.items)) {
                        // Jeśli brak ofert (pusta tablica), zapisz zebrane dane
                        if (data.items.length === 0) {
                            console.log('[ZBIERACZ][XHR] Otrzymano pustą odpowiedź - kończę automatyczne pobieranie i zapisuję dane.');
                            isAutoFetching = false;
                            saveCollectedData();
                            return;
                        }

                        // Przetwarzanie danych na odpowiedni format dla Excela
                        const rows = processItems(data.items);

                        // Dodaj dane do zebranych
                        collectedRows = collectedRows.concat(rows);
                        pagesCollected++;

                        // Aktualizuj okienko pobierania
                        updateDownloadingModal(pagesCollected, collectedRows.length);

                        console.log(`[ZBIERACZ][XHR] Automatycznie zebrano stronę ${pagesCollected} (${data.items.length} ofert). Łącznie: ${collectedRows.length} ofert.`);

                        // Pobierz następną stronę z offsetem zwiększonym o limit (200)
                        setTimeout(() => {
                            fetchNextPageXHR(offset + 200);
                        }, 500); // Małe opóźnienie aby nie przeciążać serwera
                    } else {
                        // Jeśli nie ma items, oznacza to koniec - zapisz zebrane dane
                        console.log('[ZBIERACZ][XHR] Brak pola "items" w odpowiedzi - kończę automatyczne pobieranie i zapisuję dane.');
                        isAutoFetching = false;
                        if (collectedRows.length > 0) {
                            saveCollectedData();
                        } else {
                            console.warn('[ZBIERACZ][XHR] Brak danych do zapisania.');
                            listenForNextEligibleRequest = false;
                        }
                    }
                } else {
                    throw new Error(`HTTP error! status: ${xhr.status}`);
                }
            } catch (error) {
                console.error('[ZBIERACZ][XHR] Błąd podczas automatycznego pobierania:', error);
                isAutoFetching = false;
                // Zapisz to co udało się zebrać
                if (collectedRows.length > 0) {
                    saveCollectedData();
                }
            }
        };

        xhr.onerror = function() {
            console.error('[ZBIERACZ][XHR] Błąd sieci podczas automatycznego pobierania');
            isAutoFetching = false;
            if (collectedRows.length > 0) {
                saveCollectedData();
            }
        };

        // Wysyłaj żądanie
        originalXHRSend.call(xhr);
    }

    // Przechwytywanie fetch
    window.fetch = function(...args) {
        const requestUrl = args[0];

        // Sprawdź czy to żądanie eligible z limit=200 (dopasowuje różne kampanie)
        const isEligibleRequest = listenForNextEligibleRequest &&
                                   typeof requestUrl === 'string' &&
                                   requestUrl.includes('eligible') &&
                                   requestUrl.includes('limit=200');

        if (isEligibleRequest && !isAutoFetching) {
            // To jest pierwsze żądanie - zapisz bazowy URL i opcje żądania
            baseUrl = requestUrl;
            isAutoFetching = true;
            useXHR = false; // Używamy fetch, nie XHR

            // Zapisz opcje żądania (drugi argument fetch, jeśli istnieje)
            if (args[1]) {
                // Konwertuj headers na zwykły obiekt jeśli jest Headers object
                let headersObj = {};
                if (args[1].headers) {
                    if (args[1].headers instanceof Headers) {
                        args[1].headers.forEach((value, key) => {
                            headersObj[key] = value;
                        });
                    } else if (typeof args[1].headers === 'object' && !Array.isArray(args[1].headers)) {
                        // Jeśli to zwykły obiekt, skopiuj go
                        headersObj = { ...args[1].headers };
                    }
                }

                // Skopiuj opcje - szczególnie ważne są headers, credentials, etc.
                fetchOptions = {
                    method: args[1].method || 'GET',
                    headers: headersObj,
                    credentials: args[1].credentials !== undefined ? args[1].credentials : 'include',
                    cache: args[1].cache || 'default',
                    redirect: args[1].redirect || 'follow',
                    referrer: args[1].referrer || 'client',
                    referrerPolicy: args[1].referrerPolicy || '',
                    mode: args[1].mode || 'cors'
                    // Nie kopiujemy signal i body - nie są potrzebne dla GET
                };

                console.log('[ZBIERACZ] Zapisano opcje żądania:', fetchOptions);
            } else {
                // Domyślne opcje jeśli nie podano
                fetchOptions = {
                    method: 'GET',
                    credentials: 'include',
                    headers: {}
                };
            }

            // Wyciągnij offset z URL do logowania
            const urlMatch = requestUrl.match(/offset=(\d+)/);
            const currentOffset = urlMatch ? parseInt(urlMatch[1]) : 0;

            console.log(`[ZBIERACZ] Wykryto pierwsze żądanie (offset=${currentOffset}):`, requestUrl);
            console.log(`[ZBIERACZ] Rozpoczynam automatyczne pobieranie z wielu stron...`);

            return originalFetch(...args).then(response => {
                const clonedResponse = response.clone();

                clonedResponse.json().then(data => {
                    console.log(`[ZBIERACZ] Odpowiedź pierwszej strony (offset=${currentOffset}):`, data);

                    // Sprawdź, czy odpowiedź zawiera pole 'items'
                    if (data.items && Array.isArray(data.items)) {
                        // Jeśli brak ofert (pusta tablica), zapisz i zakończ
                        if (data.items.length === 0) {
                            console.log('[ZBIERACZ] Pierwsza strona jest pusta - kończę zbieranie i zapisuję dane.');
                            isAutoFetching = false;
                            saveCollectedData();
                            return;
                        }

                        // Przetwarzanie danych na odpowiedni format dla Excela
                        const rows = processItems(data.items);

                        // Dodaj dane do zebranych
                        collectedRows = collectedRows.concat(rows);
                        pagesCollected++;

                        // Pokaż okienko pobierania
                        showDownloadingModal(pagesCollected, collectedRows.length);

                        console.log(`[ZBIERACZ] Zebrano stronę ${pagesCollected} (${data.items.length} ofert). Łącznie: ${collectedRows.length} ofert.`);
                        console.log(`[ZBIERACZ] Rozpoczynam automatyczne pobieranie kolejnych stron...`);

                        // Rozpocznij automatyczne pobieranie kolejnych stron
                        setTimeout(() => {
                            fetchNextPage(currentOffset + 200);
                        }, 500);
                    } else {
                        // Jeśli nie ma items, oznacza to koniec - zapisz zebrane dane
                        console.log('[ZBIERACZ] Brak pola "items" w odpowiedzi pierwszej strony - kończę zbieranie.');
                        isAutoFetching = false;
                        if (collectedRows.length > 0) {
                            saveCollectedData();
                        } else {
                            console.warn('[ZBIERACZ] Brak danych do zapisania.');
                            listenForNextEligibleRequest = false;
                        }
                    }
                });

                return response;
            });
        }

        return originalFetch(...args);
    };

    // Przechwytywanie XMLHttpRequest - przechwytujemy setRequestHeader aby zapisać nagłówki
    const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
    XMLHttpRequest.prototype.setRequestHeader = function(header, value) {
        // Jeśli to nasze żądanie, zapisz nagłówek
        if (this._isEligibleRequest && this._headers) {
            this._headers[header] = value;
        }
        return originalSetRequestHeader.call(this, header, value);
    };

    XMLHttpRequest.prototype.open = function(method, url, ...rest) {
        // Sprawdź czy to żądanie eligible z limit=200 (dopasowuje różne kampanie)
        this._isEligibleRequest = listenForNextEligibleRequest &&
                                   typeof url === 'string' &&
                                   url.includes('eligible') &&
                                   url.includes('limit=200') &&
                                   !isAutoFetching; // Tylko pierwsze żądanie

        if (this._isEligibleRequest) {
            this._requestUrl = url; // Zapisz URL dla późniejszego użycia
            this._headers = {}; // Inicjalizuj obiekt do przechowywania nagłówków
            this._method = method; // Zapisz metodę
        }

        return originalXHROpen.call(this, method, url, ...rest);
    };

    XMLHttpRequest.prototype.send = function(...args) {
        if (this._isEligibleRequest) {
            const xhr = this;
            const requestUrl = this._requestUrl || '';

            // To jest pierwsze żądanie - zapisz bazowy URL, nagłówki i rozpocznij automatyczne pobieranie
            baseUrl = requestUrl;
            isAutoFetching = true;
            useXHR = true; // Oznacz, że używamy XHR

            // Zapisz nagłówki i inne opcje jako fetchOptions dla spójności
            fetchOptions = {
                method: this._method || 'GET',
                headers: this._headers || {},
                credentials: 'include', // XHR domyślnie wysyła cookies
                mode: 'cors'
            };

            console.log('[ZBIERACZ][XHR] Zapisano opcje żądania:', fetchOptions);

            // Wyciągnij offset z URL do logowania
            const urlMatch = requestUrl.match(/offset=(\d+)/);
            const currentOffset = urlMatch ? parseInt(urlMatch[1]) : 0;

            console.log(`[ZBIERACZ][XHR] Wykryto pierwsze żądanie (offset=${currentOffset}):`, requestUrl);
            console.log(`[ZBIERACZ][XHR] Rozpoczynam automatyczne pobieranie z wielu stron...`);

            const onLoad = function() {
                try {
                    const response = JSON.parse(xhr.responseText);
                    console.log(`[ZBIERACZ][XHR] Odpowiedź pierwszej strony (offset=${currentOffset}):`, response);

                    // Sprawdź, czy odpowiedź zawiera pole 'items'
                    if (response.items && Array.isArray(response.items)) {
                        // Jeśli brak ofert (pusta tablica), zapisz i zakończ
                        if (response.items.length === 0) {
                            console.log('[ZBIERACZ][XHR] Pierwsza strona jest pusta - kończę zbieranie i zapisuję dane.');
                            isAutoFetching = false;
                            saveCollectedData();
                            return;
                        }

                        // Przetwarzanie danych na odpowiedni format dla Excela
                        const rows = processItems(response.items);

                        // Dodaj dane do zebranych
                        collectedRows = collectedRows.concat(rows);
                        pagesCollected++;

                        // Pokaż okienko pobierania
                        showDownloadingModal(pagesCollected, collectedRows.length);

                        console.log(`[ZBIERACZ][XHR] Zebrano stronę ${pagesCollected} (${response.items.length} ofert). Łącznie: ${collectedRows.length} ofert.`);
                        console.log(`[ZBIERACZ][XHR] Rozpoczynam automatyczne pobieranie kolejnych stron...`);

                        // Rozpocznij automatyczne pobieranie kolejnych stron używając XHR
                        setTimeout(() => {
                            fetchNextPageXHR(currentOffset + 200);
                        }, 500);
                    } else {
                        // Jeśli nie ma items, oznacza to koniec - zapisz zebrane dane
                        console.log('[ZBIERACZ][XHR] Brak pola "items" w odpowiedzi pierwszej strony - kończę zbieranie.');
                        isAutoFetching = false;
                        if (collectedRows.length > 0) {
                            saveCollectedData();
                        } else {
                            console.warn('[ZBIERACZ][XHR] Brak danych do zapisania.');
                            listenForNextEligibleRequest = false;
                        }
                    }

                } catch (e) {
                    console.warn('[ZBIERACZ][XHR] Nie udało się sparsować odpowiedzi:', e);
                    isAutoFetching = false;
                }
            };

            this.addEventListener('load', onLoad);
        }

        return originalXHRSend.apply(this, args);
    };
}
)();

// --- Allegro Kampanie Filtr ---
(function() {
    'use strict';
    if (window.vSprintPlusSettings && window.vSprintPlusSettings.kampFiltr === false) return;
    // Uruchamiaj tylko na stronie kampanii
    if (!window.location.href.match(/^https:\/\/salescenter\.allegro\.com\/campaigns/)) {
        return; // Przerywamy wykonywanie tego bloku
    }


    'use strict';

    // Funkcja do tworzenia i dodania wyszukiwarki
    function addSearchBox() {
        const searchContainer = document.querySelector('[data-testid="reco-offers"]');

        // Sprawdź czy już dodano wyszukiwarkę
        if (document.getElementById('allegro-search-wrapper')) {
            return; // Już dodano, nie dodawaj ponownie
        }

        if (searchContainer) {
            // Tworzymy kontener dla wyszukiwarki i przycisku
            const wrapper = document.createElement('div');
            wrapper.id = 'allegro-search-wrapper';
            wrapper.style.marginTop = '20px';
            wrapper.style.marginBottom = '20px';

            // Tworzymy pole wyszukiwania
            const searchBox = document.createElement('input');
            searchBox.setAttribute('id', 'offerSearchBox');
            searchBox.setAttribute('placeholder', 'Wpisz numery ofert (np. 12345, 67890)');
            searchBox.style.width = '100%';
            searchBox.style.padding = '12px 16px';
            searchBox.style.marginBottom = '12px';
            searchBox.style.fontSize = '16px';
            searchBox.style.background = '#fff'; // Standardowe białe tło
            searchBox.style.color = '#000'; // Czarny tekst
            searchBox.style.border = '1.5px solid #ff5a00'; // Pomarańczowa ramka
            searchBox.style.borderRadius = '8px';
            searchBox.style.fontFamily = 'inherit';
            searchBox.style.boxSizing = 'border-box';
            searchBox.style.outline = 'none';
            searchBox.style.transition = 'border-color 0.2s';

            // Dodaj style dla placeholder (pogrubiony)
            if (!document.getElementById('allegro-search-placeholder-style')) {
                const style = document.createElement('style');
                style.id = 'allegro-search-placeholder-style';
                style.textContent = `
                    #offerSearchBox::placeholder {
                        color: rgba(0, 0, 0, 0.6);
                        font-weight: bold;
                    }
                `;
                document.head.appendChild(style);
            }

            searchBox.addEventListener('input', filterOffers);
            searchBox.addEventListener('focus', () => {
                searchBox.style.borderColor = '#ff7a30';
            });
            searchBox.addEventListener('blur', () => {
                searchBox.style.borderColor = '#ff5a00';
            });

            // Tworzymy przycisk masowego zaznaczania w stylu przycisku "Pobierz raport"
            const massSelectButton = document.createElement('button');
            massSelectButton.textContent = 'Zaznacz wszystkie widoczne';
            massSelectButton.style.background = '#fff'; // Białe tło jak standardowe przyciski
            massSelectButton.style.color = '#000'; // Czarny tekst
            massSelectButton.style.border = '1.5px solid #ff5a00'; // Pomarańczowa ramka
            massSelectButton.style.padding = '10px 20px';
            massSelectButton.style.fontSize = '16px';
            massSelectButton.style.borderRadius = '8px';
            massSelectButton.style.cursor = 'pointer';
            massSelectButton.style.fontWeight = 'bold';
            massSelectButton.style.boxShadow = '0 2px 8px rgba(0,0,0,0.10)';
            massSelectButton.style.transition = 'background 0.2s, color 0.2s, border-color 0.2s';
            massSelectButton.style.fontFamily = 'inherit';
            massSelectButton.style.display = 'inline-block'; // Nie na całą szerokość
            massSelectButton.style.textAlign = 'left'; // Wyrównanie do lewej
            massSelectButton.addEventListener('click', toggleCheckboxes);

            // Efekty hover
            massSelectButton.onmouseenter = () => {
                massSelectButton.style.background = '#ff5a00';
                massSelectButton.style.color = '#fff';
                massSelectButton.style.borderColor = '#ff5a00';
            };
            massSelectButton.onmouseleave = () => {
                massSelectButton.style.background = '#fff';
                massSelectButton.style.color = '#000';
                massSelectButton.style.borderColor = '#ff5a00';
            };

            // Dodajemy elementy do kontenera
            wrapper.appendChild(searchBox);
            wrapper.appendChild(massSelectButton);

            // Dodajemy wrapper przed kontenerem z ofertami
            searchContainer.insertAdjacentElement('beforebegin', wrapper);
            console.log('[KAMPANIE FILTR] Wyszukiwarka i przycisk dodane!');
        } else {
            console.log('[KAMPANIE FILTR] Nie znaleziono kontenera z ofertami, próbuję ponownie...');
        }
    }

    // Funkcja do filtrowania ofert na podstawie numerów
    function filterOffers() {
        const input = document.getElementById('offerSearchBox').value.trim();
        console.log('Wyszukiwanie dla:', input); // Logujemy wartość wpisaną w pole wyszukiwania

        const numbers = input.split(/[\s,]+/).filter(Boolean); // Dzielimy po spacji lub przecinku i usuwamy puste elementy

        if (numbers.length > 0) {
            const offers = document.querySelectorAll('.mpof_ki');
            console.log('Znalezione oferty:', offers.length); // Logujemy liczbę ofert

            offers.forEach(offer => {
                const offerId = offer.querySelector('[data-testid="campaigns-recolist-offerId"]');
                if (offerId && numbers.includes(offerId.textContent.trim())) {
                    offer.style.display = ''; // Pokaż ofertę
                } else {
                    offer.style.display = 'none'; // Ukryj ofertę
                }
            });
        } else {
            // Jeśli brak numerów, pokazujemy wszystkie oferty
            const offers = document.querySelectorAll('.mpof_ki');
            offers.forEach(offer => {
                offer.style.display = ''; // Pokaż ofertę
            });
        }
    }

    // Funkcja do masowego zaznaczania checkboxów
    function toggleCheckboxes() {
        const offers = document.querySelectorAll('.mpof_ki');
        offers.forEach(offer => {
            // Sprawdzamy, czy oferta jest widoczna
            if (offer.style.display !== 'none') {
                const checkbox = offer.querySelector('input[type="checkbox"]');
                if (checkbox) {
                    // Zmieniamy stan checkboxa
                    checkbox.checked = !checkbox.checked;

                    // Wymuszamy wywołanie zdarzenia change
                    const event = new Event('change', {
                        'bubbles': true,
                        'cancelable': true
                    });
                    checkbox.dispatchEvent(event);

                    console.log(`Checkbox dla oferty ${offer.querySelector('[data-testid="campaigns-recolist-offerId"]').textContent} zmieniony na: ${checkbox.checked}`);
                }
            }
        });
    }

    // Funkcja inicjalizująca - próbuje dodać wyszukiwarkę natychmiast i ustawia obserwatora
    function initSearchBox() {
        // Spróbuj dodać natychmiast
        addSearchBox();

        // Jeśli nie udało się, ustaw obserwatora DOM
        if (!document.getElementById('allegro-search-wrapper')) {
            const observer = new MutationObserver((mutations, obs) => {
                // Sprawdź czy kontener z ofertami się pojawił
                const searchContainer = document.querySelector('[data-testid="reco-offers"]');
                if (searchContainer && !document.getElementById('allegro-search-wrapper')) {
                    addSearchBox();
                    // Jeśli udało się dodać, można przestać obserwować (opcjonalnie)
                    // obs.disconnect();
                }
            });

            // Rozpocznij obserwację całego body
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });

            console.log('[KAMPANIE FILTR] Ustawiono obserwatora DOM dla wyszukiwarki');
        }
    }

    // Inicjalizuj po załadowaniu strony lub natychmiast jeśli DOM jest gotowy
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initSearchBox);
    } else {
        initSearchBox();
    }

    // Również spróbuj po pełnym załadowaniu strony
    window.addEventListener('load', () => {
        console.log('[KAMPANIE FILTR] Strona załadowana, sprawdzam wyszukiwarkę...');
        addSearchBox();
    });



})();

// --- vSprint+ PANEL USTAWIEŃ ---
(function() {
    'use strict';
    const vSprintFeatures = [
        { key: 'oceny', label: 'Raport z ocen' },
        { key: 'filtr', label: 'Wyszukiwarka SKU/ID' },
        { key: 'info', label: 'vSprint info' },
        { key: 'img', label: 'Image/Desc Downloader' },
        { key: 'kampanie', label: 'Asystent Kampanii' },
        { key: 'kampFiltr', label: 'Filtr ofert w kampaniach' },
        { key: 'kopiujId', label: 'Kopiuj ID' },
        { key: 'edytuj', label: 'Edytuj' }
    ];
    function getVSprintSettings() {
        let settings = {};
        try { settings = JSON.parse(localStorage.getItem('vSprintPlusSettings') || '{}'); } catch (e) {}
        vSprintFeatures.forEach(f => { if (typeof settings[f.key] === 'undefined') settings[f.key] = true; });
        return settings;
    }
    function saveVSprintSettings(settings) {
        localStorage.setItem('vSprintPlusSettings', JSON.stringify(settings));
    }
    function createVSprintButton() {
        if (document.getElementById('vsprintplus-btn')) return;
        const btn = document.createElement('button');
        btn.id = 'vsprintplus-btn';
        btn.textContent = 'vS+';
        btn.style.position = 'fixed';
        btn.style.right = '0px';
        btn.style.bottom = '24px';
        btn.style.borderRadius = '16px 0 0 16px';
        btn.style.zIndex = '99999';
        btn.style.background = 'rgb(255, 90, 0)';
        btn.style.color = '#fff';
        btn.style.border = 'none';
        btn.style.padding = '10px 10px 10px 18px';
        btn.style.fontSize = '16px';
        btn.style.boxShadow = '0 2px 8px rgba(0,0,0,0.15)';
        btn.style.cursor = 'pointer';
        btn.style.transition = 'width 0.2s, min-width 0.2s, padding 0.2s, background 0.2s, color 0.2s';
        btn.style.overflow = 'hidden';
        btn.style.whiteSpace = 'nowrap';
        btn.style.width = '54px';
        btn.style.minWidth = '54px';
        btn.style.textAlign = 'center';
        btn.onmouseenter = function() {
            btn.textContent = 'vSprint Allegro+';
            btn.style.width = '148px';
            btn.style.minWidth = '148px';
            btn.style.padding = '10px 18px 10px 18px';
        };
        btn.onmouseleave = function() {
            btn.textContent = 'vS+';
            btn.style.width = '54px';
            btn.style.minWidth = '54px';
            btn.style.padding = '10px 10px 10px 18px';
        };
        btn.onclick = showVSprintPanel;
        document.body.appendChild(btn);
    }
    function showVSprintPanel() {
        if (document.getElementById('vsprintplus-modal')) return;
        const settings = getVSprintSettings();
        const modal = document.createElement('div');
        modal.id = 'vsprintplus-modal';
        modal.style.position = 'fixed';
        modal.style.right = '24px';
        modal.style.bottom = '70px';
        modal.style.background = '#fff';
        modal.style.border = '1.5px solid #ff5a00';
        modal.style.borderRadius = '12px';
        modal.style.boxShadow = '0 4px 24px rgba(0,0,0,0.18)';
        modal.style.padding = '28px 32px 20px 32px';
        modal.style.zIndex = '100000';
        modal.style.minWidth = '300px';
        modal.style.fontSize = '16px';
        modal.style.display = 'flex';
        modal.style.flexDirection = 'column';
        modal.style.gap = '14px';
        modal.style.fontFamily = 'inherit';
        // Nagłówek
        const title = document.createElement('div');
        title.textContent = 'vSprint Allegro+';
        title.style.fontWeight = 'bold';
        title.style.fontSize = '20px';
        title.style.marginBottom = '16px';
        title.style.color = '#ff5a00';
        title.style.letterSpacing = '1px';
        title.style.textAlign = 'center';
        modal.appendChild(title);
        // Checkboxy
        vSprintFeatures.forEach(f => {
            const row = document.createElement('label');
            row.style.display = 'flex';
            row.style.fontFamily = '"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif';
            row.style.alignItems = 'center';
            row.style.gap = '10px';
            row.style.color = '#23272e';
            row.style.fontSize = '16px';
            row.style.padding = '4px 0';
            const cb = document.createElement('input');
            cb.type = 'checkbox';
            cb.checked = !!settings[f.key];
            cb.style.width = '20px';
            cb.style.height = '20px';
            cb.style.accentColor = '#ff5a00';
            cb.onchange = function() {
                settings[f.key] = cb.checked;
                saveVSprintSettings(settings);
            };
            row.appendChild(cb);
            row.appendChild(document.createTextNode(f.label));
            modal.appendChild(row);
        });
        // Zamknięcie
        const closeBtn = document.createElement('button');
        closeBtn.textContent = 'Zamknij';
        closeBtn.style.marginTop = '22px';
        closeBtn.style.alignSelf = 'center';
        closeBtn.style.background = 'rgb(255, 90, 0)';
        closeBtn.style.color = '#fff';
        closeBtn.style.border = 'none';
        closeBtn.style.borderRadius = '8px';
        closeBtn.style.padding = '10px 28px';
        closeBtn.style.fontSize = '16px';
        closeBtn.style.cursor = 'pointer';
        closeBtn.style.fontWeight = 'bold';
        closeBtn.style.boxShadow = '0 2px 8px rgba(0,0,0,0.10)';
        closeBtn.onclick = () => modal.remove();
        modal.appendChild(closeBtn);
        document.body.appendChild(modal);
    }
    createVSprintButton();
})();

// --- ALLEGRO OFERTA PRZYCISKI ---
(function() {
    'use strict';

    // Sprawdzamy czy funkcje są włączone
    if (window.vSprintPlusSettings && window.vSprintPlusSettings.edytuj === false &&
        window.vSprintPlusSettings && window.vSprintPlusSettings.kopiujId === false) return;

    // Uruchamiaj tylko na stronach ofert (stary /oferta/ i nowy /produkt/)
    if (!window.location.href.match(/^https:\/\/allegro\.pl\/(oferta|produkt)\//)) {
        return;
    }

    // Funkcja do pobrania ID oferty z URL
    function getOfferIdFromUrl() {
        const url = window.location.href;
        const match = url.match(/offerId=(\d+)/);
        if (match) {
            return match[1];
        }
        return null;
    }

    // Funkcja do pobrania ID oferty z body JSON
    function getOfferIdFromBody() {
        const match = document.body.innerHTML.match(/"offerId":"(\d+)"/);
        if (match) {
            return match[1];
        }
        return null;
    }

    // Funkcja do pobrania ID oferty z meta description
    function getOfferIdFromMetaDescription() {
        const metaDescription = document.querySelector('meta[name="description"]');
        if (metaDescription) {
            const content = metaDescription.getAttribute('content');
            const match = content.match(/Oferta (\d+)$/);
            if (match) {
                return match[1];
            }
        }
        return null;
    }

    // Funkcja do pobrania ID oferty z canonical link
    function getOfferIdFromCanonical() {
        const canonicalLink = document.querySelector('link[rel="canonical"]');
        if (canonicalLink) {
            const href = canonicalLink.getAttribute('href');
            const match = href.match(/-(\d+)$/);
            if (match) {
                return match[1];
            }
        }
        return null;
    }

    // Funkcja do pobrania ID oferty (próbuje wszystkie metody)
    function getOfferId() {
        return getOfferIdFromUrl() ||
               getOfferIdFromBody() ||
               getOfferIdFromMetaDescription() ||
               getOfferIdFromCanonical();
    }

    // Funkcja do kopiowania ID do schowka (używamy tej samej co wcześniej)
    function copyToClipboard(text) {
        if (typeof GM_setClipboard !== 'undefined') {
            GM_setClipboard(text);
            showCopyNotification('ID skopiowane do schowka!');
        } else {
            if (navigator.clipboard && window.isSecureContext) {
                navigator.clipboard.writeText(text).then(function() {
                    showCopyNotification('ID skopiowane do schowka!');
                }).catch(function(err) {
                    console.error('Błąd kopiowania do schowka:', err);
                    fallbackCopyTextToClipboard(text);
                });
            } else {
                fallbackCopyTextToClipboard(text);
            }
        }
    }

    // Fallback funkcja kopiowania
    function fallbackCopyTextToClipboard(text) {
        var textArea = document.createElement("textarea");
        textArea.value = text;
        textArea.style.top = "0";
        textArea.style.left = "0";
        textArea.style.position = "fixed";
        textArea.style.opacity = "0";
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();

        try {
            var successful = document.execCommand('copy');
            if (successful) {
                showCopyNotification('ID skopiowane do schowka!');
            } else {
                showCopyNotification('Nie udało się skopiować ID', 'error');
            }
        } catch (err) {
            console.error('Błąd kopiowania:', err);
            showCopyNotification('Nie udało się skopiować ID', 'error');
        }

        document.body.removeChild(textArea);
    }

    // Funkcja do wyświetlania powiadomienia
    function showCopyNotification(message, type) {
        var existingNotification = document.querySelector('.copy-notification');
        if (existingNotification) {
            existingNotification.remove();
        }

        var notification = document.createElement('div');
        notification.className = 'copy-notification';
        notification.textContent = message;
        notification.style.position = 'fixed';
        notification.style.top = '20px';
        notification.style.right = '20px';
        notification.style.backgroundColor = type === 'error' ? '#dc3545' : '#28a745';
        notification.style.color = '#fff';
        notification.style.padding = '12px 20px';
        notification.style.borderRadius = '5px';
        notification.style.zIndex = '10001';
        notification.style.fontSize = '14px';
        notification.style.fontWeight = 'bold';
        notification.style.boxShadow = '0 2px 10px rgba(0,0,0,0.3)';
        notification.style.transition = 'opacity 0.3s ease';

        document.body.appendChild(notification);

        setTimeout(function() {
            notification.style.opacity = '0';
            setTimeout(function() {
                if (notification.parentNode) {
                    notification.parentNode.removeChild(notification);
                }
            }, 300);
        }, 3000);
    }

    // Funkcja do otwierania strony edycji oferty
    function openEditPage(offerId) {
        if (!offerId) {
            showCopyNotification('Nie udało się pobrać ID oferty', 'error');
            return;
        }

        const editUrl = `https://salescenter.allegro.com/offer/${offerId}`;
        window.open(editUrl, '_blank');
        showCopyNotification('Otwieranie strony edycji oferty...', 'success');
    }

    // Funkcja do tworzenia przycisków na stronie oferty
    function createOfferButtons() {
        // Sprawdzamy czy przyciski już istnieją
        if (document.querySelector('.offer-edytuj-btn') || document.querySelector('.offer-copy-id-btn')) {
            return;
        }

        const offerId = getOfferId();
        if (!offerId) {
            console.log('Nie udało się pobrać ID oferty');
            return;
        }

        // Znajdujemy kontener na przyciski (np. nagłówek oferty)
        const targetContainer = document.querySelector('[data-role="offer-header"]') ||
                               document.querySelector('.offer-header') ||
                               document.querySelector('h1') ||
                               document.querySelector('.offer-title') ||
                               document.body;

        if (!targetContainer) {
            console.log('Nie znaleziono kontenera na przyciski');
            return;
        }

        // Tworzymy kontener na przyciski
        const buttonContainer = document.createElement('div');
        buttonContainer.style.position = 'relative';
        buttonContainer.style.marginTop = '10px';
        buttonContainer.style.marginBottom = '10px';
        buttonContainer.style.display = 'flex';
        buttonContainer.style.gap = '10px';
        buttonContainer.style.flexWrap = 'wrap';

        // Przycisk Edytuj (jeśli funkcja włączona)
        if (window.vSprintPlusSettings && window.vSprintPlusSettings.edytuj !== false) {
            const edytujButton = document.createElement('button');
            edytujButton.className = 'offer-edytuj-btn';
            edytujButton.innerHTML = 'Edytuj';
            edytujButton.style.padding = '10px 16px';
            edytujButton.style.backgroundColor = '#6c757d';
            edytujButton.style.color = '#fff';
            edytujButton.style.border = 'none';
            edytujButton.style.borderRadius = '5px';
            edytujButton.style.cursor = 'pointer';
            edytujButton.style.fontSize = '14px';
            edytujButton.style.fontWeight = 'bold';
            edytujButton.style.transition = 'background 0.2s';

            edytujButton.onmouseenter = function() {
                edytujButton.style.backgroundColor = '#5a6268';
            };
            edytujButton.onmouseleave = function() {
                edytujButton.style.backgroundColor = '#6c757d';
            };

            edytujButton.onclick = function(event) {
                event.preventDefault();
                openEditPage(offerId);
            };

            buttonContainer.appendChild(edytujButton);
        }

        // Przycisk Kopiuj ID (jeśli funkcja włączona)
        if (window.vSprintPlusSettings && window.vSprintPlusSettings.kopiujId !== false) {
            const copyIdButton = document.createElement('button');
            copyIdButton.className = 'offer-copy-id-btn';
            copyIdButton.innerHTML = 'Kopiuj ID';
            copyIdButton.style.padding = '10px 16px';
            copyIdButton.style.backgroundColor = '#28a745';
            copyIdButton.style.color = '#fff';
            copyIdButton.style.border = 'none';
            copyIdButton.style.borderRadius = '5px';
            copyIdButton.style.cursor = 'pointer';
            copyIdButton.style.fontSize = '14px';
            copyIdButton.style.fontWeight = 'bold';
            copyIdButton.style.transition = 'background 0.2s';

            copyIdButton.onmouseenter = function() {
                copyIdButton.style.backgroundColor = '#218838';
            };
            copyIdButton.onmouseleave = function() {
                copyIdButton.style.backgroundColor = '#28a745';
            };

            copyIdButton.onclick = function(event) {
                event.preventDefault();
                copyToClipboard(offerId);
            };

            buttonContainer.appendChild(copyIdButton);
        }

        // Dodajemy kontener do strony (po elemencie, nie jako dziecko)
        if (targetContainer.tagName === 'H1' || targetContainer.tagName === 'BODY') {
            targetContainer.insertAdjacentElement('afterend', buttonContainer);
        } else {
            targetContainer.appendChild(buttonContainer);
        }

        console.log('Przyciski oferty dodane, ID:', offerId);
    }

    // Inicjalizacja - czekamy na załadowanie strony
    let attempts = 0;
    const maxAttempts = 10;

    function tryCreateButtons() {
        attempts++;
        const offerId = getOfferId();
        const h1 = document.querySelector('h1');

        if (offerId && h1) {
            createOfferButtons();
            return true;
        }

        if (attempts < maxAttempts) {
            setTimeout(tryCreateButtons, 500);
        }
        return false;
    }

    function init() {
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', tryCreateButtons);
        } else {
            tryCreateButtons();
        }

        const observer = new MutationObserver(function(mutations) {
            if (document.querySelector('.offer-edytuj-btn') || document.querySelector('.offer-copy-id-btn')) {
                return;
            }
            if (document.querySelector('h1') && getOfferId()) {
                createOfferButtons();
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    init();
})();

// --- COSTS SUMMARY TRACKER ---
(function() {
    'use strict';

    if (!window.location.href.match(/^https:\/\/salescenter\.allegro\.com\/costs-summary/)) {
        return;
    }

    const STORAGE_KEY = 'vSprintPlusCostsData';
    const THRESHOLD_KEY = 'vSprintPlusMaxFeeThreshold';

    function getAccountThreshold(account) {
        const thresholds = JSON.parse(localStorage.getItem(THRESHOLD_KEY) || '{}');
        return thresholds[account] || null;
    }

    function setAccountThreshold(account, threshold) {
        const thresholds = JSON.parse(localStorage.getItem(THRESHOLD_KEY) || '{}');
        if (threshold === null || threshold === '') {
            delete thresholds[account];
        } else {
            thresholds[account] = parseFloat(threshold);
        }
        localStorage.setItem(THRESHOLD_KEY, JSON.stringify(thresholds));
    }

    function parseAmount(text) {
        if (!text) return 0;
        const clean = text.replace(/[^\d,.-]/g, '').replace(/\s/g, '').replace(',', '.');
        return parseFloat(clean) || 0;
    }

    function getAccountName() {
        const accountSpan = document.querySelector('div[data-testid="accountInfo"] span');
        return accountSpan ? accountSpan.textContent.trim() : 'unknown';
    }

    function getDateKey() {
        const dateInput = document.querySelector('input#Data\\ do');
        if (dateInput && dateInput.value) {
            const value = dateInput.value;
            const parts = value.split(' ');
            if (parts.length === 3) {
                const day = parts[0];
                const monthNames = ['stycznia', 'lutego', 'marca', 'kwietnia', 'maja', 'czerwca', 'lipca', 'sierpnia', 'września', 'października', 'listopada', 'grudnia'];
                const monthIndex = monthNames.indexOf(parts[1].toLowerCase());
                const year = parts[2];
                if (monthIndex !== -1) {
                    return `${year}-${String(monthIndex + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
                }
            }
            const dotParts = value.split('.');
            if (dotParts.length === 3) {
                return `${dotParts[2]}-${dotParts[1]}-${dotParts[0]}`;
            }
        }
        const now = new Date();
        return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
    }

    function extractCostsData() {
        const data = {
            date: getDateKey(),
            account: getAccountName(),
            timestamp: Date.now(),
            details: {}
        };

        const summarySection = Array.from(document.querySelectorAll('h2')).find(h => h.textContent.includes('Podsumowanie'));
        if (summarySection) {
            const container = summarySection.closest('.msts_pt') || summarySection.parentElement;
            const rows = container.querySelectorAll('.m7f5_sf');
            
            rows.forEach(row => {
                const labelEl = row.querySelector('.mzaq_56 strong, .mzaq_56 span');
                const valueEl = row.querySelector('.mzmg_f9 span[lang]');
                
                if (labelEl && valueEl) {
                    const label = labelEl.textContent.trim();
                    const value = parseAmount(valueEl.textContent);
                    
                    if (label.includes('Wartość sprzedaży') && label.includes('dostawy')) {
                        data.salesAndDelivery = value;
                    } else if (label === 'Opłaty') {
                        data.totalFees = value;
                    } else if (label === 'Obowiązkowe') {
                        data.mandatoryFees = value;
                    } else if (label === 'Dostawa') {
                        data.deliveryFees = value;
                    } else if (label.includes('Reklama') || label.includes('promowanie')) {
                        data.advertisingFees = value;
                    } else if (label === 'Abonament') {
                        data.subscriptionFees = value;
                    }
                }
            });
        }

        const allLabelEls = document.querySelectorAll('[data-testid$="-table-label-name"]');
        allLabelEls.forEach(labelEl => {
            const testId = labelEl.getAttribute('data-testid');
            const label = labelEl.textContent.trim();
            const prefix = testId.replace('-table-label-name', '');
            const valueEl = document.querySelector(`[data-testid="${prefix}-table-label-value"]`);
            
            if (valueEl) {
                const value = parseAmount(valueEl.textContent);
                if (value !== 0 && !label.includes('Wartość sprzedaży')) {
                    data.details[label] = value;
                }
            }
        });

        console.log('Extracted data:', data);
        return data;
    }

    function checkDataExists(account, date) {
        try {
            const allData = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
            return allData[account] && allData[account][date];
        } catch (e) {
            return false;
        }
    }

    function saveData(data, forceOverwrite = false, silent = false) {
        if (!data || !data.account) return false;

        let allData = {};
        try {
            allData = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
        } catch (e) {}

        if (!forceOverwrite && allData[data.account] && allData[data.account][data.date]) {
            if (!silent) showNotification('Dane z ' + data.date + ' już istnieją', 'warning');
            return false;
        }

        if (!allData[data.account]) {
            allData[data.account] = {};
        }

        allData[data.account][data.date] = {
            salesAndDelivery: data.salesAndDelivery || 0,
            totalFees: data.totalFees || 0,
            mandatoryFees: data.mandatoryFees || 0,
            deliveryFees: data.deliveryFees || 0,
            advertisingFees: data.advertisingFees || 0,
            subscriptionFees: data.subscriptionFees || 0,
            details: data.details || {},
            timestamp: data.timestamp
        };

        try {
            localStorage.setItem(STORAGE_KEY, JSON.stringify(allData));
            if (!silent) showNotification('Dane zapisane: ' + data.date);
            return true;
        } catch (e) {
            showNotification('Błąd zapisu danych', 'error');
            return false;
        }
    }

    function showNotification(message, type = 'success') {
        const notification = document.createElement('div');
        notification.textContent = message;
        const colors = {
            success: '#28a745',
            error: '#dc3545',
            warning: '#ffc107'
        };
        notification.style.cssText = `
            position: fixed;
            top: 80px;
            right: 20px;
            padding: 12px 20px;
            background: ${colors[type] || colors.success};
            color: ${type === 'warning' ? '#333' : 'white'};
            border-radius: 5px;
            font-size: 14px;
            font-weight: bold;
            z-index: 99999;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);
        `;
        document.body.appendChild(notification);
        setTimeout(() => notification.remove(), 3000);
    }

    function showThresholdModal(account, currentValue, onSave) {
        const existing = document.getElementById('vSprint-threshold-modal');
        if (existing) existing.remove();

        const modal = document.createElement('div');
        modal.id = 'vSprint-threshold-modal';
        modal.style.cssText = `
            position: fixed;
            top: 0; left: 0; right: 0; bottom: 0;
            background: rgba(0,0,0,0.5);
            z-index: 200000;
            display: flex;
            align-items: center;
            justify-content: center;
        `;

        modal.innerHTML = `
            <div style="background: #fff; border-radius: 8px; padding: 24px; width: 360px; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
                <h3 style="margin: 0 0 16px 0; font-size: 16px; color: #333;">⚙️ Maksymalny próg kosztów</h3>
                <p style="margin: 0 0 12px 0; font-size: 13px; color: #666;">Konto: <strong>${account}</strong></p>
                <input type="number" id="vSprint-threshold-input" value="${currentValue || ''}" min="0" max="100" step="0.1" placeholder="np. 25" style="width: 100%; padding: 10px 12px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; box-sizing: border-box;">
                <p style="margin: 8px 0 0 0; font-size: 11px; color: #999;">Wpisz wartość 0-100%. Zostaw puste aby usunąć próg.</p>
                <div style="margin-top: 20px; display: flex; gap: 10px; justify-content: flex-end;">
                    <button id="vSprint-threshold-cancel" style="padding: 8px 16px; background: #f0f0f0; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">Anuluj</button>
                    <button id="vSprint-threshold-save" style="padding: 8px 20px; background: #ff5a00; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; font-weight: 500;">Zapisz</button>
                </div>
            </div>
        `;

        document.body.appendChild(modal);
        const input = document.getElementById('vSprint-threshold-input');
        input.focus();
        input.select();

        const close = () => modal.remove();

        modal.onclick = (e) => { if (e.target === modal) close(); };
        document.getElementById('vSprint-threshold-cancel').onclick = close;
        document.getElementById('vSprint-threshold-save').onclick = () => {
            const val = input.value.trim();
            onSave(val === '' ? null : parseFloat(val));
            close();
        };
        input.onkeydown = (e) => {
            if (e.key === 'Enter') document.getElementById('vSprint-threshold-save').click();
            if (e.key === 'Escape') close();
        };
    }

    function formatCurrency(amount) {
        return new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN' }).format(amount);
    }

    function formatDate(dateStr) {
        const parts = dateStr.split('-');
        return `${parts[2]}.${parts[1]}`;
    }

    function createDetailedDataPanel(date, account, details, summaryHtml = '') {
        const existingDetail = document.getElementById('vSprint-detail-panel');
        if (existingDetail) existingDetail.remove();

        const panel = document.createElement('div');
        panel.id = 'vSprint-detail-panel';
        panel.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 750px;
            max-height: 85vh;
            overflow-y: auto;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.3);
            z-index: 100000;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        `;

        let detailRows = '';
        const sortedDetails = Object.entries(details).sort((a, b) => a[0].localeCompare(b[0]));
        sortedDetails.forEach(([label, value]) => {
            const color = value < 0 ? '#dc3545' : '#28a745';
            detailRows += `
                <tr>
                    <td style="padding: 10px 12px; border-bottom: 1px solid #eee;">${label}</td>
                    <td style="padding: 10px 12px; border-bottom: 1px solid #eee; text-align: right; color: ${color}; font-weight: 500;">${formatCurrency(value)}</td>
                </tr>
            `;
        });

        panel.innerHTML = `
            <div style="background: #ff5a00; color: white; padding: 18px 20px; border-radius: 8px 8px 0 0; display: flex; justify-content: space-between; align-items: center;">
                <h3 style="margin: 0; font-size: 18px;">📋 ${formatDate(date)}</h3>
                <button id="vSprint-close-detail" style="background: none; border: none; color: white; font-size: 24px; cursor: pointer;">✕</button>
            </div>
            <div style="padding: 20px;">
                <p style="margin: 0 0 15px 0; color: #666; font-size: 14px;">Konto: <strong>${account}</strong></p>
                ${summaryHtml}
                <table style="width: 100%; border-collapse: collapse; font-size: 14px;">
                    <thead>
                        <tr style="background: #f5f5f5;">
                            <th style="padding: 12px; text-align: left; border-bottom: 2px solid #ddd;">Pozycja</th>
                            <th style="padding: 12px; text-align: right; border-bottom: 2px solid #ddd;">Kwota</th>
                        </tr>
                    </thead>
                    <tbody>
                        ${detailRows}
                    </tbody>
                </table>
            </div>
        `;

        document.body.appendChild(panel);
        document.getElementById('vSprint-close-detail').onclick = () => panel.remove();
        panel.onclick = (e) => {
            if (e.target === panel) panel.remove();
        };
    }

    function getMonthName(monthNum) {
        const months = ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 
                       'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień'];
        return months[monthNum - 1] || '';
    }

    function deleteReport(account, date) {
        let allData = {};
        try {
            allData = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
        } catch (e) { return; }
        
        if (allData[account] && allData[account][date]) {
            delete allData[account][date];
            localStorage.setItem(STORAGE_KEY, JSON.stringify(allData));
            showNotification('Usunięto: ' + formatDate(date));
        }
    }

    function createPanel(showAllAccounts = false) {
        const existingPanel = document.getElementById('vSprint-costs-panel');
        if (existingPanel) {
            existingPanel.remove();
            return;
        }

        const panel = document.createElement('div');
        panel.id = 'vSprint-costs-panel';
        panel.style.cssText = `
            position: fixed;
            top: 80px;
            right: 20px;
            width: 720px;
            max-height: 85vh;
            overflow-y: auto;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.15);
            z-index: 99998;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        `;

        let allData = {};
        try {
            allData = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
        } catch (e) {}

        const currentAccount = getAccountName();
        const allAccounts = Object.keys(allData);
        const accountsToShow = showAllAccounts ? allAccounts : allAccounts.filter(a => a === currentAccount);

        let html = `
            <div style="background: #ff5a00; color: white; padding: 18px 20px; border-radius: 8px 8px 0 0; display: flex; justify-content: space-between; align-items: center;">
                <h3 style="margin: 0; font-size: 18px;">📊 Historia kosztów</h3>
                <div style="display: flex; gap: 10px; align-items: center;">
                    <button id="vSprint-toggle-accounts" style="background: rgba(255,255,255,0.2); color: white; border: none; border-radius: 4px; padding: 6px 12px; cursor: pointer; font-size: 12px;">${showAllAccounts ? 'Pokaż moje' : 'Wszystkie konta'}</button>
                    <button id="vSprint-close-panel" style="background: none; border: none; color: white; font-size: 24px; cursor: pointer;">✕</button>
                </div>
            </div>
            <div style="padding: 20px;">
        `;

        if (accountsToShow.length === 0) {
            html += '<p style="color: #666; text-align: center; font-size: 14px;">Brak zapisanych danych' + (!showAllAccounts && allAccounts.length > 0 ? ' dla tego konta' : '') + '</p>';
        } else {
            accountsToShow.forEach(account => {
                const accountData = allData[account];
                const allDates = Object.keys(accountData).sort().reverse();
                
                const groupedByMonth = {};
                allDates.forEach(date => {
                    const [year, month] = date.split('-');
                    const key = `${year}-${month}`;
                    if (!groupedByMonth[key]) {
                        groupedByMonth[key] = { year, month, dates: [] };
                    }
                    groupedByMonth[key].dates.push(date);
                });

                const accountThreshold = getAccountThreshold(account);
                
                html += `
                    <div style="margin-bottom: 25px;">
                        <div style="margin: 0 0 12px 0; padding-bottom: 8px; border-bottom: 2px solid #ff5a00; display: flex; justify-content: space-between; align-items: center;">
                            <h4 style="margin: 0; color: #333; font-size: 16px;">👤 ${account}${account === currentAccount ? ' (obecne)' : ''}</h4>
                            <div style="display: flex; align-items: center; gap: 8px;">
                                ${accountThreshold !== null ? `<span style="background: #28a745; color: white; padding: 3px 8px; border-radius: 4px; font-size: 11px; font-weight: 600;">max: ${accountThreshold}%</span>` : ''}
                                <button class="vSprint-threshold-btn" data-account="${account}" style="background: none; color: #ff5a00; border: 1px solid #ff5a00; border-radius: 4px; padding: 3px 8px; cursor: pointer; font-size: 11px; font-weight: 500;">⚙️ próg</button>
                            </div>
                        </div>
                `;

                Object.entries(groupedByMonth).forEach(([monthKey, monthData]) => {
                    html += `
                        <div style="margin-bottom: 15px;">
                            <div style="background: #f8f9fa; padding: 8px 12px; border-radius: 4px; margin-bottom: 8px; font-weight: 500; color: #495057; font-size: 13px;">
                                📅 ${getMonthName(parseInt(monthData.month))} ${monthData.year}
                            </div>
                            <table style="width: 100%; border-collapse: collapse; font-size: 13px;">
                                <thead>
                                    <tr style="background: #f5f5f5;">
                                        <th style="padding: 8px; text-align: left; border-bottom: 2px solid #ddd;">Data</th>
                                        <th style="padding: 8px; text-align: right; border-bottom: 2px solid #ddd;">Sprzedaż</th>
                                        <th style="padding: 8px; text-align: right; border-bottom: 2px solid #ddd;">Opłaty</th>
                                        <th style="padding: 8px; text-align: right; border-bottom: 2px solid #ddd;">%</th>
                                        <th style="padding: 8px; text-align: center; border-bottom: 2px solid #ddd; width: 100px;"></th>
                                    </tr>
                                </thead>
                                <tbody>
                    `;

                    monthData.dates.forEach((date, indexInMonth) => {
                        const d = accountData[date];
                        const feePercent = d.salesAndDelivery > 0 ? ((Math.abs(d.totalFees) / d.salesAndDelivery) * 100).toFixed(1) : '0';
                        const globalIndex = allDates.indexOf(date);
                        
                        if (globalIndex < allDates.length - 1) {
                            const prevDate = allDates[globalIndex + 1];
                            const prevData = accountData[prevDate];
                            
                            const salesDiff = prevData.salesAndDelivery > 0 
                                ? ((d.salesAndDelivery - prevData.salesAndDelivery) / prevData.salesAndDelivery * 100).toFixed(1)
                                : null;
                            
                            const feesDiff = Math.abs(prevData.totalFees) > 0 
                                ? ((Math.abs(d.totalFees) - Math.abs(prevData.totalFees)) / Math.abs(prevData.totalFees) * 100).toFixed(1)
                                : null;
                            
                            const prevFeePercent = prevData.salesAndDelivery > 0 
                                ? ((Math.abs(prevData.totalFees) / prevData.salesAndDelivery) * 100).toFixed(1)
                                : '0';
                            const feePercentDiff = (parseFloat(feePercent) - parseFloat(prevFeePercent)).toFixed(1);
                            
                            const salesDiffDisplay = salesDiff !== null ? (parseFloat(salesDiff) >= 0 ? `+${salesDiff}%` : `${salesDiff}%`) : '';
                            const feesDiffDisplay = feesDiff !== null ? (parseFloat(feesDiff) >= 0 ? `+${feesDiff}%` : `${feesDiff}%`) : '';
                            const feePercentDiffDisplay = parseFloat(feePercentDiff) >= 0 ? `+${feePercentDiff}` : feePercentDiff;
                            
                            const salesColor = parseFloat(salesDiff) >= 0 ? '#28a745' : '#dc3545';
                            const feesColor = parseFloat(feesDiff) >= 0 ? '#dc3545' : '#28a745';
                            const feePercentColor = parseFloat(feePercentDiff) >= 0 ? '#dc3545' : '#28a745';
                            
                            const salesCell = `<span style="color: #28a745; font-weight: 500;">${formatCurrency(d.salesAndDelivery)}</span>${salesDiffDisplay ? `<br><small style="font-size: 10px; color: ${salesColor};" title="vs ${formatDate(prevDate)}">${salesDiffDisplay}</small>` : ''}`;
                            const feesCell = `<span style="color: #dc3545; font-weight: 500;">${formatCurrency(d.totalFees)}</span>${feesDiffDisplay ? `<br><small style="font-size: 10px; color: ${feesColor};" title="vs ${formatDate(prevDate)}">${feesDiffDisplay}</small>` : ''}`;
                            const percentCell = `<span style="font-weight: bold;">${feePercent}%</span><br><small style="font-size: 10px; color: ${feePercentColor};" title="vs ${formatDate(prevDate)}">${feePercentDiffDisplay}pp</small>`;
                            
                            html += `
                                <tr>
                                    <td style="padding: 8px; border-bottom: 1px solid #eee;">${formatDate(date)}</td>
                                    <td style="padding: 8px; text-align: right; border-bottom: 1px solid #eee;">${salesCell}</td>
                                    <td style="padding: 8px; text-align: right; border-bottom: 1px solid #eee;">${feesCell}</td>
                                    <td style="padding: 8px; text-align: right; border-bottom: 1px solid #eee;">${percentCell}</td>
                                    <td style="padding: 8px; text-align: center; border-bottom: 1px solid #eee; white-space: nowrap;">
                                        <button class="vSprint-more-btn" data-date="${date}" data-account="${account}" style="background: none; color: #ff5a00; border: none; cursor: pointer; font-size: 11px; text-decoration: underline; padding: 2px 4px;">Więcej</button>
                                        <button class="vSprint-delete-btn" data-date="${date}" data-account="${account}" style="background: none; color: #999; border: none; cursor: pointer; font-size: 11px; padding: 2px 4px;" title="Usuń ten raport">🗑️</button>
                                    </td>
                                </tr>
                            `;
                        } else {
                            html += `
                                <tr>
                                    <td style="padding: 8px; border-bottom: 1px solid #eee;">${formatDate(date)}</td>
                                    <td style="padding: 8px; text-align: right; border-bottom: 1px solid #eee; color: #28a745; font-weight: 500;">${formatCurrency(d.salesAndDelivery)}</td>
                                    <td style="padding: 8px; text-align: right; border-bottom: 1px solid #eee; color: #dc3545; font-weight: 500;">${formatCurrency(d.totalFees)}</td>
                                    <td style="padding: 8px; text-align: right; border-bottom: 1px solid #eee; font-weight: bold;">${feePercent}%</td>
                                    <td style="padding: 8px; text-align: center; border-bottom: 1px solid #eee; white-space: nowrap;">
                                        <button class="vSprint-more-btn" data-date="${date}" data-account="${account}" style="background: none; color: #ff5a00; border: none; cursor: pointer; font-size: 11px; text-decoration: underline; padding: 2px 4px;">Więcej</button>
                                        <button class="vSprint-delete-btn" data-date="${date}" data-account="${account}" style="background: none; color: #999; border: none; cursor: pointer; font-size: 11px; padding: 2px 4px;" title="Usuń ten raport">🗑️</button>
                                    </td>
                                </tr>
                            `;
                        }
                    });

                    html += `
                                </tbody>
                            </table>
                        </div>
                    `;
                });

                html += `</div>`;
            });
        }

        html += `
        `;

        panel.innerHTML = html;
        document.body.appendChild(panel);

        document.getElementById('vSprint-close-panel').onclick = () => panel.remove();
        document.getElementById('vSprint-toggle-accounts').onclick = () => {
            panel.remove();
            createPanel(!showAllAccounts);
        };

        panel.querySelectorAll('.vSprint-more-btn').forEach(btn => {
            btn.onclick = (e) => {
                e.stopPropagation();
                const date = btn.dataset.date;
                const account = btn.dataset.account;
                const d = allData[account]?.[date];
                if (!d) return;
                
                const details = d.details || {};
                const summaryHtml = `
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 15px; padding-bottom: 15px; border-bottom: 1px solid #eee;">
                        <span style="font-weight: 500;">Obowiązkowe:</span><span style="text-align: right; color: #dc3545;">${formatCurrency(d.mandatoryFees)}</span>
                        <span style="font-weight: 500;">Dostawa:</span><span style="text-align: right; color: #dc3545;">${formatCurrency(d.deliveryFees)}</span>
                        <span style="font-weight: 500;">Reklama:</span><span style="text-align: right; color: #dc3545;">${formatCurrency(d.advertisingFees)}</span>
                        <span style="font-weight: 500;">Abonament:</span><span style="text-align: right; color: #dc3545;">${formatCurrency(d.subscriptionFees)}</span>
                    </div>
                `;
                createDetailedDataPanel(date, account, details, summaryHtml);
            };
        });

        panel.querySelectorAll('.vSprint-delete-btn').forEach(btn => {
            btn.onclick = (e) => {
                e.stopPropagation();
                const date = btn.dataset.date;
                const account = btn.dataset.account;
                if (confirm(`Usunąć raport z ${formatDate(date)}?`)) {
                    deleteReport(account, date);
                    panel.remove();
                    createPanel(showAllAccounts);
                }
            };
        });

        panel.querySelectorAll('.vSprint-threshold-btn').forEach(btn => {
            btn.onclick = (e) => {
                e.stopPropagation();
                const account = btn.dataset.account;
                const currentVal = getAccountThreshold(account);
                showThresholdModal(account, currentVal, (newThreshold) => {
                    if (newThreshold === null) {
                        setAccountThreshold(account, null);
                        showNotification('Usunięto próg kosztów');
                    } else if (isNaN(newThreshold) || newThreshold < 0 || newThreshold > 100) {
                        showNotification('Nieprawidłowa wartość (0-100)', 'error');
                        return;
                    } else {
                        setAccountThreshold(account, newThreshold);
                        showNotification(`Ustawiono próg: ${newThreshold}%`);
                    }
                    panel.remove();
                    createPanel(showAllAccounts);
                });
            };
        });
    }

    function createSaveButton() {
        if (document.getElementById('vSprint-save-btn')) return;

        const downloadIcon = document.querySelector('span[data-testid="download-report-button"]');
        const downloadBtn = downloadIcon ? downloadIcon.closest('button') : null;
        if (!downloadBtn) {
            const btns = document.querySelectorAll('button');
            for (const btn of btns) {
                if (btn.textContent.includes('Pobierz raport')) {
                    return createSaveButtonNextTo(btn);
                }
            }
            return;
        }

        createSaveButtonNextTo(downloadBtn);
    }

    function createSaveButtonNextTo(downloadBtn) {
        if (document.getElementById('vSprint-save-btn')) return;

        const saveBtn = document.createElement('button');
        saveBtn.id = 'vSprint-save-btn';
        saveBtn.type = 'button';
        saveBtn.innerHTML = '💾 Zapamiętaj';
        saveBtn.style.cssText = `
            margin-right: 8px;
            padding: 0 12px;
            height: 32px;
            background: #ff5a00;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 13px;
            font-weight: 500;
            display: inline-flex;
            align-items: center;
            gap: 4px;
            transition: background 0.2s;
            white-space: nowrap;
        `;
        saveBtn.onmouseenter = () => saveBtn.style.background = '#e64d00';
        saveBtn.onmouseleave = () => saveBtn.style.background = '#ff5a00';
        saveBtn.onclick = () => {
            const data = extractCostsData();
            if (data && data.salesAndDelivery) {
                const exists = checkDataExists(data.account, data.date);
                if (exists) {
                    if (confirm('Dane z ' + data.date + ' już istnieją. Czy chcesz je nadpisać?')) {
                        saveData(data, true);
                    }
                } else {
                    saveData(data);
                }
            } else {
                showNotification('Nie udało się pobrać danych', 'error');
            }
        };

        downloadBtn.insertAdjacentElement('beforebegin', saveBtn);
    }

    function createFloatingButton() {
        if (document.getElementById('vSprint-costs-btn')) return;

        const btn = document.createElement('button');
        btn.id = 'vSprint-costs-btn';
        btn.innerHTML = '📊 Koszty';
        btn.style.cssText = `
            position: fixed;
            top: 80px;
            right: 20px;
            padding: 10px 16px;
            background: #ff5a00;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
            z-index: 99997;
            box-shadow: 0 2px 8px rgba(0,0,0,0.2);
            transition: background 0.2s;
        `;
        btn.onmouseenter = () => btn.style.background = '#e64d00';
        btn.onmouseleave = () => btn.style.background = '#ff5a00';
        btn.onclick = () => createPanel(false);
        document.body.appendChild(btn);
    }

    function showComparisonOnPage() {
        
        const allData = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
        const currentAccount = getAccountName();
        const accountData = allData[currentAccount];
        
        const currentDate = getDateKey();
        const currentData = accountData ? accountData[currentDate] : null;
        
        const summarySection = Array.from(document.querySelectorAll('h2')).find(h => h.textContent.includes('Podsumowanie'));
        if (!summarySection) return;
        
        const container = summarySection.closest('.msts_pt') || summarySection.parentElement;
        const rows = container.querySelectorAll('.m7f5_sf');
        
        const maxThreshold = getAccountThreshold(currentAccount);
        
        rows.forEach(row => {
            const labelEl = row.querySelector('.mzaq_56 strong, .mzaq_56 span');
            if (!labelEl) return;
            
            const label = labelEl.textContent.trim();
            const percentContainer = row.querySelector('.munh_8');
            if (!percentContainer) return;
            
            if (percentContainer.dataset.vsprintInit === '1') {
                if (!percentContainer.querySelector('.vSprint-threshold-badge') && !percentContainer.querySelector('.vSprint-set-threshold')) {
                    delete percentContainer.dataset.vsprintInit;
                } else {
                    return;
                }
            }
            percentContainer.dataset.vsprintInit = '1';
            
            percentContainer.style.position = 'relative';
            
            if (label === 'Opłaty') {
                const percentSpan = percentContainer.querySelector('span.mgn2_14');
                
                const liveData = extractCostsData();
                const currentFeePercent = liveData && liveData.salesAndDelivery > 0 
                    ? (Math.abs(liveData.totalFees) / liveData.salesAndDelivery * 100) 
                    : null;
                
                if (maxThreshold !== null) {
                    const overThreshold = currentFeePercent !== null && currentFeePercent > maxThreshold;
                    
                    if (overThreshold && percentSpan) {
                        percentSpan.style.background = 'rgba(220, 53, 69, 0.2)';
                        percentSpan.style.padding = '4px 8px';
                        percentSpan.style.borderRadius = '4px';
                        percentSpan.style.border = '1px solid rgba(220, 53, 69, 0.4)';
                    }
                    
                    const thresholdInfo = document.createElement('span');
                    thresholdInfo.className = 'vSprint-threshold-badge';
                    thresholdInfo.style.cssText = `
                        position: absolute;
                        left: -9px;
                        top: 23px;
                        padding: 4px 8px;
                        background: ${overThreshold ? '#dc3545' : '#28a745'};
                        color: white;
                        border-radius: 4px;
                        font-size: 12px;
                        font-weight: 400;
                        white-space: nowrap;
                        cursor: pointer;
                        box-shadow: 0 2px 4px rgba(0,0,0,0.2);
                    `;
                    thresholdInfo.innerHTML = `max: ${maxThreshold}%`;
                    thresholdInfo.title = `Kliknij aby zmienić próg (obecnie: ${maxThreshold}%)`;
                    percentContainer.appendChild(thresholdInfo);
                    
                } else {
                    const setBadge = document.createElement('span');
                    setBadge.className = 'vSprint-set-threshold';
                    setBadge.style.cssText = `
                        position: absolute;
                        left: -15px;
                        top: -23px;
                        padding: 4px 8px;
                        background: #17a2b8;
                        color: white;
                        border-radius: 4px;
                        font-size: 12px;
                        font-weight: 400;
                        white-space: nowrap;
                        cursor: pointer;
                        box-shadow: 0 2px 4px rgba(0,0,0,0.15);
                    `;
                    setBadge.innerHTML = '⚙️ ustaw max';
                    setBadge.title = 'Kliknij aby ustawić maksymalny próg kosztów';
                    percentContainer.appendChild(setBadge);
                }
                
                percentContainer.onclick = (e) => {
                    e.stopPropagation();
                    const currentVal = getAccountThreshold(currentAccount);
                    showThresholdModal(currentAccount, currentVal, (newThreshold) => {
                        if (newThreshold === null) {
                            setAccountThreshold(currentAccount, null);
                            showNotification('Usunięto próg kosztów');
                        } else if (isNaN(newThreshold) || newThreshold < 0 || newThreshold > 100) {
                            showNotification('Nieprawidłowa wartość (0-100)', 'error');
                            return;
                        } else {
                            setAccountThreshold(currentAccount, newThreshold);
                            showNotification(`Ustawiono próg: ${newThreshold}%`);
                        }
                        percentContainer.querySelector('.vSprint-threshold-badge')?.remove();
                        percentContainer.querySelector('.vSprint-set-threshold')?.remove();
                        delete percentContainer.dataset.vsprintInit;
                        showComparisonOnPage();
                    });
                };
            }
            
            if (!accountData || !currentData) return;
            
            const dates = Object.keys(accountData).sort().reverse();
            const currentIndex = dates.indexOf(currentDate);
            if (currentIndex === -1) return;
            
            let prevDate, prevData;
            if (currentIndex === 0) {
                if (dates.length < 2) return;
                prevDate = dates[1];
                prevData = accountData[prevDate];
            } else {
                prevDate = dates[0];
                prevData = accountData[prevDate];
            }
            
            let currentPercent = 0, prevPercent = 0, diff = 0;
            const salesAndDelivery = currentData.salesAndDelivery || 1;
            const prevSalesAndDelivery = prevData.salesAndDelivery || 1;
            
            if (label.includes('Wartość sprzedaży') && label.includes('dostawy')) {
                currentPercent = 100;
                prevPercent = 100;
            } else if (label === 'Opłaty') {
                currentPercent = salesAndDelivery > 0 ? (Math.abs(currentData.totalFees) / salesAndDelivery * 100) : 0;
                prevPercent = prevSalesAndDelivery > 0 ? (Math.abs(prevData.totalFees) / prevSalesAndDelivery * 100) : 0;
            } else if (label === 'Obowiązkowe') {
                currentPercent = salesAndDelivery > 0 ? (Math.abs(currentData.mandatoryFees) / salesAndDelivery * 100) : 0;
                prevPercent = prevSalesAndDelivery > 0 ? (Math.abs(prevData.mandatoryFees) / prevSalesAndDelivery * 100) : 0;
            } else if (label === 'Dostawa') {
                currentPercent = salesAndDelivery > 0 ? (Math.abs(currentData.deliveryFees) / salesAndDelivery * 100) : 0;
                prevPercent = prevSalesAndDelivery > 0 ? (Math.abs(prevData.deliveryFees) / prevSalesAndDelivery * 100) : 0;
            } else if (label.includes('Reklama') || label.includes('promowanie')) {
                currentPercent = salesAndDelivery > 0 ? (Math.abs(currentData.advertisingFees) / salesAndDelivery * 100) : 0;
                prevPercent = prevSalesAndDelivery > 0 ? (Math.abs(prevData.advertisingFees) / prevSalesAndDelivery * 100) : 0;
            } else if (label === 'Abonament') {
                currentPercent = salesAndDelivery > 0 ? (Math.abs(currentData.subscriptionFees) / salesAndDelivery * 100) : 0;
                prevPercent = prevSalesAndDelivery > 0 ? (Math.abs(prevData.subscriptionFees) / prevSalesAndDelivery * 100) : 0;
            } else {
                return;
            }
            
            diff = (currentPercent - prevPercent).toFixed(1);
            if (Math.abs(diff) < 0.05) return;
            
            if (percentContainer.querySelector('.vSprint-diff-badge')) return;
            
            const diffDisplay = parseFloat(diff) >= 0 ? `+${diff}%` : `${diff}%`;
            const color = parseFloat(diff) >= 0 ? '#dc3545' : '#28a745';
            
            const offsetLeft = 12;
            
            const diffBadge = document.createElement('span');
            diffBadge.className = 'vSprint-diff-badge';
            diffBadge.style.cssText = `
                position: absolute;
                left: 100%;
                top: 50%;
                transform: translateY(-50%);
                margin-left: ${offsetLeft}px;
                padding: 2px 6px;
                background: ${color};
                color: white;
                border-radius: 3px;
                font-size: 11px;
                font-weight: 500;
                cursor: help;
                white-space: nowrap;
            `;
            diffBadge.textContent = diffDisplay;
            diffBadge.title = `vs ${formatDate(prevDate)}`;
            
            percentContainer.appendChild(diffBadge);
        });
    }

    function autoSaveData() {
        const data = extractCostsData();
        if (!data || !data.salesAndDelivery) {
            console.log('Auto-save: no data to save');
            return;
        }
        
        const exists = checkDataExists(data.account, data.date);
        if (exists) {
            console.log('Auto-save: data already exists for', data.date);
            return;
        }
        
        if (saveData(data, false, true)) {
            console.log('Auto-save: saved successfully');
        }
    }

    function init() {
        createFloatingButton();

        let attempts = 0;
        const maxAttempts = 30;
        let autoSaved = false;

        function tryCreateSaveButton() {
            attempts++;
            createSaveButton();
            showComparisonOnPage();
            if (attempts === 3 && !autoSaved) {
                autoSaveData();
                autoSaved = true;
            }
            if (attempts < maxAttempts) {
                setTimeout(tryCreateSaveButton, 500);
            }
        }

        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', tryCreateSaveButton);
        } else {
            setTimeout(tryCreateSaveButton, 1000);
        }

        setInterval(() => {
            createSaveButton();
            showComparisonOnPage();
        }, 2000);

        let observerTimeout = null;
        const observer = new MutationObserver(() => {
            createFloatingButton();
            
            if (observerTimeout) clearTimeout(observerTimeout);
            observerTimeout = setTimeout(() => {
                createSaveButton();
                showComparisonOnPage();
            }, 300);
        });
        observer.observe(document.body, { childList: true, subtree: true });
    }

    init();
})();