// ==UserScript==
// @name         TorrentBD - Persistent Sort Forum Posts by Likes
// @namespace    http://tampermonkey.net/
// @version      1.5 // Incremented version for persistence
// @description  Adds a button to sort forum posts by likes on TorrentBD, persisting across pagination for the same topic.
// @author       Your Name Here
// @match        https://www.torrentbd.net/forums.php?action=viewtopic&*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    console.log("TorrentBD Persistent Sort by Likes script starting (v1.5)...");

    const buttonId = 'sort-by-likes-button';
    let currentTopicId = null;
    let storageKey = null;

    /**
     * Extracts the topic ID from the current URL.
     * @returns {string|null} The topic ID or null if not found.
     */
    function getTopicId() {
        try {
            const urlParams = new URLSearchParams(window.location.search);
            return urlParams.get('topicid');
        } catch (e) {
            console.error("Error parsing URL parameters:", e);
            return null;
        }
    }

    /**
     * Checks if sorting is enabled for the current topic in sessionStorage.
     * @returns {boolean} True if sorting is enabled, false otherwise.
     */
    function isSortEnabledForTopic() {
        if (!storageKey) return false;
        try {
            return sessionStorage.getItem(storageKey) === 'true';
        } catch (e) {
            console.error("Error reading sessionStorage:", e);
            return false;
        }
    }

    /**
     * Enables or disables sorting persistence for the current topic.
     * @param {boolean} enable - True to enable (store flag), false to disable (remove flag).
     */
    function setSortPersistence(enable) {
        if (!storageKey) return;
        try {
            if (enable) {
                sessionStorage.setItem(storageKey, 'true');
                console.log(`Sort preference saved for topic ${currentTopicId}`);
            } else {
                sessionStorage.removeItem(storageKey);
                console.log(`Sort preference removed for topic ${currentTopicId}`);
            }
        } catch (e) {
            console.error("Error writing to sessionStorage:", e);
        }
    }

    /**
     * Extracts the like count from a post element.
     * @param {HTMLElement} postElement - The container element of a single post.
     * @returns {number} The number of likes, or 0 if not found/invalid.
     */
    function getLikeCount(postElement) {
        // Existing function - unchanged
        const likeSpan = postElement.querySelector('.like-dislike .forum-rating span[id^="likesfor"]');
        if (likeSpan && likeSpan.textContent) {
            const count = parseInt(likeSpan.textContent.trim(), 10);
            return isNaN(count) ? 0 : count;
        }
        return 0;
    }

    /**
     * Sorts the posts currently visible on the page by their like count.
     * @param {boolean} [isInitialSort=false] - True if this is the automatic sort on page load.
     */
    function sortPostsByLikes(isInitialSort = false) {
        console.log("Attempting to sort posts...");

        const postSelector = '#middle-block .col.s12[id^="post"]';
        const posts = Array.from(document.querySelectorAll(postSelector));
        console.log(`Found ${posts.length} elements matching post selector ('${postSelector}').`);

        if (posts.length < 2) {
            console.log("Not enough posts to sort.");
            if (!isInitialSort) alert("Not enough posts on this page to sort.");
            return; // Don't proceed if nothing to sort
        }

        const parentContainer = posts[0].parentNode;
        if (!parentContainer) {
            console.error("Critical Error: Could not find a parent container for the posts.");
            if (!isInitialSort) alert("Error: Could not find the container element holding the posts.");
            return;
        }
        console.log(`Identified parent container for posts: <${parentContainer.tagName} id="${parentContainer.id || ''}" class="${parentContainer.className || ''}">`);

        const lastPostOriginalSibling = posts[posts.length - 1].nextSibling;
        console.log("Reference node (sibling after last post):", lastPostOriginalSibling);

        const postsData = posts.map(post => ({
            element: post,
            likes: getLikeCount(post)
        }));

        postsData.sort((a, b) => b.likes - a.likes);

        console.log("Post data after sorting:", postsData.map(p => ({ id: p.element.id, likes: p.likes })));

        // Detach all posts from the DOM *before* re-inserting
        posts.forEach(post => post.remove());

        // Re-insert posts back into their original parent container in sorted order
        postsData.forEach(postData => {
            parentContainer.insertBefore(postData.element, lastPostOriginalSibling);
        });

        console.log(`Posts have been re-inserted into parent in sorted order (Highest: ${postsData[0]?.likes}, Lowest: ${postsData[postsData.length - 1]?.likes})`);

        // Set persistence ONLY if it wasn't the initial sort triggered by persistence
        if (!isInitialSort) {
            setSortPersistence(true);
            // Update button state immediately after manual sort
            updateButtonState(true, 'Sorted!'); // Show temporary feedback
            setTimeout(() => updateButtonState(true), 1500); // Revert to standard "Sorted" state
        } else {
             // If it was an initial sort, just ensure the button state is correct
             updateButtonState(true);
        }
    }

    /**
     * Handles the click event on the sort/unsort button.
     */
    function handleButtonClick() {
        const isCurrentlySorted = isSortEnabledForTopic();
        const sortButton = document.getElementById(buttonId);
        if (!sortButton) return;

        if (isCurrentlySorted) {
            // --- Unsort Action ---
            console.log("Unsort button clicked.");
            setSortPersistence(false);
            sortButton.textContent = 'Reloading...';
            sortButton.disabled = true;
            window.location.reload(); // Reload page to get original order
        } else {
            // --- Sort Action ---
            console.log("Sort button clicked.");
            sortButton.textContent = 'Sorting...';
            sortButton.disabled = true;
            // Use setTimeout to allow the UI to update before potentially heavy sort operation
            setTimeout(() => {
                sortPostsByLikes(false); // false indicates it's a manual sort
                // sortPostsByLikes will call updateButtonState after completion
            }, 50);
        }
    }

     /**
     * Updates the button's appearance and behavior based on the sorted state.
     * @param {boolean} isSorted - Whether the content is currently considered sorted.
     * @param {string} [tempText=null] - Optional temporary text (like 'Sorting...' or 'Sorted!').
     */
    function updateButtonState(isSorted, tempText = null) {
        const sortButton = document.getElementById(buttonId);
        if (!sortButton) return;

        sortButton.disabled = false; // Re-enable by default

        if (isSorted) {
            sortButton.textContent = tempText || 'Unsort (Reload Page)';
            sortButton.title = 'Click to remove sorting and reload the page for the original order.';
            // Optional: Change style for "unsort" state if desired
            // sortButton.style.backgroundColor = '#ff9800'; // Example: Orange for unsort
        } else {
            sortButton.textContent = tempText || 'Sort by Likes';
            sortButton.title = 'Sort posts on this page by number of likes (descending). This preference will be remembered for this topic in this session.';
            // Ensure original style is applied
            sortButton.style.backgroundColor = 'rgb(33, 150, 243)'; // Restore blue
        }

        // If tempText is provided, it usually implies a temporary disabled state
        if (tempText && (tempText === 'Sorting...' || tempText === 'Reloading...')) {
             sortButton.disabled = true;
        }
    }


    /**
     * Creates and adds the Sort/Unsort button to the page.
     */
    function addSortButton() {
        console.log("Attempting to add sort button...");
        const targetContainer = document.querySelector('#ftta-container');

        if (!targetContainer) {
             console.error("Could not find target container (#ftta-container) for sort button.");
             return; // Exit if target container not found
        }
        if (document.getElementById(buttonId)){
            console.log("Sort button already exists.");
            return; // Exit if button already exists
        }

        const sortButton = document.createElement('button');
        sortButton.id = buttonId;
        sortButton.type = 'button';

        // --- Style Application (Material UI Look) ---
        sortButton.classList.add('btn-small', 'waves-effect', 'waves-light');
        sortButton.style.backgroundColor = 'rgb(33, 150, 243)';
        sortButton.style.color = 'white';
        sortButton.style.border = 'none';
        sortButton.style.borderRadius = '4px';
        sortButton.style.padding = '6px 16px';
        sortButton.style.fontSize = '0.875rem';
        sortButton.style.fontWeight = '500';
        sortButton.style.textTransform = 'none';
        sortButton.style.letterSpacing = '0.02857em';
        sortButton.style.boxShadow = '0px 3px 1px -2px rgba(0,0,0,0.2), 0px 2px 2px 0px rgba(0,0,0,0.14), 0px 1px 5px 0px rgba(0,0,0,0.12)';
        sortButton.style.transition = 'background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms';
        sortButton.style.lineHeight = '1.75';
        sortButton.style.cursor = 'pointer';
        sortButton.style.outline = 'none';
        sortButton.style.marginLeft = '10px';
        sortButton.style.verticalAlign = 'middle';
        // --- End Style Application ---

        sortButton.addEventListener('click', handleButtonClick);

        targetContainer.appendChild(sortButton);
        console.log("Sort button added successfully.");

        // Initial button state check AFTER adding it to the DOM
        updateButtonState(isSortEnabledForTopic());
    }

    // --- Main Execution ---

    currentTopicId = getTopicId();
    if (currentTopicId) {
        storageKey = `tbd_sort_likes_topic_${currentTopicId}`;
        console.log(`Operating on Topic ID: ${currentTopicId}. Storage key: ${storageKey}`);

        // Function to run setup logic (add button, check/apply sort)
        const setup = () => {
            addSortButton(); // Creates the button and sets initial text/state

            // If persistence is enabled for this topic, sort automatically
            if (isSortEnabledForTopic()) {
                console.log("Sort preference found for this topic. Applying sort automatically.");
                // Use timeout to ensure DOM is fully ready after load event
                setTimeout(() => sortPostsByLikes(true), 100); // true = initial sort
            }
        };

        // Wait for the page content to be fully loaded
        if (document.readyState === "complete" || document.readyState === "interactive") {
            console.log("DOM ready state is complete/interactive.");
            setup();
        } else {
            console.log("Adding 'load' event listener for setup.");
            window.addEventListener('load', setup);
        }

    } else {
        console.warn("Could not determine Topic ID from URL. Sort persistence disabled for this page.");
        // Optionally, you could still add the button but without persistence:
        // if (document.readyState === "complete" || document.readyState === "interactive") { addSortButton(); }
        // else { window.addEventListener('load', addSortButton); }
        // But the current logic implicitly handles this by not proceeding if topicId is null.
    }

})();

Explain this javascript code for me