Allegro+

Pakiet usprawnien do Allegro.pl

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==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();
})();