The West - Experience

Tracks and displays gained experience in The West with activity details, including reset functionality and draggable window

// ==UserScript==
// @name         The West - Experience
// @namespace    http://tampermonkey.net/
// @version      6.8
// @description  Tracks and displays gained experience in The West with activity details, including reset functionality and draggable window
// @author       DK, Shikokuchuo
// @include      https://*.the-west.*/game.php*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Inicjalizacja zmiennych
    let totalExperience = JSON.parse(localStorage.getItem('totalExperience')) || 0;
    let experienceLog = JSON.parse(localStorage.getItem('experienceLog')) || [];
    let savedPosition = JSON.parse(localStorage.getItem('experienceTrackerPosition')) || { top: '50px', left: 'auto', right: '310px' };
    let isCollectingHistory = false;
    let isPaused = false;
    let shouldCancel = false;
    let collectionStartTime = null;
    let processedPagesTime = [];
    let tempExpLog = [];
    let messageTimeout = null;
    let isTrackerVisible = JSON.parse(localStorage.getItem('experienceTrackerVisible')) !== false; // domyślnie widoczny

    // Dodajemy zmienną na nazwę gracza
    let playerName = Character.name;

    // Dodajemy nowe zmienne do przechowywania stanu kolekcji
    let collectionState = JSON.parse(localStorage.getItem('collectionState')) || {
        inProgress: false,
        currentPage: 1,
        folder: null,
        tempLog: [],
        totalPages: 0
    };

    // Funkcja do wyświetlania komunikatów
    function showError(message, duration = 5000) {
        if (messageTimeout) {
            clearTimeout(messageTimeout);
            messageTimeout = null;
        }

        const statusElement = document.querySelector('#collection-status');
        if (statusElement) {
            statusElement.innerHTML = `
                <div style="
                    background: rgba(0,0,0,0.7);
                    padding: 10px;
                    border-radius: 5px;
                    margin-top: 10px;
                    color: white;
                    text-align: center;
                    animation: fadeIn 0.3s ease-in-out;
                ">
                    ${message}
                </div>
            `;

            if (duration > 0) {
                messageTimeout = setTimeout(() => {
                    if (statusElement) {
                        statusElement.innerHTML = '';
                    }
                    messageTimeout = null;
                }, duration);
            }
        }
    }

    // Funkcja do pokazywania komunikatu o postępie
    function showProgress(message) {
        const statusElement = document.querySelector('#collection-status');
        if (statusElement) {
            statusElement.innerHTML = `
                <div style="
                    background: rgba(0,0,0,0.7);
                    padding: 10px;
                    border-radius: 5px;
                    margin-top: 10px;
                    color: white;
                    text-align: center;
                ">
                    ${message}
                </div>
            `;
        }
    }

    // Dodaj style CSS dla animacji
    const style = document.createElement('style');
    style.textContent = `
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }
    `;
    document.head.appendChild(style);

    // Funkcja do aktualizacji statusu kolekcji
    function updateCollectionStatus(processed, total, foundEntries) {
        let statusElement = document.querySelector('#collection-status');
        const experienceTracker = document.querySelector('#experience-tracker');
        const controlButtons = document.querySelector('#collection-controls');

        // Jeśli element nie istnieje lub nie ma właściwej klasy, tworzymy go na nowo
        if (!statusElement || !statusElement.classList.contains('collection-status-fixed')) {
            // Usuń stary element jeśli istnieje
            if (statusElement) {
                statusElement.remove();
            }

            // Stwórz nowy element
            statusElement = document.createElement('div');
            statusElement.id = 'collection-status';
            statusElement.classList.add('collection-status-fixed');
            statusElement.style.cssText = `
                margin: 15px 0;
                opacity: 0;
                transition: opacity 0.3s ease;
            `;

            // Dodaj status przed przyciskami
            if (experienceTracker && controlButtons) {
                experienceTracker.insertBefore(statusElement, controlButtons);
            } else {
                experienceTracker.appendChild(statusElement);
            }

            // Pokaż element z animacją
            setTimeout(() => {
                statusElement.style.opacity = '1';
            }, 100);
        }

        const percent = Math.round((processed / total) * 100);

        // Używamy tempExpLog zamiast experienceLog podczas zbierania danych
        const workEntries = tempExpLog.filter(e => e.type === 'work').length;
        const duelEntries = tempExpLog.filter(e => e.type === 'duel').length;
        const battleEntries = tempExpLog.filter(e => e.type === 'battle').length;

        // Dodajmy też szacowany pozostały czas
        const timeEstimate = calculateTimeEstimate(processed, total);
        const timeInfo = timeEstimate ? `<div class="time-estimate">⏱️ ${timeEstimate}</div>` : '';

        statusElement.innerHTML = `
            <div class="status-container" style="
                background: rgba(20, 20, 20, 0.95);
                padding: 15px;
                border-radius: 12px;
                border: 1px solid rgba(255, 255, 255, 0.1);
                box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            ">
                <div class="status-header" style="
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-bottom: 15px;
                    padding-bottom: 10px;
                    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
                ">
                    <div style="
                        color: #F1C40F;
                        font-size: 14px;
                        font-weight: 600;
                        letter-spacing: 0.5px;
                    ">Status pobierania</div>
                    <div style="
                        background: rgba(241, 196, 15, 0.1);
                        color: #F1C40F;
                        padding: 4px 8px;
                        border-radius: 12px;
                        font-size: 12px;
                        font-weight: 600;
                    ">${percent}%</div>
                </div>

                <div class="status-grid" style="
                    display: grid;
                    grid-template-columns: repeat(3, 1fr);
                    gap: 10px;
                    margin-bottom: 15px;
                ">
                    <div class="stat-box" style="
                        background: rgba(46, 204, 113, 0.1);
                        padding: 10px;
                        border-radius: 8px;
                        border: 1px solid rgba(46, 204, 113, 0.2);
                    ">
                        <div style="color: #2ecc71; font-size: 12px; margin-bottom: 5px;">Prace</div>
                        <div style="font-size: 14px; font-weight: 600; color: #fff;">
                            ${workEntries}<br>
                            <span style="font-size: 12px; color: #2ecc71;">${tempExpLog.filter(e => e.type === 'work').reduce((sum, e) => sum + e.amount, 0)} XP</span>
                        </div>
                    </div>

                    <div class="stat-box" style="
                        background: rgba(231, 76, 60, 0.1);
                        padding: 10px;
                        border-radius: 8px;
                        border: 1px solid rgba(231, 76, 60, 0.2);
                    ">
                        <div style="color: #e74c3c; font-size: 12px; margin-bottom: 5px;">Pojedynki</div>
                        <div style="font-size: 14px; font-weight: 600; color: #fff;">
                            ${duelEntries}<br>
                            <span style="font-size: 12px; color: #e74c3c;">${tempExpLog.filter(e => e.type === 'duel').reduce((sum, e) => sum + e.amount, 0)} XP</span>
                        </div>
                    </div>

                    <div class="stat-box" style="
                        background: rgba(155, 89, 182, 0.1);
                        padding: 10px;
                        border-radius: 8px;
                        border: 1px solid rgba(155, 89, 182, 0.2);
                    ">
                        <div style="color: #9b59b6; font-size: 12px; margin-bottom: 5px;">Bitwy</div>
                        <div style="font-size: 14px; font-weight: 600; color: #fff;">
                            ${battleEntries}<br>
                            <span style="font-size: 12px; color: #9b59b6;">${tempExpLog.filter(e => e.type === 'battle').reduce((sum, e) => sum + e.amount, 0)} XP</span>
                        </div>
                    </div>
                </div>

                <div class="progress-info" style="
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-bottom: 10px;
                    font-size: 12px;
                    color: #95a5a6;
                ">
                    <div>Postęp: ${processed}/${total} stron</div>
                    <div>Znalezione wpisy: ${foundEntries}</div>
                </div>

                <div class="progress-container" style="
                    background: rgba(255, 255, 255, 0.1);
                    height: 6px;
                    border-radius: 3px;
                    overflow: hidden;
                    margin-bottom: 10px;
                ">
                    <div class="progress-bar" style="
                        width: ${percent}%;
                        background: linear-gradient(90deg, #2ecc71, #27ae60);
                        height: 100%;
                        transition: width 0.3s ease;
                        border-radius: 3px;
                    "></div>
                </div>

                ${timeInfo ? `
                    <div style="
                        text-align: center;
                        color: #95a5a6;
                        font-size: 12px;
                        margin-top: 10px;
                        padding: 5px;
                        background: rgba(255, 255, 255, 0.05);
                        border-radius: 4px;
                    ">${timeInfo}</div>
                ` : ''}
            </div>
        `;
    }

    // Dodaj nową funkcję do obsługi przeciągania statusu
    function makeStatusDraggable(element) {
        let isDragging = false;
        let currentX;
        let currentY;
        let initialX;
        let initialY;
        let xOffset = 0;
        let yOffset = 0;

        element.addEventListener('mousedown', dragStart);
        document.addEventListener('mousemove', drag);
        document.addEventListener('mouseup', dragEnd);

        function dragStart(e) {
            if (e.target.closest('.status-container')) {
                initialX = e.clientX - xOffset;
                initialY = e.clientY - yOffset;

                isDragging = true;
            }
        }

        function drag(e) {
            if (isDragging) {
                e.preventDefault();
                currentX = e.clientX - initialX;
                currentY = e.clientY - initialY;

                xOffset = currentX;
                yOffset = currentY;

                setTranslate(currentX, currentY, element);
            }
        }

        function dragEnd(e) {
            initialX = currentX;
            initialY = currentY;
            isDragging = false;
        }

        function setTranslate(xPos, yPos, el) {
            // Zabezpieczenie przed wyjściem poza ekran
            const rect = el.getBoundingClientRect();
            const windowWidth = window.innerWidth;
            const windowHeight = window.innerHeight;

            if (xPos < -rect.width + 50) xPos = -rect.width + 50;
            if (xPos > windowWidth - 50) xPos = windowWidth - 50;
            if (yPos < 0) yPos = 0;
            if (yPos > windowHeight - 50) yPos = windowHeight - 50;

            el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
        }
    }

    // Funkcja do aktualizacji statystyk XP
    function updateXPStats() {
        const workXP = experienceLog.reduce((sum, entry) => {
            if (entry.type === 'work') {
                return sum + entry.amount;
            }
            return sum;
        }, 0);

        const duelXP = experienceLog.reduce((sum, entry) => {
            if (entry.type === 'duel') {
                return sum + entry.amount;
            }
            return sum;
        }, 0);

        const battleXP = experienceLog.reduce((sum, entry) => {
            if (entry.type === 'battle') {
                return sum + entry.amount;
            }
            return sum;
        }, 0);

        const workXPElement = document.querySelector('#work-xp');
        const duelXPElement = document.querySelector('#duel-xp');
        const battleXPElement = document.querySelector('#battle-xp');

        if (workXPElement) workXPElement.textContent = workXP + ' XP';
        if (duelXPElement) duelXPElement.textContent = duelXP + ' XP';
        if (battleXPElement) battleXPElement.textContent = battleXP + ' XP';
    }

    // Funkcja do debugowania systemu raportów
    function debugReportSystem() {
        // Sprawdź różne parametry zapytań
        const testQueries = [
            { page: 1, folder: 'all' },
            { page: 1, folder: 'all', offset: 0 },
            { page: 1, folder: 'all', offset: 0, limit: 50 }
        ];

        function makeTestQuery(params, index) {
            setTimeout(() => {
                Ajax.remoteCall('reports', 'get_reports', params, function(response) {
                });
            }, index * 1000);
        }

        testQueries.forEach(makeTestQuery);
    }

    function formatTimeRemaining(milliseconds) {
        if (!milliseconds || isNaN(milliseconds)) return "obliczanie...";
        const seconds = milliseconds / 1000;
        if (seconds < 60) return Math.round(seconds) + ' sekund';
        const minutes = Math.floor(seconds / 60);
        const remainingSeconds = Math.round(seconds % 60);
        return minutes + ' min ' + remainingSeconds + ' sek';
    }

    function calculateTimeEstimate(processedPages, totalPages) {
        if (processedPages < 2) return null;

        const currentTime = Date.now();
        const timeElapsed = currentTime - collectionStartTime;

        // Oblicz średni czas na stronę w milisekundach
        const avgTimePerPage = timeElapsed / processedPages;

        if (isNaN(avgTimePerPage)) return null;

        // Oblicz pozostały czas w milisekundach
        const remainingPages = totalPages - processedPages;
        const estimatedTimeRemaining = remainingPages * avgTimePerPage;

        return formatTimeRemaining(estimatedTimeRemaining);
    }

    // Funkcja do tłumaczenia nazw kategorii
    function getCategoryName(folder) {
        switch(folder) {
            case 'all': return 'WSZYSTKIE RAPORTY';
            case 'job': return 'PRACE';
            case 'duel': return 'POJEDYNKI';
            case 'fortbattle': return 'BITWY FORTOWE';
            default: return folder;
        }
    }

    // Funkcja do zapisywania stanu kolekcji
    function saveCollectionState(state) {
        localStorage.setItem('collectionState', JSON.stringify(state));
    }

    // Funkcja do czyszczenia stanu kolekcji
    function clearCollectionState() {
        collectionState = {
            inProgress: false,
            currentPage: 1,
            folder: null,
            tempLog: [],
            totalPages: 0
        };
        saveCollectionState(collectionState);
    }

    function toggleMainElements(show) {
        const experienceHeader = document.querySelector('#experience-tracker > div:first-child');
        const statsGrid = document.querySelector('#experience-tracker > div:nth-child(2)');
        const statusElement = document.querySelector('#collection-status');

        if (experienceHeader && statsGrid) {
            if (show) {
                // Pokazujemy główne elementy z animacją
                experienceHeader.style.display = 'flex';
                statsGrid.style.display = 'grid';
                setTimeout(() => {
                    experienceHeader.style.opacity = '1';
                    statsGrid.style.opacity = '1';
                    if (statusElement) {
                        statusElement.style.opacity = '0';
                        setTimeout(() => {
                            statusElement.remove();
                        }, 300);
                    }
                }, 50);
            } else {
                // Ukrywamy główne elementy z animacją
                experienceHeader.style.opacity = '0';
                statsGrid.style.opacity = '0';
                setTimeout(() => {
                    experienceHeader.style.display = 'none';
                    statsGrid.style.display = 'none';
                }, 300);
            }
        }
    }

    // Funkcja do zbierania historii doświadczenia
    function collectExperienceHistory(maxPages = null, folder = 'all', callback = null) {
        if (isCollectingHistory) {
            showError('Pobieranie danych jest już w trakcie. Poczekaj na zakończenie.');
            if (callback) callback();
            return;
        }

        // Ukryj główne elementy przed rozpoczęciem pobierania
        toggleMainElements(false);

        isCollectingHistory = true;
        isPaused = false;
        shouldCancel = false;
        collectionStartTime = Date.now();
        processedPagesTime = [];

        // Sprawdzamy, czy mamy zapisany stan kolekcji do wznowienia
        const shouldResume = collectionState.inProgress &&
                           collectionState.folder === folder &&
                           collectionState.tempLog.length > 0;

        if (shouldResume) {
            tempExpLog = collectionState.tempLog;
            showError(`Wznawianie zbierania danych dla ${getCategoryName(folder)} od strony ${collectionState.currentPage}`);
        } else {
            tempExpLog = [];
            collectionState.currentPage = 1;
            collectionState.folder = folder;
            collectionState.tempLog = [];
        }

        // Zachowujemy istniejące wpisy z innych kategorii
        let existingEntries = [];
        if (folder !== 'all') {
            existingEntries = experienceLog.filter(entry => {
                const entryCategory =
                    entry.type === 'work' ? 'job' :
                    entry.type === 'duel' ? 'duel' :
                    entry.type === 'battle' ? 'fortbattle' : 'other';
                return entryCategory !== folder;
            });
        }

        // Pokaż przyciski kontrolne i ukryj standardowe
        const controlButtons = document.querySelector('#collection-controls');
        const standardButtons = document.querySelector('#standard-buttons');
        if (controlButtons) {
            controlButtons.style.display = 'grid';
        }
        if (standardButtons) {
            standardButtons.style.display = 'none';
        }

        // Dostosowane opóźnienia
        const MIN_DELAY = 2400;
        const MAX_DELAY = 3000;
        const RETRY_DELAY = 3000;
        let processedPages = shouldResume ? collectionState.currentPage - 1 : 0;
        let failedAttempts = 0;
        const MAX_RETRIES = 3;

        function getRandomDelay() {
            return Math.floor(Math.random() * (MAX_DELAY - MIN_DELAY + 1)) + MIN_DELAY;
        }

        function finishCollection(wasSuccessful = true) {
            isCollectingHistory = false;
            isPaused = false;

            // Pokaż z powrotem główne elementy
            toggleMainElements(true);

            // Przywróć standardowe przyciski i ukryj kontrolne
            const controlButtons = document.querySelector('#collection-controls');
            const standardButtons = document.querySelector('#standard-buttons');
            if (controlButtons) {
                controlButtons.style.display = 'none';
            }
            if (standardButtons) {
                standardButtons.style.display = 'grid';
            }

            // Ukryj status pobierania
            const statusElement = document.querySelector('#collection-status');
            if (statusElement) {
                statusElement.innerHTML = '';
            }

            if (!wasSuccessful) {
                // Zapisz stan kolekcji do późniejszego wznowienia
                collectionState.inProgress = true;
                collectionState.tempLog = tempExpLog;
                saveCollectionState(collectionState);

                showError('Przerwano zbieranie danych. Możesz wznowić je później.');
                if (callback) callback();
                return;
            }

            // Wyczyść stan kolekcji po udanym zakończeniu
            clearCollectionState();

            if (tempExpLog.length === 0 && existingEntries.length === 0) {
                showError('Nie znaleziono żadnych wpisów z doświadczeniem.');
                if (callback) callback();
                return;
            }

            // Łączymy nowe wpisy z zachowanymi wpisami z innych kategorii
            if (folder === 'all') {
                experienceLog = tempExpLog;
            } else {
                experienceLog = [...tempExpLog, ...existingEntries];
            }

            totalExperience = experienceLog.reduce((sum, entry) => sum + entry.amount, 0);

            localStorage.setItem('experienceLog', JSON.stringify(experienceLog));
            localStorage.setItem('totalExperience', JSON.stringify(totalExperience));

            updateDisplay();
            updateXPStats();

            const newEntriesCount = tempExpLog.length;
            showError(`Zakończono pobieranie ${getCategoryName(folder)}! ${folder === 'all' ? 'Znaleziono' : 'Dodano'} ${newEntriesCount} wpisów.`);

            if (callback) {
                callback();
            }
        }

        // Pobierz wszystkie raporty
        Ajax.remoteCall('reports', 'get_reports', {
            page: 1,
            folder: folder
        }, function(initialData) {
            if (!initialData || initialData.error) {
                isCollectingHistory = false;
                showError('Nie udało się pobrać informacji o raportach. Spróbuj ponownie.');
                return;
            }

            const totalPages = initialData.count;
            collectionState.totalPages = totalPages;
            const pagesToProcess = maxPages ? Math.min(maxPages, totalPages) : totalPages;

            function processPage(page) {
                if (shouldCancel) {
                    finishCollection(false);
                    return;
                }

                if (!isCollectingHistory || page > pagesToProcess) {
                    finishCollection(true);
                    return;
                }

                if (isPaused) {
                    // Zapisz aktualny stan przed zatrzymaniem
                    collectionState.currentPage = page;
                    collectionState.tempLog = tempExpLog;
                    collectionState.inProgress = true;
                    saveCollectionState(collectionState);

                    setTimeout(() => processPage(page), 500);
                    return;
                }

                collectionState.currentPage = page;
                saveCollectionState(collectionState);

                Ajax.remoteCall('reports', 'get_reports', {
                    page: page,
                    folder: folder
                }, function(data) {
                    if (!isCollectingHistory || shouldCancel) return;

                    if (data && !data.error && data.reports && data.reports.length > 0) {
                        failedAttempts = 0;

                        data.reports.forEach(report => {
                            // Najpierw sprawdzamy typ raportu
                            const reportType = report.title.includes('Raport dot. pracy') ? 'work' :
                                            report.title.includes('Pojedynek') ? 'duel' :
                                            (report.title.includes('Bitwa') || report.title.includes('Fort')) ? 'battle' : 'other';

                            // Domyślnie zakładamy, że nie powinniśmy zliczyć XP
                            let shouldCount = false;

                            // Dla pojedynków sprawdzamy szczegóły
                            if (reportType === 'duel') {
                                // Jeśli to pojedynek z bandytą, zawsze zliczamy
                                if (report.title.includes('bandytą') || report.title.includes('bandit')) {
                                    shouldCount = true;
                                } else {
                                    // Dla pojedynków z graczami sprawdzamy zwycięzcę
                                    const winnerMatch = report.popupData.match(/Zwycięzca:\s*([^<]+)/) ||
                                                      report.popupData.match(/(\w+)\s+wygrywa pojedynek!/);

                                    if (winnerMatch) {
                                        const winner = winnerMatch[1].trim();
                                        shouldCount = winner === playerName;
                                    } else {
                                        shouldCount = false;
                                    }
                                }
                            } else {
                                // Dla nie-pojedynków zawsze zliczamy
                                shouldCount = true;
                            }

                            // Tylko jeśli powinniśmy zliczyć XP, sprawdzamy czy jest XP do dodania
                            if (shouldCount) {
                                const expMatch = report.popupData.match(/experience.png[^>]*>(?:[^<]*<\/[^>]+>)*[^<]*<td>(\d+)<\/td>/) ||
                                               report.popupData.match(/Doświadczenie<\/span>\s*<span[^>]*>(\d+)\s*punktów/);
                                const exp = expMatch ? parseInt(expMatch[1]) : 0;

                                if (exp > 0) {
                                    tempExpLog.push({
                                        amount: exp,
                                        source: report.title,
                                        timestamp: report.date_received,
                                        page: page,
                                        type: reportType
                                    });

                                    // Aktualizuj zapisany stan
                                    collectionState.tempLog = tempExpLog;
                                    saveCollectionState(collectionState);
                                }
                            }
                        });

                        processedPages++;
                        updateCollectionStatus(processedPages, pagesToProcess, tempExpLog.length);
                        setTimeout(() => processPage(page + 1), getRandomDelay());
                    } else {
                        failedAttempts++;
                        if (failedAttempts < MAX_RETRIES) {
                            setTimeout(() => processPage(page), RETRY_DELAY);
                        } else {
                            showError(`Nie udało się przetworzyć strony ${page} po ${MAX_RETRIES} próbach`);
                            finishCollection(true);
                        }
                    }
                });
            }

            processPage(shouldResume ? collectionState.currentPage : 1);
        });
    }

    // Funkcja do aktualizacji wyświetlania
    function updateDisplay() {
        const totalExperienceElement = document.querySelector('#total-experience');
        if (totalExperienceElement) {
            totalExperienceElement.textContent = totalExperience;
        }
    }

    // Funkcja do dodawania okna z doświadczeniem
    function addExperienceWindow() {
        const existingWindow = document.querySelector('#experience-tracker');
        if (existingWindow) {
            existingWindow.style.display = isTrackerVisible ? 'block' : 'none';
            return;
        }

        // Pobierz zapisaną pozycję
        const savedPosition = JSON.parse(localStorage.getItem('experienceTrackerPosition')) || { top: '50px', left: 'auto', right: '310px' };

        const trackerDiv = document.createElement('div');
        trackerDiv.id = 'experience-tracker';
        trackerDiv.style.cssText = `
            position: fixed;
            top: ${savedPosition.top};
            left: ${savedPosition.left};
            right: ${savedPosition.right};
            width: 280px;
            padding: 15px;
            background: rgba(20, 20, 20, 0.95);
            color: #fff;
            border: 1px solid #444;
            border-radius: 8px;
            z-index: 1000;
            cursor: move;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
            font-family: Arial, sans-serif;
            display: ${isTrackerVisible ? 'block' : 'none'};
        `;

        // Dodaj style dla animacji
        const style = document.createElement('style');
        style.textContent = `
            #experience-tracker > div {
                transition: opacity 0.3s ease;
            }
            #collection-status {
                transition: opacity 0.3s ease;
            }
        `;
        document.head.appendChild(style);

        trackerDiv.innerHTML = `
            <div style="background: linear-gradient(135deg, rgba(241, 196, 15, 0.1), rgba(241, 196, 15, 0.05)); border-radius: 10px; padding: 15px; margin-bottom: 15px; border: 1px solid rgba(241, 196, 15, 0.2); display: flex; justify-content: space-between; align-items: center;">
                <div style="display: flex; flex-direction: column;">
                    <span style="font-size: 12px; color: #F1C40F; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 4px;">Całkowite doświadczenie</span>
                    <span id="total-experience" style="font-size: 24px; font-weight: bold; color: #F1C40F; transition: all 0.3s ease;">${totalExperience} XP</span>
                </div>
            </div>
            <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 10px; font-size: 13px;">
                <div style="background: rgba(39, 174, 96, 0.2); padding: 8px; border-radius: 8px; text-align: center; border: 1px solid rgba(39, 174, 96, 0.3);">
                    <div style="color: #2ecc71; font-weight: bold;">Prace</div>
                    <span id="work-xp" style="color: #fff;">0 XP</span>
                </div>
                <div style="background: rgba(231, 76, 60, 0.2); padding: 8px; border-radius: 8px; text-align: center; border: 1px solid rgba(231, 76, 60, 0.3);">
                    <div style="color: #e74c3c; font-weight: bold;">PvP</div>
                    <span id="duel-xp" style="color: #fff;">0 XP</span>
                </div>
                <div style="background: rgba(155, 89, 182, 0.2); padding: 8px; border-radius: 8px; text-align: center; border: 1px solid rgba(155, 89, 182, 0.3);">
                    <div style="color: #9b59b6; font-weight: bold;">Bitwy</div>
                    <span id="battle-xp" style="color: #fff;">0 XP</span>
                </div>
            </div>

            <div id="collection-status"></div>

            <div id="collection-controls" style="display: none; grid-template-columns: 1fr 1fr; gap: 10px; margin: 10px 0;">
                <button id="pause-collection" style="
                    padding: 10px 15px;
                    background: rgba(241, 196, 15, 0.1);
                    color: #F1C40F;
                    border: 1px solid rgba(241, 196, 15, 0.2);
                    border-radius: 8px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: 600;
                    letter-spacing: 0.3px;
                    transition: all 0.3s ease;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 8px;
                ">
                    <span style="font-size: 16px;">⏸️</span>
                    Wstrzymaj
                </button>

                <button id="cancel-collection" style="
                    padding: 10px 15px;
                    background: rgba(231, 76, 60, 0.1);
                    color: #E74C3C;
                    border: 1px solid rgba(231, 76, 60, 0.2);
                    border-radius: 8px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: 600;
                    letter-spacing: 0.3px;
                    transition: all 0.3s ease;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 8px;
                ">
                    <span style="font-size: 16px;">✖️</span>
                    Anuluj
                </button>
            </div>

            <div id="standard-buttons" style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 15px;">
                <button id="update-history" style="
                    padding: 10px 0px;
                    background: rgba(33, 150, 243, 0.1);
                    color: #2196F3;
                    border: 1px solid rgba(33, 150, 243, 0.2);
                    border-radius: 8px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: 600;
                    letter-spacing: 0.3px;
                    transition: all 0.3s ease;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 8px;
                ">
                    <span style="font-size: 16px;">🔄</span>
                    Aktualizuj dane
                </button>

                <button id="collect-history" style="
                    padding: 10px 0px;
                    background: rgba(130, 224, 170, 0.1);
                    color: #82E0AA;
                    border: 1px solid rgba(130, 224, 170, 0.2);
                    border-radius: 8px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: 600;
                    letter-spacing: 0.3px;
                    transition: all 0.3s ease;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 8px;
                ">
                    <span style="font-size: 16px;">📊</span>
                    Zbierz dane
                </button>

                <button id="show-experience-log" style="
                    padding: 10px 15px;
                    background: rgba(230, 126, 34, 0.1);
                    color: #E67E22;
                    border: 1px solid rgba(230, 126, 34, 0.2);
                    border-radius: 8px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: 600;
                    letter-spacing: 0.3px;
                    transition: all 0.3s ease;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 8px;
                ">
                    <span style="font-size: 16px;">📋</span>
                    Szczegóły
                </button>

                <button id="reset-experience" style="
                    padding: 10px 15px;
                    background: rgba(255, 148, 148, 0.1);
                    color: #FF9494;
                    border: 1px solid rgba(255, 148, 148, 0.2);
                    border-radius: 8px;
                    cursor: pointer;
                    font-size: 13px;
                    font-weight: 600;
                    letter-spacing: 0.3px;
                    transition: all 0.3s ease;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 8px;
                ">
                    <span style="font-size: 16px;">🗑️</span>
                    Kasuj
                </button>
            </div>
        `;

        // Modyfikacja efektu hover dla przycisków
        const buttons = trackerDiv.getElementsByTagName('button');
        for (let button of buttons) {
            button.addEventListener('mouseover', function() {
                this.style.transform = 'translateY(-1px)';
                this.style.boxShadow = '0 4px 12px ' + (
                    this.id === 'pause-collection' ? 'rgba(241, 196, 15, 0.2)' :
                    this.id === 'cancel-collection' ? 'rgba(231, 76, 60, 0.2)' :
                    'rgba(255, 255, 255, 0.1)'
                );
            });
            button.addEventListener('mouseout', function() {
                this.style.transform = 'translateY(0)';
                this.style.boxShadow = 'none';
            });
        }

        document.body.appendChild(trackerDiv);

        // Dodanie obsługi przycisków
        document.querySelector('#collect-history').addEventListener('click', () => {
            if (!isCollectingHistory) {
                showCategorySelectionPanel('collect');
            }
        });

        document.querySelector('#pause-collection').addEventListener('click', function() {
            isPaused = !isPaused;
            if (isPaused) {
                this.innerHTML = `
                    <span style="font-size: 16px;">▶️</span>
                    Wznów
                `;
                this.style.background = 'rgba(46, 204, 113, 0.1)';
                this.style.color = '#2ECC71';
                this.style.border = '1px solid rgba(46, 204, 113, 0.2)';
            } else {
                this.innerHTML = `
                    <span style="font-size: 16px;">⏸️</span>
                    Wstrzymaj
                `;
                this.style.background = 'rgba(241, 196, 15, 0.1)';
                this.style.color = '#F1C40F';
                this.style.border = '1px solid rgba(241, 196, 15, 0.2)';
            }
        });

        document.querySelector('#cancel-collection').addEventListener('click', function() {
            shouldCancel = true;
        });

        document.querySelector('#show-experience-log').addEventListener('click', showExperienceDetails);
        document.querySelector('#reset-experience').addEventListener('click', resetExperience);

        // Dodaj obsługę przycisku aktualizacji
        document.querySelector('#update-history').addEventListener('click', () => {
            if (!isCollectingHistory) {
                showCategorySelectionPanel('update');
            }
        });

        makeDraggable(trackerDiv);

        // Aktualizuj statystyki przy tworzeniu okna
        updateXPStats();

        // Modyfikacja funkcji addExperience aby aktualizowała statystyki
        const originalAddExperience = addExperience;
        addExperience = function(amount, source) {
            originalAddExperience.call(this, amount, source);
            updateXPStats();
        };

        // Dodanie aktualizacji statystyk po zebraniu danych
        const originalCollectExperienceHistory = collectExperienceHistory;
        collectExperienceHistory = function(maxPages, folder, callback = null) {
            originalCollectExperienceHistory.call(this, maxPages, folder, callback);
            setTimeout(updateXPStats, 1000); // Aktualizuj po zakończeniu zbierania
        };
    }

    // Funkcja przeciągania elementu
    function makeDraggable(element) {
        let isDragging = false;
        let startX, startY, initialX, initialY;

        // Znajdujemy element nagłówka (cały górny obszar z doświadczeniem)
        const headerArea = element.querySelector('div:first-child');

        if (headerArea) {
            headerArea.style.cursor = 'move';
        }

        element.onmousedown = (event) => {
            let targetElement = event.target;
            let isInHeader = false;

            while (targetElement && targetElement !== element) {
                if (targetElement === headerArea) {
                    isInHeader = true;
                    break;
                }
                targetElement = targetElement.parentElement;
            }

            if (isInHeader && event.target.tagName !== 'BUTTON') {
                isDragging = true;
                startX = event.clientX;
                startY = event.clientY;
                initialX = parseInt(window.getComputedStyle(element).left, 10) || 0;
                initialY = parseInt(window.getComputedStyle(element).top, 10) || 0;
                document.onmousemove = onMouseMove;
                document.onmouseup = onMouseUp;
            }
        };

        function onMouseMove(event) {
            if (!isDragging) return;
            const deltaX = event.clientX - startX;
            const deltaY = event.clientY - startY;
            element.style.left = `${initialX + deltaX}px`;
            element.style.top = `${initialY + deltaY}px`;
            element.style.right = 'auto';
        }

        function onMouseUp() {
            if (isDragging) {
                const position = {
                    top: element.style.top,
                    left: element.style.left,
                    right: element.style.right
                };
                localStorage.setItem('experienceTrackerPosition', JSON.stringify(position));
            }
            isDragging = false;
            document.onmousemove = null;
            document.onmouseup = null;
        }
    }

    // Funkcja zapisywania pozycji okna
    function savePosition(element) {
        const top = element.style.top;
        const left = element.style.left;
        const right = element.style.right;

        localStorage.setItem('experienceTrackerPosition', JSON.stringify({ top, left, right }));
        alert('Pozycja okna została zapisana!');
    }

    // Funkcja do zapisywania zdobytego doświadczenia
    function addExperience(amount, source) {
        const now = new Date();
        const day = String(now.getDate()).padStart(2, '0');
        const month = String(now.getMonth() + 1).padStart(2, '0');
        const year = now.getFullYear();
        const formattedDate = `${day}.${month}.${year}`;

        totalExperience += amount;
        experienceLog.push({ amount, source, timestamp: formattedDate });

        // Aktualizuj lokalne przechowywanie
        localStorage.setItem('totalExperience', JSON.stringify(totalExperience));
        localStorage.setItem('experienceLog', JSON.stringify(experienceLog));

        // Zaktualizuj wyświetlaną wartość
        const totalExperienceElement = document.querySelector('#total-experience');
        if (totalExperienceElement) {
            totalExperienceElement.textContent = totalExperience;
        }
    }

    // Funkcja do pokazywania szczegółów doświadczenia
    function showExperienceDetails() {
        const logWindow = window.open('', '_blank');

        // Ensure we have a valid window reference
        if (logWindow === null) {
            alert('Proszę zezwolić na otwieranie nowych kart w przeglądarce.');
            return;
        }

        logWindow.document.write(`
            <!DOCTYPE html>
            <html>
            <head>
                <title>Historia doświadczenia</title>
                <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
                <style>
                    * {
                        margin: 0;
                        padding: 0;
                        box-sizing: border-box;
                        font-family: 'Roboto', sans-serif;
                    }

                    html {
                        min-width: 1300px;
                    }

                    body {
                        background: #f5f6fa;
                        color: #2d3436;
                        line-height: 1.6;
                        padding: 20px;
                        min-width: 1300px;
                        width: 100%;
                    }

                    .container {
                        min-width: 1300px;
                        width: 100%;
                        margin: 0 auto;
                        padding: 20px;
                    }

                    .controls {
                        background: white;
                        padding: 15px;
                        border-radius: 12px;
                        box-shadow: 0 2px 10px rgba(0,0,0,0.05);
                        display: grid;
                        grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
                        gap: 10px;
                        margin-bottom: 15px;
                    }

                    .controls select,
                    .controls input,
                    .controls button {
                        padding: 8px 12px;
                        border: 1px solid #dfe6e9;
                        border-radius: 6px;
                        font-size: 13px;
                        width: 100%;
                    }

                    .controls button {
                        background: #2196F3;
                        color: white;
                        border: none;
                        cursor: pointer;
                        transition: background 0.2s;
                    }

                    .controls button:hover {
                        background: #1976D2;
                    }

                    .chart-container {
                        background: white;
                        padding: 20px;
                        border-radius: 12px;
                        box-shadow: 0 2px 10px rgba(0,0,0,0.05);
                        height: 400px;
                        margin: 20px 0;
                    }

                    .content-wrapper {
                        display: grid;
                        grid-template-columns: 20% 35% 45%;
                        gap: 20px;
                        margin-top: 20px;
                        width: 100%;
                        height: calc(100vh - 220px); /* Dodajemy stałą wysokość dla wrappera */
                    }

                    .left-column, .middle-column, .right-column {
                        width: 100%;
                        min-width: 0;
                        height: 100%; /* Ustawiamy pełną wysokość dla kolumn */
                    }

                    .right-column {
                        display: flex;
                        flex-direction: column;
                        gap: 15px;
                        height: 560px; /* Całkowita wysokość kolumny */
                    }

                    .right-content {
                        background: white;
                        padding: 20px;
                        border-radius: 12px;
                        box-shadow: 0 2px 10px rgba(0,0,0,0.05);
                        height: 500px !important;
                        overflow: hidden;
                        min-height: 500px !important;
                        max-height: 500px !important;
                        display: flex;
                        flex-direction: column;
                    }

                    .right-content h2 {
                        margin: 0 0 15px 0;
                        color: #2d3436;
                        font-size: 18px;
                        flex: 0 0 auto;
                    }

                    .entries-list {
                        flex: 1;
                        overflow-y: auto;
                    }

                    .entries-header {
                        display: grid;
                        grid-template-columns: 100px 1fr 100px;
                        gap: 15px;
                        padding: 10px 15px;
                        background: white;
                        font-weight: bold;
                        border-bottom: 2px solid #ddd;
                        position: sticky;
                        top: 0;
                        z-index: 1;
                        flex: 0 0 auto; /* Dodajemy flex aby header nie rozpychał kontenera */
                    }

                    .entry {
                        display: grid;
                        grid-template-columns: 100px 1fr 100px;
                        gap: 15px;
                        padding: 15px;
                        border-bottom: 1px solid #f1f2f6;
                        transition: all 0.2s ease;
                        align-items: center;
                    }

                    .entry:hover {
                        background: #f8f9fa;
                    }

                    .entry:last-child {
                        border-bottom: none;
                    }

                    .entry .timestamp {
                        color: #636e72;
                        font-size: 14px;
                        white-space: nowrap;
                    }

                    .entry .source {
                        color: #2d3436;
                        font-weight: 500;
                    }

                    .entry .amount {
                        color: #00b894;
                        font-weight: 700;
                        font-size: 16px;
                    }

                    .badge {
                        display: inline-block;
                        padding: 4px 8px;
                        border-radius: 6px;
                        font-size: 12px;
                        font-weight: 500;
                        margin-right: 8px;
                    }

                    .badge-church { background: #81ecec; color: #00cec9; }
                    .badge-work { background: #55efc4; color: #00b894; }
                    .badge-duel-player { background: #ff7675; color: #d63031; }
                    .badge-duel-bandit { background: #fab1a0; color: #e17055; }
                    .badge-battle { background: #9b59b6; color: #8e44ad; }
                    .badge-other { background: #81ecec; color: #00cec9; }

                    .pagination {
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        gap: 10px;
                        padding: 10px;
                        background: white;
                        border-radius: 8px;
                        box-shadow: 0 2px 10px rgba(0,0,0,0.05);
                        height: 45px;
                        flex: 0 0 auto; /* Dodajemy flex aby paginacja nie rozpychała kontenera */
                    }

                    .pagination button {
                        padding: 8px 12px;
                        border: 1px solid #dfe6e9;
                        background: white;
                        color: #2d3436;
                        border-radius: 8px;
                        cursor: pointer;
                        transition: all 0.3s ease;
                    }

                    .pagination button:hover {
                        border-color: #0984e3;
                        color: #0984e3;
                    }

                    .pagination button.active {
                        background: #0984e3;
                        color: white;
                        border-color: #0984e3;
                    }

                    .pagination .info {
                        color: #636e72;
                        font-size: 14px;
                    }

                    .daily-xp-container {
                        background: white;
                        padding: 20px;
                        border-radius: 12px;
                        box-shadow: 0 2px 10px rgba(0,0,0,0.05);
                        height: 500px !important;
                        overflow: hidden;
                        min-height: 500px !important;
                        max-height: 500px !important;
                        display: flex;
                        flex-direction: column;
                    }

                    .daily-xp-container h2 {
                        margin: 0 0 15px 0;
                        color: #2d3436;
                        font-size: 18px;
                        flex: 0 0 auto;
                    }

                    .daily-xp-header {
                        display: grid;
                        grid-template-columns: 100px minmax(150px, 1fr) 100px;
                        gap: 15px;
                        padding: 10px 15px;
                        background: white;
                        font-weight: bold;
                        border-bottom: 2px solid #ddd;
                        flex: 0 0 auto;
                    }

                    .daily-xp-header > div:nth-child(3) {
                        text-align: right;
                        padding-right: 30px;
                    }

                    .daily-xp-entries {
                        flex: 1;
                        overflow-y: auto;
                        padding-right: 5px;
                    }

                    .daily-xp-table {
                        width: 100%;
                        border-collapse: collapse;
                        table-layout: fixed;
                    }

                    .daily-xp-table td {
                        padding: 10px 15px;
                        border-bottom: 1px solid #f1f2f6;
                    }

                    .daily-xp-table td:first-child {
                        width: 100px;
                    }

                    .daily-xp-table td:nth-child(2) {
                        width: auto;
                        min-width: 150px;
                    }

                    .daily-xp-table td:last-child {
                        width: 100px;
                    }

                    .daily-xp-entry {
                        transition: all 0.2s ease;
                    }

                    .daily-xp-entry:hover {
                        background: #f8f9fa;
                    }

                    .daily-xp-entry:last-child td {
                        border-bottom: none;
                    }

                    .daily-xp-entry .date {
                        color: #636e72;
                        font-size: 14px;
                    }

                    .daily-xp-entry .xp {
                        color: #2d3436;
                        font-weight: 500;
                        text-align: center;
                    }

                    .daily-xp-entry .difference {
                        text-align: right;
                        font-weight: 700;
                        font-size: 14px;
                        padding-right: 30px;
                    }

                    .daily-xp-entry .difference.positive {
                        color: #27ae60;
                    }

                    .daily-xp-entry .difference.negative {
                        color: #e74c3c;
                    }

                    .daily-xp-entry .difference.neutral {
                        color: #666;
                    }

                    .stat-card {
                        background: white;
                        padding: 20px;
                        border-radius: 12px;
                        box-shadow: 0 2px 10px rgba(0,0,0,0.05);
                        transition: all 0.3s ease;
                        margin-bottom: 15px;
                    }

                    .stat-card:hover {
                        transform: translateY(-2px);
                        box-shadow: 0 4px 15px rgba(0,0,0,0.1);
                    }

                    .stat-card h3 {
                        color: #636e72;
                        font-size: 14px;
                        font-weight: 500;
                        text-transform: uppercase;
                        letter-spacing: 0.5px;
                        margin-bottom: 10px;
                    }

                    .stat-card .value {
                        font-size: 24px;
                        font-weight: 700;
                        color: #2d3436;
                        margin-bottom: 5px;
                    }

                    .stat-card .sub-value {
                        font-size: 14px;
                        color: #636e72;
                    }
                </style>
            </head>
            <body>
                <div class="container">
                    <div class="controls">
                        <select id="categoryFilter">
                            <option value="all">Wszystkie źródła</option>
                            <option value="Prace">Zwykłe prace</option>
                            <option value="Kosciol">Budowa kościoła</option>
                            <option value="PojedynkiGracze">Pojedynki z graczami</option>
                            <option value="PojedynkiBandyci">Pojedynki z bandytami</option>
                            <option value="Bitwy">Bitwy fortowe</option>
                            <option value="Inne">Inne</option>
                        </select>
                        <select id="sortBy">
                            <option value="date-desc">Od najnowszych</option>
                            <option value="exp-desc">Najwięcej XP</option>
                            <option value="exp-asc">Najmniej XP</option>
                        </select>
                        <input type="text" id="searchInput" placeholder="Szukaj...">
                        <button onclick="applyFilters()">Filtruj</button>
                    </div>

                    <div class="chart-container">
                        <canvas id="dailyExpChart"></canvas>
                    </div>

                    <div class="content-wrapper">
                        <div class="left-column">
                            <div id="summary" class="stats-grid"></div>
                        </div>
                        <div class="middle-column">
                            <div class="daily-xp-container">
                                <h2>Dzienne XP</h2>
                                <div class="daily-xp-header">
                                    <div>Data</div>
                                    <div style="text-align: center;">XP</div>
                                    <div style="text-align: right;">Różnica</div>
                                </div>
                                <div class="daily-xp-entries">
                                    <table class="daily-xp-table">
                                        <tbody id="daily-xp-tbody"></tbody>
                                    </table>
                                </div>
                            </div>
                        </div>
                        <div class="right-column">
                            <div class="right-content">
                                <h2>Raporty</h2>
                                <div class="entries-header">
                                    <div>Data</div>
                                    <div>Raport</div>
                                       <div>XP</div>
                                </div>
                                <div class="entries-list" id="experience-list"></div>
                            </div>
                            <div id="pagination" class="pagination"></div>
                        </div>
                    </div>
                </div>

                <script>
                    let currentPage = 1;
                    const itemsPerPage = 25;
                    let filteredData = [];
                    const originalData = ${JSON.stringify(experienceLog)};

                    function updateSummary() {
                        const summary = {
                            total: 0,
                            categories: {
                                'Zwykłe prace': { exp: 0, count: 0, max: 0 },
                                'Budowa kościoła': { exp: 0, count: 0, max: 0 },
                                'Pojedynki z graczami': { exp: 0, count: 0, max: 0 },
                                'Pojedynki z bandytami': { exp: 0, count: 0, max: 0 },
                                'Bitwy fortowe': { exp: 0, count: 0, max: 0 },
                                'Inne': { exp: 0, count: 0, max: 0 }
                            }
                        };

                        // Funkcja pomocnicza do formatowania daty
                        function formatDate(timestamp) {
                            if (!timestamp) return '';

                            // Jeśli timestamp zaczyna się od "Godzina:"
                            if (timestamp.startsWith('Godzina:')) {
                                const today = new Date();
                                const day = String(today.getDate()).padStart(2, '0');
                                const month = String(today.getMonth() + 1).padStart(2, '0');
                                const year = today.getFullYear();
                                return day + '.' + month + '.' + year;
                            }

                            // Jeśli data jest w formacie DD.MM.YYYY, HH:mm:ss
                            if (timestamp.includes('.') && timestamp.includes(':')) {
                                const [datePart] = timestamp.split(',');
                                return datePart.trim();
                            }

                            // Jeśli data jest w formacie "DD MMM YYYY"
                            const monthMap = {
                                'sty': '01', 'lut': '02', 'mar': '03', 'kwi': '04',
                                'maj': '05', 'cze': '06', 'lip': '07', 'sie': '08',
                                'wrz': '09', 'paź': '10', 'lis': '11', 'gru': '12'
                            };

                            const parts = timestamp.split(' ');
                            if (parts.length === 3) {
                                const day = String(parseInt(parts[0])).padStart(2, '0');
                                const monthAbbr = parts[1].toLowerCase();
                                const year = parts[2];

                                if (monthMap[monthAbbr]) {
                                    return day + '.' + monthMap[monthAbbr] + '.' + year;
                                }
                            }

                            // Dla pozostałych przypadków zwróć oryginalny timestamp
                            return timestamp;
                        }

                        // Analiza dziennego XP
                        const dailyExp = {};
                        const dailyMaxNpcExp = {};

                        originalData.forEach(entry => {
                            const formattedDate = formatDate(entry.timestamp);

                            if (!dailyExp[formattedDate]) {
                                dailyExp[formattedDate] = 0;
                                dailyMaxNpcExp[formattedDate] = 0;
                            }
                            dailyExp[formattedDate] += entry.amount;

                            if (entry.source.includes('Pojedynek z bandytą')) {
                                dailyMaxNpcExp[formattedDate] = Math.max(dailyMaxNpcExp[formattedDate], entry.amount);
                            }

                            // Aktualizacja statystyk ogólnych
                            let category = 'Inne';
                            if (entry.type === 'work') {
                                if (entry.source.includes('rozbudowa Kościół')) {
                                    category = 'Budowa kościoła';
                                } else {
                                    category = 'Zwykłe prace';
                                }
                            } else if (entry.type === 'duel') {
                                if (entry.source.includes('bandytą') || entry.source.includes('bandit')) {
                                    category = 'Pojedynki z bandytami';
                                } else {
                                    category = 'Pojedynki z graczami';
                                }
                            } else if (entry.type === 'battle') {
                                category = 'Bitwy fortowe';
                            }

                            summary.categories[category].exp += entry.amount;
                            summary.categories[category].count++;
                            summary.categories[category].max = Math.max(summary.categories[category].max, entry.amount);
                            summary.total += entry.amount;
                        });

                        // Sortowanie dat
                        const sortedDates = Object.keys(dailyExp).sort((a, b) => {
                            const [dayA, monthA, yearA] = a.split(' ');
                            const [dayB, monthB, yearB] = b.split(' ');
                            const monthMap = {
                                'sty': 1, 'lut': 2, 'mar': 3, 'kwi': 4, 'maj': 5, 'cze': 6,
                                'lip': 7, 'sie': 8, 'wrz': 9, 'paź': 10, 'lis': 11, 'gru': 12
                            };

                            if (yearA !== yearB) return yearB - yearA;
                            if (monthMap[monthA] !== monthMap[monthB]) return monthMap[monthB] - monthMap[monthA];
                            return dayB - dayA;
                        });

                        // Aktualizacja HTML
                        const summaryDiv = document.getElementById('summary');
                        const summaryHtml = [
                            '<div class="stats-grid">',
                            '<div class="stat-card">',
                            '<h3>Całkowite XP</h3>',
                            '<div class="value">' + summary.total.toLocaleString() + ' XP</div>',
                            '<div class="sub-value">' + originalData.length + ' wpisów</div>',
                            '</div>',
                            Object.entries(summary.categories).map(([category, data]) =>
                                data.count > 0 ? [
                                    '<div class="stat-card">',
                                    '<h3>' + category + '</h3>',
                                    '<div class="value">' + data.exp.toLocaleString() + ' XP</div>',
                                    '<div class="sub-value">',
                                    'Ilość: ' + data.count + '<br>',
                                    'Średnio: ' + Math.round(data.exp / data.count).toLocaleString() + ' XP<br>',
                                    'Max: ' + data.max.toLocaleString() + ' XP',
                                    '</div>',
                                    '</div>'
                                ].join('') : ''
                            ).join(''),
                            '</div>'
                        ].join('');

                        summaryDiv.innerHTML = summaryHtml;

                        // Aktualizacja tabeli dziennego XP
                        const dailyXpTbody = document.getElementById('daily-xp-tbody');
                        if (dailyXpTbody) {
                            let htmlContent = '';

                            htmlContent += sortedDates.map((date, index) => {
                                const prevDayXP = index < sortedDates.length - 1 ? dailyExp[sortedDates[index + 1]] : 0;
                                const difference = dailyExp[date] - prevDayXP;
                                const differenceText = index < sortedDates.length - 1 ?
                                    (difference > 0 ? '+' + difference.toLocaleString() : difference.toLocaleString()) : '-';
                                const differenceClass = difference > 0 ? 'positive' : difference < 0 ? 'negative' : 'neutral';

                                return '<tr class="daily-xp-entry">' +
                                    '<td class="date">' + date + '</td>' +
                                    '<td class="xp">' + dailyExp[date].toLocaleString() + '</td>' +
                                    '<td class="difference ' + differenceClass + '">' + differenceText + ' XP</td>' +
                                    '</tr>';
                            }).join('');

                            dailyXpTbody.innerHTML = htmlContent;
                        }

                        // Tworzenie wykresu
                        const ctx = document.getElementById('dailyExpChart');
                        new Chart(ctx, {
                            type: 'line',
                            data: {
                                labels: sortedDates.slice(0, 30), // Ostatnie 30 dni
                                datasets: [{
                                    label: 'XP dziennie',
                                    data: sortedDates.slice(0, 30).map(date => dailyExp[date]),
                                    borderColor: '#4CAF50',
                                    backgroundColor: 'rgba(76, 175, 80, 0.1)',
                                    tension: 0.1,
                                    fill: true
                                }]
                            },
                            options: {
                                responsive: true,
                                maintainAspectRatio: false,
                                plugins: {
                                    legend: {
                                        display: true,
                                        position: 'top'
                                    },
                                    tooltip: {
                                        callbacks: {
                                            label: function(context) {
                                                return context.raw.toLocaleString() + ' XP';
                                            }
                                        }
                                    }
                                },
                                scales: {
                                    y: {
                                        beginAtZero: true,
                                        ticks: {
                                            callback: function(value) {
                                                return value.toLocaleString();
                                            }
                                        }
                                    }
                                }
                            }
                        });
                    }

                    function applyFilters() {
                        const category = document.getElementById('categoryFilter').value;
                        const sortBy = document.getElementById('sortBy').value;
                        const searchText = document.getElementById('searchInput').value.toLowerCase();

                        filteredData = originalData.filter(entry => {
                            const matchesCategory =
                                category === 'all' ? true :
                                category === 'Kosciol' ? (entry.type === 'work' && entry.source.includes('rozbudowa Kościół')) :
                                category === 'Prace' ? (entry.type === 'work' && !entry.source.includes('rozbudowa Kościół')) :
                                category === 'PojedynkiGracze' ? (entry.type === 'duel' && !entry.source.includes('bandytą') && !entry.source.includes('bandit')) :
                                category === 'PojedynkiBandyci' ? (entry.type === 'duel' && (entry.source.includes('bandytą') || entry.source.includes('bandit'))) :
                                category === 'Bitwy' ? entry.type === 'battle' :
                                category === 'Inne' ? (entry.type !== 'work' && entry.type !== 'duel' && entry.type !== 'battle') : false;

                            const matchesSearch = searchText === '' ||
                                entry.source.toLowerCase().includes(searchText);

                            return matchesCategory && matchesSearch;
                        });

                        filteredData.sort((a, b) => {
                            switch(sortBy) {
                                case 'date-desc':
                                    return new Date(b.timestamp) - new Date(a.timestamp);
                                case 'exp-desc':
                                    return b.amount - a.amount;
                                case 'exp-asc':
                                    return a.amount - b.amount;
                                default:
                                    return 0;
                            }
                        });

                        currentPage = 1;
                        renderPage();
                    }

                    function renderPage() {
                        const start = (currentPage - 1) * itemsPerPage;
                        const end = start + itemsPerPage;
                        const pageItems = filteredData.slice(start, end);

                        const listDiv = document.getElementById('experience-list');
                        listDiv.innerHTML = '';

                        if (pageItems.length === 0) {
                            listDiv.innerHTML = '<div style="text-align: center; padding: 20px; color: #666;">Brak wpisów spełniających kryteria</div>';
                            return;
                        }

                        // Funkcja pomocnicza do formatowania daty
                        function formatDate(timestamp) {
                            if (!timestamp) return '';

                            // Jeśli timestamp zaczyna się od "Godzina:"
                            if (timestamp.startsWith('Godzina:')) {
                                const today = new Date();
                                const day = String(today.getDate()).padStart(2, '0');
                                const month = String(today.getMonth() + 1).padStart(2, '0');
                                const year = today.getFullYear();
                                return day + '.' + month + '.' + year;
                            }

                            // Jeśli data jest w formacie DD.MM.YYYY, HH:mm:ss
                            if (timestamp.includes('.') && timestamp.includes(':')) {
                                const [datePart] = timestamp.split(',');
                                return datePart.trim();
                            }

                            // Jeśli data jest w formacie "DD MMM YYYY"
                            const monthMap = {
                                'sty': '01', 'lut': '02', 'mar': '03', 'kwi': '04',
                                'maj': '05', 'cze': '06', 'lip': '07', 'sie': '08',
                                'wrz': '09', 'paź': '10', 'lis': '11', 'gru': '12'
                            };

                            const parts = timestamp.split(' ');
                            if (parts.length === 3) {
                                const day = String(parseInt(parts[0])).padStart(2, '0');
                                const monthAbbr = parts[1].toLowerCase();
                                const year = parts[2];

                                if (monthMap[monthAbbr]) {
                                    return day + '.' + monthMap[monthAbbr] + '.' + year;
                                }
                            }

                            // Dla pozostałych przypadków zwróć oryginalny timestamp
                            return timestamp;
                        }

                        pageItems.forEach(entry => {
                            const entryDiv = document.createElement('div');
                            entryDiv.className = 'entry';

                            let badgeClass = '';
                            let badgeText = '';

                            if (entry.type === 'work') {
                                if (entry.source.includes('rozbudowa Kościół')) {
                                    badgeClass = 'badge-church';
                                    badgeText = 'Kościół';
                                } else {
                                    badgeClass = 'badge-work';
                                    badgeText = 'Praca';
                                }
                            } else if (entry.type === 'duel') {
                                if (entry.source.includes('bandytą')) {
                                    badgeClass = 'badge-duel-bandit';
                                    badgeText = 'Bandyta';
                                } else {
                                    badgeClass = 'badge-duel-player';
                                    badgeText = 'PvP';
                                }
                            } else if (entry.type === 'battle') {
                                badgeClass = 'badge-battle';
                                badgeText = 'Bitwa';
                            } else {
                                badgeClass = 'badge-other';
                                badgeText = 'Inne';
                            }

                            entryDiv.innerHTML = [
                                '<span class="timestamp">' + formatDate(entry.timestamp) + '</span>',
                                '<span class="source">',
                                '<span class="badge ' + badgeClass + '">' + badgeText + '</span>',
                                entry.source,
                                '</span>',
                                '<span class="amount">+' + entry.amount.toLocaleString() + ' XP</span>'
                            ].join('');

                            listDiv.appendChild(entryDiv);
                        });

                        updatePagination();
                    }

                    function updatePagination() {
                        const totalPages = Math.ceil(filteredData.length / itemsPerPage);
                        const paginationDiv = document.getElementById('pagination');

                        let html = [
                            '<div class="pagination">',
                            '<span class="info">Strona ' + currentPage + ' z ' + totalPages + ' (' + filteredData.length + ' wpisów)</span>'
                        ];

                        if (totalPages > 1) {
                            if (currentPage > 1) {
                                html.push('<button onclick="changePage(1)">«</button>');
                                html.push('<button onclick="changePage(' + (currentPage - 1) + ')">‹</button>');
                            }

                            for (let i = Math.max(1, currentPage - 2); i <= Math.min(totalPages, currentPage + 2); i++) {
                                html.push('<button onclick="changePage(' + i + ')"' +
                                        (i === currentPage ? ' class="active"' : '') + '>' + i + '</button>');
                            }

                            if (currentPage < totalPages) {
                                html.push('<button onclick="changePage(' + (currentPage + 1) + ')">›</button>');
                                html.push('<button onclick="changePage(' + totalPages + ')">»</button>');
                            }
                        }

                        html.push('</div>');
                        paginationDiv.innerHTML = html.join('');
                    }

                    function changePage(newPage) {
                        currentPage = newPage;
                        renderPage();
                        window.scrollTo(0, 0);
                    }

                    // Inicjalizacja
                    filteredData = [...originalData];
                    updateSummary();
                    applyFilters();
                </script>
                <script>
                    // Add resize handling
                    window.addEventListener('resize', function() {
                        if (window.outerWidth < 1300) {
                            window.resizeTo(1300, window.outerHeight);
                        }
                    });
                </script>
            </body>
            </html>
        `);
        logWindow.document.close();
    }

    // Funkcja resetująca doświadczenie do 0
    function resetExperience() {
        totalExperience = 0;
        experienceLog = [];

        // Czyścimy również stan przerwanej kolekcji
        clearCollectionState();

        // Zapisz zresetowane wartości w localStorage
        localStorage.setItem('totalExperience', JSON.stringify(totalExperience));
        localStorage.setItem('experienceLog', JSON.stringify(experienceLog));

        // Zaktualizuj wyświetlaną wartość doświadczenia
        const totalExperienceElement = document.querySelector('#total-experience');
        if (totalExperienceElement) {
            totalExperienceElement.textContent = totalExperience + ' XP';
        }

        // Zaktualizuj statystyki z prac i pojedynków
        const workXPElement = document.querySelector('#work-xp');
        const duelXPElement = document.querySelector('#duel-xp');
        const battleXPElement = document.querySelector('#battle-xp');

        if (workXPElement) workXPElement.textContent = '0 XP';
        if (duelXPElement) duelXPElement.textContent = '0 XP';
        if (battleXPElement) battleXPElement.textContent = '0 XP';
    }

    // Nasłuchiwanie na zmiany w doświadczeniu (np. praca, bitwa)
    const originalSetExperience = window.Character.setExperience;
    window.Character.setExperience = function(newExperience) {
        const currentExperience = this.experience;
        const gainedExperience = newExperience - currentExperience;
        if (gainedExperience > 0) {
            addExperience(gainedExperience, 'Aktywność w grze'); // Domyślna aktywność
        }
        originalSetExperience.call(this, newExperience);
    };

    // Dodajemy nową funkcję do tworzenia panelu wyboru
    function showCategorySelectionPanel(action) {
        const existingPanel = document.querySelector('#category-selection-panel');
        if (existingPanel) existingPanel.remove();

        const experienceTracker = document.querySelector('#experience-tracker');
        if (!experienceTracker) return;

        const panel = document.createElement('div');
        panel.id = 'category-selection-panel';
        panel.style.cssText = `
            color: white;
            width: 100%;
            box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
            margin-top: 15px;
        `;

        const title = action === 'collect' ? 'Zbieranie danych' : 'Aktualizacja danych';

        // Dodajemy informację o przerwanej kolekcji
        const hasInterruptedCollection = collectionState.inProgress && collectionState.tempLog.length > 0;

        panel.innerHTML = `
            <div style="margin-bottom: 15px; text-align: center;">
                <span style="font-size: 18px; color: #F1C40F; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 4px; display: block;">
                    ${title}
                </span>
            </div>
            <div style="display: grid; gap: 12px;">
                ${hasInterruptedCollection ? `
                    <div style="margin-bottom: 15px; padding: 15px; background: rgba(241, 196, 15, 0.1); border: 1px solid rgba(241, 196, 15, 0.2); border-radius: 8px;">
                        <div style="margin-bottom: 8px; color: #F1C40F;">Wykryto przerwaną kolekcję:</div>
                        <div style="color: #DDD; font-size: 13px; line-height: 1.5;">
                            Kategoria: ${getCategoryName(collectionState.folder)}<br>
                            Postęp: ${collectionState.currentPage}/${collectionState.totalPages} stron<br>
                            Zebrane wpisy: ${collectionState.tempLog.length}
                        </div>
                    </div>
                    <button id="resume-collection" style="
                        padding: 10px 15px;
                        background: rgba(130, 224, 170, 0.1);
                        color: #82E0AA;
                        border: 1px solid rgba(130, 224, 170, 0.2);
                        border-radius: 8px;
                        cursor: pointer;
                        font-size: 13px;
                        font-weight: 600;
                        letter-spacing: 0.3px;
                        transition: all 0.3s ease;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        gap: 8px;
                    ">
                        <span style="font-size: 16px;">▶️</span>
                        Wznów przerwaną kolekcję
                    </button>
                    <button id="clear-interrupted" style="
                        padding: 10px 15px;
                        background: rgba(255, 148, 148, 0.1);
                        color: #FF9494;
                        border: 1px solid rgba(255, 148, 148, 0.2);
                        border-radius: 8px;
                        cursor: pointer;
                        font-size: 13px;
                        font-weight: 600;
                        letter-spacing: 0.3px;
                        transition: all 0.3s ease;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        gap: 8px;
                    ">
                        <span style="font-size: 16px;">🗑️</span>
                        Wyczyść przerwaną kolekcję
                    </button>
                ` : `
                    <label style="
                        display: flex;
                        align-items: center;
                        padding: 12px 15px;
                        background: rgba(241, 196, 15, 0.1);
                        border: 1px solid rgba(241, 196, 15, 0.2);
                        border-radius: 8px;
                        cursor: pointer;
                        transition: all 0.3s ease;
                        gap: 10px;
                    ">
                        <input type="checkbox" data-folder="all" class="category-checkbox" style="
                            width: 16px;
                            height: 16px;
                            cursor: pointer;
                        ">
                        <span style="color: #F1C40F; font-weight: 600;">WSZYSTKIE RAPORTY</span>
                    </label>

                    <label style="
                        display: flex;
                        align-items: center;
                        padding: 12px 15px;
                        background: rgba(46, 204, 113, 0.1);
                        border: 1px solid rgba(46, 204, 113, 0.2);
                        border-radius: 8px;
                        cursor: pointer;
                        transition: all 0.3s ease;
                        gap: 10px;
                    ">
                        <input type="checkbox" data-folder="job" class="category-checkbox" style="
                            width: 16px;
                            height: 16px;
                            cursor: pointer;
                        ">
                        <span style="color: #2ecc71; font-weight: 600;">PRACE</span>
                    </label>

                    <label style="
                        display: flex;
                        align-items: center;
                        padding: 12px 15px;
                        background: rgba(231, 76, 60, 0.1);
                        border: 1px solid rgba(231, 76, 60, 0.2);
                        border-radius: 8px;
                        cursor: pointer;
                        transition: all 0.3s ease;
                        gap: 10px;
                    ">
                        <input type="checkbox" data-folder="duel" class="category-checkbox" style="
                            width: 16px;
                            height: 16px;
                            cursor: pointer;
                        ">
                        <span style="color: #e74c3c; font-weight: 600;">POJEDYNKI</span>
                    </label>

                    <label style="
                        display: flex;
                        align-items: center;
                        padding: 12px 15px;
                        background: rgba(155, 89, 182, 0.1);
                        border: 1px solid rgba(155, 89, 182, 0.2);
                        border-radius: 8px;
                        cursor: pointer;
                        transition: all 0.3s ease;
                        gap: 10px;
                    ">
                        <input type="checkbox" data-folder="fortbattle" class="category-checkbox" style="
                            width: 16px;
                            height: 16px;
                            cursor: pointer;
                        ">
                        <span style="color: #9b59b6; font-weight: 600;">BITWY FORTOWE</span>
                    </label>

                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 5px;">
                        <button id="start-collection" style="
                            padding: 10px 15px;
                            background: rgba(130, 224, 170, 0.1);
                            color: #82E0AA;
                            border: 1px solid rgba(130, 224, 170, 0.2);
                            border-radius: 8px;
                            cursor: pointer;
                            font-size: 13px;
                            font-weight: 600;
                            letter-spacing: 0.3px;
                            transition: all 0.3s ease;
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            gap: 8px;
                        ">
                            <span style="font-size: 16px;">▶️</span>
                            Start
                        </button>

                        <button id="cancel-selection" style="
                            padding: 10px 15px;
                            background: rgba(255, 148, 148, 0.1);
                            color: #FF9494;
                            border: 1px solid rgba(255, 148, 148, 0.2);
                            border-radius: 8px;
                            cursor: pointer;
                            font-size: 13px;
                            font-weight: 600;
                            letter-spacing: 0.3px;
                            transition: all 0.3s ease;
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            gap: 8px;
                        ">
                            <span style="font-size: 16px;">✖️</span>
                            Anuluj
                        </button>
                    </div>
                `}
            </div>
        `;

        // Dodaj panel do głównego interfejsu
        experienceTracker.appendChild(panel);

        // Dodaj obsługę zdarzeń
        const buttons = panel.getElementsByTagName('button');
        for (let button of buttons) {
            button.addEventListener('click', function() {
                if (this.id === 'resume-collection') {
                    panel.remove();
                    collectExperienceHistory(null, collectionState.folder);
                } else if (this.id === 'clear-interrupted') {
                    clearCollectionState();
                    panel.remove();
                } else if (this.id === 'start-collection') {
                    const selectedFolders = Array.from(panel.querySelectorAll('.category-checkbox:checked'))
                        .map(cb => cb.dataset.folder);

                    if (selectedFolders.length === 0) {
                        showError('Wybierz przynajmniej jedną kategorię!');
                        return;
                    }

                    panel.remove();

                    if (selectedFolders.includes('all')) {
                        if (action === 'collect') {
                            collectExperienceHistory(null, 'all');
                        } else {
                            updateExperienceHistory('all');
                        }
                    } else {
                        processCategories(selectedFolders, action);
                    }
                } else if (this.id === 'cancel-selection') {
                    panel.remove();
                }
            });
        }

        // Obsługa checkboxów
        const allCheckbox = panel.querySelector('input[data-folder="all"]');
        if (allCheckbox) {
            allCheckbox.addEventListener('change', function() {
                const checkboxes = panel.querySelectorAll('.category-checkbox:not([data-folder="all"])');
                checkboxes.forEach(checkbox => {
                    checkbox.checked = false;
                    checkbox.disabled = this.checked;
                });
            });
        }

        const otherCheckboxes = panel.querySelectorAll('.category-checkbox:not([data-folder="all"])');
        otherCheckboxes.forEach(checkbox => {
            checkbox.addEventListener('change', function() {
                if (this.checked && allCheckbox) {
                    allCheckbox.checked = false;
                }
            });
        });
    }

    // Dodaj funkcję do przetwarzania kategorii
    async function processCategories(folders, action) {
        for (let i = 0; i < folders.length; i++) {
            const folder = folders[i];
            showError(`Rozpoczynam zbieranie danych dla ${getCategoryName(folder)}`);

            await new Promise((resolve) => {
                if (action === 'collect') {
                    collectExperienceHistory(null, folder, () => {
                        showError(`Zakończono przetwarzanie ${getCategoryName(folder)}`);
                        setTimeout(resolve, 2000);
                    });
                } else {
                    updateExperienceHistory(folder, () => {
                        showError(`Zakończono przetwarzanie ${getCategoryName(folder)}`);
                        setTimeout(resolve, 2000);
                    });
                }
            });

            if (shouldCancel) {
                showError('Anulowano zbieranie pozostałych danych.');
                break;
            }
        }

        if (!shouldCancel) {
            showError('Zakończono przetwarzanie wszystkich wybranych kategorii!');
        }
    }

    // Modyfikacja funkcji updateExperienceHistory
    function updateExperienceHistory(folder = 'all', callback = null) {
        if (isCollectingHistory) {
            showError('Aktualizacja danych jest już w trakcie. Poczekaj na zakończenie.');
            if (callback) callback();
            return;
        }

        // Ukryj główne elementy przed rozpoczęciem aktualizacji
        toggleMainElements(false);

        showError(`Rozpoczynam aktualizację danych dla ${getCategoryName(folder)}`);

        isCollectingHistory = true;
        isPaused = false;
        shouldCancel = false;
        tempExpLog = [];
        let processedPages = 0;
        let failedAttempts = 0;
        const MAX_RETRIES = 3;
        const MIN_DELAY = 2000;
        const MAX_DELAY = 2200;
        const RETRY_DELAY = 3000;

        // Pokaż przyciski kontrolne i ukryj standardowe
        const controlButtons = document.querySelector('#collection-controls');
        const standardButtons = document.querySelector('#standard-buttons');
        if (controlButtons) {
            controlButtons.style.display = 'grid';
        }
        if (standardButtons) {
            standardButtons.style.display = 'none';
        }

        // Tworzymy zbiór istniejących raportów (unikalny po source+timestamp)
        const existingKeys = new Set(experienceLog.map(e => `${e.source}|${e.timestamp}`));
        let foundDuplicate = false;

        function getRandomDelay() {
            return Math.floor(Math.random() * (MAX_DELAY - MIN_DELAY + 1)) + MIN_DELAY;
        }

        Ajax.remoteCall('reports', 'get_reports', {
            page: 1,
            folder: folder
        }, function(initialData) {
            if (!initialData || initialData.error) {
                isCollectingHistory = false;
                showError('Nie udało się pobrać informacji o raportach. Spróbuj ponownie.');
                return;
            }

            const totalPages = initialData.count;
            collectionState.totalPages = totalPages;

            function processPage(page) {
                if (!isCollectingHistory || shouldCancel || page > totalPages || foundDuplicate) {
                    finishUpdate(shouldCancel);
                    return;
                }

                if (isPaused) {
                    setTimeout(() => processPage(page), 500);
                    return;
                }

                Ajax.remoteCall('reports', 'get_reports', {
                    page: page,
                    folder: folder
                }, function(data) {
                    if (!isCollectingHistory || shouldCancel || foundDuplicate) {
                        finishUpdate(shouldCancel);
                        return;
                    }

                    if (data && !data.error && data.reports && data.reports.length > 0) {
                        failedAttempts = 0;
                        for (const report of data.reports) {
                            const expMatch = report.popupData.match(/experience.png[^>]*>(?:[^<]*<\/[^>]+>)*[^<]*<td>(\d+)<\/td>/) ||
                                            report.popupData.match(/Doświadczenie<\/span>\s*<span[^>]*>(\d+)\s*punktów/);
                            const exp = expMatch ? parseInt(expMatch[1]) : 0;

                            if (exp > 0) {
                                const key = `${report.title}|${report.date_received}`;
                                if (existingKeys.has(key)) {
                                    foundDuplicate = true;
                                    break;
                                }

                                const reportType = report.title.includes('Raport dot. pracy') ? 'work' :
                                    report.title.includes('Pojedynek') ? 'duel' :
                                    (report.title.includes('Bitwa') || report.title.includes('Fort')) ? 'battle' : 'other';

                                // Dodajemy sprawdzanie zwycięzcy dla pojedynków
                                let shouldCount = true;
                                if (reportType === 'duel') {
                                    if (report.title.includes('bandytą') || report.title.includes('bandit')) {
                                        shouldCount = true;
                                    } else {
                                        // Dla pojedynków z graczami sprawdzamy zwycięzcę
                                        const winnerMatch = report.popupData.match(/Zwycięzca:\s*([^<]+)/) ||
                                                          report.popupData.match(/(\w+)\s+wygrywa pojedynek!/);

                                        if (winnerMatch) {
                                            const winner = winnerMatch[1].trim();
                                            shouldCount = winner === playerName;
                                        } else {
                                            shouldCount = false;
                                        }
                                    }
                                }

                                if (shouldCount) {
                                    tempExpLog.push({
                                        amount: exp,
                                        source: report.title,
                                        timestamp: report.date_received,
                                        page: page,
                                        type: reportType
                                    });

                                    // Aktualizuj zapisany stan
                                    collectionState.tempLog = tempExpLog;
                                    saveCollectionState(collectionState);
                                }
                            }
                        }

                        processedPages++;
                        updateCollectionStatus(processedPages, totalPages, tempExpLog.length);

                        if (!foundDuplicate && !shouldCancel) {
                            setTimeout(() => processPage(page + 1), getRandomDelay());
                        } else {
                            finishUpdate(shouldCancel);
                        }
                    } else {
                        failedAttempts++;
                        if (failedAttempts < MAX_RETRIES && !shouldCancel) {
                            setTimeout(() => processPage(page), RETRY_DELAY);
                        } else {
                            showError(`Nie udało się przetworzyć strony ${page} po ${MAX_RETRIES} próbach`);
                            finishUpdate(shouldCancel);
                        }
                    }
                });
            }

            processPage(1);
        });

        function finishUpdate(wasCancelled = false) {
            isCollectingHistory = false;
            isPaused = false;

            // Pokaż z powrotem główne elementy
            toggleMainElements(true);

            // Przywróć standardowe przyciski i ukryj kontrolne
            const controlButtons = document.querySelector('#collection-controls');
            const standardButtons = document.querySelector('#standard-buttons');
            if (controlButtons) {
                controlButtons.style.display = 'none';
            }
            if (standardButtons) {
                standardButtons.style.display = 'grid';
            }

            if (wasCancelled) {
                showError('Anulowano aktualizację danych.');
                if (callback) callback();
                return;
            }

            if (tempExpLog.length === 0) {
                showError(`Brak nowych wpisów w kategorii ${getCategoryName(folder)}.`);
                if (callback) callback();
                return;
            }

            // Dodaj nowe wpisy na początek loga (bo są najnowsze)
            experienceLog = tempExpLog.concat(experienceLog);
            totalExperience = experienceLog.reduce((sum, entry) => sum + entry.amount, 0);

            localStorage.setItem('experienceLog', JSON.stringify(experienceLog));
            localStorage.setItem('totalExperience', JSON.stringify(totalExperience));

            updateDisplay();
            updateXPStats();

            showError(`Zaktualizowano ${getCategoryName(folder)}! Dodano ${tempExpLog.length} nowych wpisów.`);

            if (callback) {
                callback();
            }
        }
    }

    // Funkcja do sprawdzania ilości stron dla różnych typów raportów
    function checkReportPages() {
        const types = [
            { name: 'Wszystkie raporty', params: { folder: 'all' } },
            { name: 'Raporty z pracy', params: { folder: 'job' } },
            { name: 'Raporty z pojedynków', params: { folder: 'duel' } },
            { name: 'Raporty z bitew fortowych', params: { folder: 'fortbattle' } }
        ];

        let results = {};
        let completed = 0;

        showError('Rozpoczynam sprawdzanie raportów...');

        types.forEach(type => {
            Ajax.remoteCall('reports', 'get_reports', {
                page: 1,
                ...type.params
            }, function(response) {
                completed++;

                if (response && !response.error) {
                    results[type.name] = {
                        totalPages: response.pages || response.count || 0,
                        reportsPerPage: response.reports ? response.reports.length : 0,
                        totalReports: response.total || (response.reports ? response.reports.length * (response.pages || response.count || 0) : 0)
                    };
                } else {
                    results[type.name] = {
                        error: response ? response.error : 'Brak odpowiedzi'
                    };
                }

                if (completed === types.length) {
                    let resultMessage = 'Statystyki raportów:\n\n';
                    Object.entries(results).forEach(([name, data]) => {
                        resultMessage += `${name}:\n`;
                        if (data.error) {
                            resultMessage += `  Błąd: ${data.error}\n`;
                        } else {
                            resultMessage += `  Liczba stron: ${data.totalPages}\n`;
                            resultMessage += `  Raportów na stronę: ${data.reportsPerPage}\n`;
                            resultMessage += `  Łączna liczba raportów: ${data.totalReports}\n`;
                            if (data.reportsPerPage > 0) {
                                resultMessage += `  Szacowana łączna liczba raportów: ${data.totalPages * data.reportsPerPage}\n`;
                            }
                            resultMessage += '------------------------\n';
                        }
                    });
                    showError(resultMessage, 10000); // Pokazuj przez 10 sekund
                }
            });
        });

        return "Sprawdzanie ilości stron... Wyniki pojawią się w oknie statusu.";
    }

    // Dodaj do window aby było dostępne w konsoli
    window.checkReportPages = checkReportPages;

    // Dodanie okna śledzenia doświadczenia
    setInterval(() => {
        addExperienceWindow();
        createVisibilityToggle();
    }, 1000);

    // Funkcja do przełączania widoczności
    function toggleTrackerVisibility() {
        const tracker = document.querySelector('#experience-tracker');
        const toggleCheckbox = document.querySelector('#toggle-tracker-visibility');
        if (tracker && toggleCheckbox) {
            isTrackerVisible = toggleCheckbox.checked;
            tracker.style.display = isTrackerVisible ? 'block' : 'none';
            localStorage.setItem('experienceTrackerVisible', JSON.stringify(isTrackerVisible));
        }
    }

    // Funkcja do tworzenia checkboxa widoczności
    function createVisibilityToggle() {
        const existingToggle = document.querySelector('#tracker-visibility-toggle');
        if (existingToggle) return;

        const toggleContainer = document.createElement('div');
        toggleContainer.id = 'tracker-visibility-toggle';

        // Pozycjonowanie względem ui_topbar
        const uiTopbar = document.querySelector('#ui_topbar');
        const topbarRect = uiTopbar ? uiTopbar.getBoundingClientRect() : null;

        toggleContainer.style.cssText = `
            position: fixed;
            top: ${topbarRect ? topbarRect.top + 'px' : '10px'};
            right: ${topbarRect ? (window.innerWidth - topbarRect.left) + 'px' : '310px'};
            background: rgba(20, 20, 20, 0.95);
            padding: 5px 10px;
            border-radius: 4px;
            border: 1px solid #444;
            z-index: 1000;
            color: white;
            font-family: Arial, sans-serif;
            font-size: 12px;
            display: flex;
            align-items: center;
            gap: 5px;
            cursor: pointer;
        `;

        toggleContainer.innerHTML = `
            <input type="checkbox" id="toggle-tracker-visibility" ${isTrackerVisible ? 'checked' : ''}>
        `;

        document.body.appendChild(toggleContainer);

        // Aktualizacja pozycji przy zmianie rozmiaru okna
        window.addEventListener('resize', () => {
            const uiTopbar = document.querySelector('#ui_topbar');
            const topbarRect = uiTopbar ? uiTopbar.getBoundingClientRect() : null;
            if (topbarRect && toggleContainer) {
                toggleContainer.style.top = topbarRect.top + 'px';
                toggleContainer.style.right = (window.innerWidth - topbarRect.left) + 'px';
            }
        });

        const checkbox = toggleContainer.querySelector('#toggle-tracker-visibility');
        checkbox.addEventListener('change', toggleTrackerVisibility);
    }
})();