// ==UserScript==
// @name         Add Buttons to Xiuren
// @namespace    http://tampermonkey.net/
// @version      2.2
// @description  Add custom buttons to each index_selected_box anchor in the Xiuren website for parallel downloads, ensuring valid image files only
// @author       Your Name
// @match        https://xiuren.mobi/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const script = document.createElement('script');
    script.src = "https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js";
    script.onload = function() {
        console.log('JSZip loaded');
        createButtons();
    };
    document.head.appendChild(script);

    function createButtons() {
        const targetDivs = document.querySelectorAll('div.index_selected_warp div.index_selected_box a');

        if (targetDivs.length > 0) {
            console.log(`Found ${targetDivs.length} target divs.`);

            targetDivs.forEach((targetDiv) => {
                const downloadButton = document.createElement('button');
                downloadButton.className = 'download-button';
                downloadButton.innerText = 'Download';
                downloadButton.style.cssText = `
                    font-size: 8px;
                    position: absolute;
                    background-color: #336699;
                    border: 1px solid #f92672;
                    border-radius: 3px;
                    padding: 2px;
                    color: white;
                    z-index: 10;
                    cursor: pointer;
                    opacity: 0.9;
                `;
                downloadButton.addEventListener('click', function() {
                    const imgElement = targetDiv.querySelector('img.lazy.index_selected_img.img-responsive');
                    const textElement = targetDiv.parentElement.querySelector('div.index_selected_text');
                    if (imgElement && textElement) {
                        const title = textElement.textContent || textElement.innerText;
                        const totalImagesMatch = title.match(/(\d+)P\b/);
                        const totalImages = totalImagesMatch ? Math.min(parseInt(totalImagesMatch[1], 10), 99) : 99; // Max 99
                        const imageUrl = imgElement.dataset.src || imgElement.src;
                        const issue = imageUrl.match(/\/(\d{5,8})\//)[1];
                        const alt = imgElement.alt;
                        console.log(`Attempting to download ${totalImages} images for issue: ${issue}`);
                        downloadImagesInParallel(imageUrl, issue, alt, totalImages);
                    } else {
                        console.error('Required elements not found.');
                    }
                });

                const parentDiv = targetDiv.parentElement;
                const parentRect = parentDiv.getBoundingClientRect();
                downloadButton.style.top = `${parentRect.height + 5}px`;
                downloadButton.style.right = '2px';

                parentDiv.appendChild(downloadButton);
            });
        } else {
            console.error('No target divs found!');
        }
    }

    async function fetchImageThroughWorker(url) {
        try {
            console.log(`Fetching image from ${url}`);
            const proxyUrl = `https://xiuren.maestro1four1.workers.dev/?url=${encodeURIComponent(url)}`;
            const response = await fetch(proxyUrl);
            if (response.ok) {
                const blob = await response.blob();
                if (blob.size > 100) {  // Example threshold to avoid very small or empty blobs
                    console.log(`Successfully fetched image from ${url}`);
                    return blob;
                } else {
                    console.warn(`Received empty or small blob from ${url}`);
                    return null;
                }
            } else {
                console.warn(`Failed response for ${url}: ${response.statusText}`);
                return null;
            }
        } catch (error) {
            console.error(`Error fetching from ${url}:`, error);
            return null;
        }
    }

    async function downloadImagesInParallel(baseImageUrl, issue, alt, totalImages) {
        if (!baseImageUrl || !issue) {
            console.error('Invalid image URL or issue number.');
            return;
        }

        const baseDir = baseImageUrl.match(/https:\/\/.*\/(\d{4})\//)[0];
        const zip = new JSZip();

        let downloadedCount = 0;
        const imageUrls = [];
        for (let index = 1; index <= 99; index++) { // Prepare up to 99 potential requests
            const imageIndex = index.toString().padStart(2, '0');
            const imageUrlWithIndex = `${baseDir}${issue}/${issue}${imageIndex}.jpg`;
            imageUrls.push(imageUrlWithIndex);
        }

        const CONCURRENT_DOWNLOADS = 100;
        let index = 0;

        while (index < imageUrls.length && downloadedCount < totalImages) {
            const batch = imageUrls.slice(index, index + CONCURRENT_DOWNLOADS).map(url => fetchImageThroughWorker(url));
            const results = await Promise.allSettled(batch);

            results.forEach((result, resultIndex) => {
                if (result.status === 'fulfilled' && result.value) {
                    const imageIndex = (index + resultIndex + 1).toString().padStart(2, '0');
                    zip.file(`${issue}${imageIndex}.jpg`, result.value);
                    downloadedCount++;
                    console.log(`Added ${issue}${imageIndex}.jpg to zip. Total downloaded: ${downloadedCount}`);
                } else {
                    console.warn(`Image from batch index ${index + resultIndex} not included: ${result.reason || 'Failed to fetch'}`);
                }
            });

            index += CONCURRENT_DOWNLOADS;
        }

        try {
            if (Object.keys(zip.files).length > 0) {
                console.log('Generating zip file...');
                const zipContent = await zip.generateAsync({ type: "blob" });
                const link = document.createElement('a');
                link.href = URL.createObjectURL(zipContent);
                link.download = `${alt || issue}.zip`;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                console.log('Zip file created and downloaded successfully.');
            } else {
                console.warn('No valid images were added to the zip file.');
            }
        } catch (error) {
            console.error('Error during zip generation:', error);
        }
    }

    window.addEventListener('load', function() {
        if (typeof JSZip !== 'undefined') {
            createButtons();
        }
    });
})();

does the loop always go to 99?