// ==UserScript==
// @name         XSNVShen Image URL Collector
// @namespace    violentmonkey
// @version      1.12
// @description  Collects image URLs and saves them into a text file from XSNVShen
// @author       Your Name
// @match        https://www.xsnvshen.com/*
// @grant        GM_notification
// @require      https://cdn.jsdelivr.net/npm/file-saver@2.0.5/dist/FileSaver.min.js
// ==/UserScript==

(function() {
    'use strict';

    /**
     * Creates and appends a "Save URLs" button to a given element with specific styles.
     *
     * @param {HTMLElement} element - The element to which the button will be appended.
     * @param {string} type - The type of element ('itemimg' or 'picbox') to determine the save function and styling.
     */
    function addDownloadButton(element, type) {
        let downloadButton = document.createElement('button');
        downloadButton.innerText = 'Save URLs';

        // Define base button styles
        let baseStyle = `
            font-size: 10px;
            position: absolute;
            background-color: rgba(0, 0, 0, 0.6);
            border: 1px solid #f92672;
            border-radius: 5px;
            padding: 3px;
            color: white;
            z-index: 1000;
            cursor: pointer;
        `;

        // Define position-specific styles
        let positionStyle = '';
        if (type === 'itemimg') {
            positionStyle = `
                bottom: 45px; /* Original position */
                right: 0px;
            `;
        } else if (type === 'picbox') {
            positionStyle = `
                bottom: 5px; /* Adjust as needed for picbox */
                right: 0px;
            `;
            // You can customize 'top' and 'left' to position the button as desired within picbox
        }

        downloadButton.style.cssText = baseStyle + positionStyle;

        downloadButton.onclick = function(event) {
            event.preventDefault(); // Prevent default behavior
            if (type === 'itemimg') {
                saveImageUrlsFromItemImg(element);
            } else if (type === 'picbox') {
                saveImageUrlsFromPicbox(element);
            }
        };

        // Ensure the parent has a position for absolute positioning of the button
        if (getComputedStyle(element).position === 'static') {
            element.style.position = 'relative';
        }
        element.appendChild(downloadButton);
    }

    /**
     * Adds "Save URLs" buttons to all `a.itemimg` elements.
     */
    document.querySelectorAll('a.itemimg').forEach(function(item) {
        addDownloadButton(item, 'itemimg');
    });

    /**
     * Adds "Save URLs" buttons to all `div.picbox` elements.
     */
    document.querySelectorAll('div.picbox').forEach(function(picbox) {
        addDownloadButton(picbox, 'picbox');
    });

    /**
     * Saves image URLs from an `a.itemimg` element.
     *
     * @param {HTMLElement} item - The `a.itemimg` element.
     */
    function saveImageUrlsFromItemImg(item) {
        let imgElement = item.querySelector('img.nolazy, img.lazy'); // Select both nolazy and lazy images
        if (!imgElement) {
            GM_notification(`No image found in this item.`, 'Save Failed');
            return; // No image found, exit function
        }

        let imgSrc = imgElement.getAttribute('src') || imgElement.getAttribute('data-original');
        if (!imgSrc) {
            GM_notification(`Image source not found.`, 'Save Failed');
            return;
        }

        // Construct baseUrl by removing "thumb_205x308/" and "cover.jpg"
        let baseUrl = "https:" + imgSrc.replace("thumb_205x308/", "").replace("cover.jpg", "");
        let title = item.getAttribute('title') ? item.getAttribute('title').trim() : 'untitled';
        let totalImgElement = item.querySelector('.itemset-num .num');
        if (!totalImgElement) {
            GM_notification(`Total image count not found.`, 'Save Failed');
            return;
        }
        let totalImg = parseInt(totalImgElement.innerText, 10);
        if (isNaN(totalImg)) {
            GM_notification(`Invalid total image count.`, 'Save Failed');
            return;
        }

        let imageUrls = [];
        for (let count = 0; count < totalImg; count++) {
            let formattedCount = count.toString().padStart(3, '0'); // Start from 000
            imageUrls.push(`${baseUrl}${formattedCount}.jpg`);
        }

        createTextFileWithUrls(imageUrls, title);
    }

    /**
     * Saves image URLs from a `div.picbox` element.
     *
     * @param {HTMLElement} picbox - The `div.picbox` element.
     */
    async function saveImageUrlsFromPicbox(picbox) {
        try {
            // Get the img src
            let imgElement = picbox.querySelector('img');
            if (!imgElement) {
                GM_notification(`No image found in picbox.`, 'Save Failed');
                return;
            }

            let imgSrc = imgElement.getAttribute('src') || imgElement.getAttribute('data-original');
            if (!imgSrc) {
                GM_notification(`Image source not found in picbox.`, 'Save Failed');
                return;
            }

            // Create baseUrl by removing 'thumb_256x384/' and 'cover.jpg'
            let baseUrl = "https:" + imgSrc.replace("thumb_256x384/", "").replace("cover.jpg", "");

            // Find the related 'div.titlebox'
            // Assuming 'div.titlebox' is a sibling or within the same parent as 'div.picbox'
            let parentElement = picbox.closest('.item') || picbox.parentElement;
            let titlebox = parentElement.querySelector('div.titlebox');
            if (!titlebox) {
                GM_notification(`Related titlebox not found.`, 'Save Failed');
                return;
            }

            let linkElement = titlebox.querySelector('a');
            if (!linkElement) {
                GM_notification(`Title link not found in titlebox.`, 'Save Failed');
                return;
            }

            let href = linkElement.getAttribute('href');
            if (!href) {
                GM_notification(`Href not found in title link.`, 'Save Failed');
                return;
            }

            // Construct the full TitleLink
            let titleLink = `https://www.xsnvshen.com${href}`;

            // Fetch the TitleLink page
            let response = await fetch(titleLink);
            if (!response.ok) {
                GM_notification(`Failed to fetch TitleLink page.`, 'Save Failed');
                return;
            }
            let htmlText = await response.text();

            // Parse the fetched HTML
            let parser = new DOMParser();
            let doc = parser.parseFromString(htmlText, 'text/html');

            // Select 'em#time.swpt-time span'
            let timeSpan = doc.querySelector('em#time.swpt-time span');
            if (!timeSpan) {
                GM_notification(`Time span not found in TitleLink page.`, 'Save Failed');
                return;
            }

            let timeText = timeSpan.innerText;
            // Extract the numeric value between '共' and '张' (e.g., "共 89 张")
            let match = timeText.match(/共\s*(\d+)\s*张/);
            if (!match || match.length < 2) {
                GM_notification(`Total image count not found in Time span.`, 'Save Failed');
                return;
            }

            let totalImg = parseInt(match[1], 10);
            if (isNaN(totalImg)) {
                GM_notification(`Invalid total image count.`, 'Save Failed');
                return;
            }

            // Get the title from titlebox
            let title = linkElement.innerText.trim() || 'untitled';

            // Construct image URLs
            let imageUrls = [];
            for (let count = 0; count < totalImg; count++) {
                let formattedCount = count.toString().padStart(3, '0'); // Start from 000
                imageUrls.push(`${baseUrl}${formattedCount}.jpg`);
            }

            createTextFileWithUrls(imageUrls, title);

        } catch (error) {
            console.error(error);
            GM_notification(`An error occurred: ${error.message}`, 'Save Failed');
        }
    }

    /**
     * Creates a text file from the list of URLs and triggers a download.
     *
     * @param {string[]} urls - Array of image URLs.
     * @param {string} title - The title to name the text file.
     */
    function createTextFileWithUrls(urls, title) {
        let blob = new Blob([urls.join('\n')], { type: 'text/plain' });
        saveAs(blob, `${sanitizeFilename(title)}.txt`);
        GM_notification(`Image URLs saved successfully as ${sanitizeFilename(title)}.txt`, 'Save Complete');
    }

    /**
     * Sanitizes the filename by removing or replacing invalid characters.
     *
     * @param {string} filename - The original filename.
     * @returns {string} - The sanitized filename.
     */
    function sanitizeFilename(filename) {
        return filename.replace(/[<>:"/\\|?*\x00-\x1F]/g, '').trim();
    }

})();

can you add ${baseUrl}$cover.jpg to the list?