// ==UserScript==
// @name         Hacker News URL Highlighter with Enhanced Panel and Scores
// @namespace    https://news.ycombinator.com/
// @version      1.5
// @description  Highlights URLs in comments on Hacker News, lists them in a toggleable panel with sorting, color coding based on frequency or upvotes, and displays scores next to each URL. Provides export functionality and hover previews only in comments.
// @author       MorganGeek
// @match        https://news.ycombinator.com/item?id=*
// @grant        GM_xmlhttpRequest
// @grant        GM_setClipboard
// @connect      *
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    // Configuration des couleurs en fonction des fréquences ou des upvotes
    const COLORS = {
        low: '#d1e7dd',      // Vert pâle
        medium: '#fff3cd',   // Jaune pâle
        high: '#f8d7da'      // Rouge pâle
    };

    // Créer un bouton pour basculer l'affichage du panneau
    const toggleButton = document.createElement('button');
    toggleButton.textContent = 'Afficher les URLs';
    toggleButton.style.position = 'fixed';
    toggleButton.style.bottom = '10px';
    toggleButton.style.right = '10px';
    toggleButton.style.zIndex = 1000;
    toggleButton.style.padding = '10px 15px';
    toggleButton.style.backgroundColor = '#ff6600';
    toggleButton.style.color = '#fff';
    toggleButton.style.border = 'none';
    toggleButton.style.borderRadius = '5px';
    toggleButton.style.cursor = 'pointer';
    document.body.appendChild(toggleButton);

    // Créer un panneau flottant pour afficher les URLs (caché par défaut)
    const panel = document.createElement('div');
    panel.id = 'url-panel';
    panel.style.position = 'fixed';
    panel.style.top = '10px';
    panel.style.right = '10px';
    panel.style.width = '350px';
    panel.style.backgroundColor = '#fff';
    panel.style.border = '1px solid #ccc';
    panel.style.borderRadius = '5px';
    panel.style.padding = '10px';
    panel.style.boxShadow = '0px 0px 10px rgba(0,0,0,0.2)';
    panel.style.maxHeight = '80vh';
    panel.style.overflowY = 'auto';
    panel.style.zIndex = 1000;
    panel.style.display = 'none'; // Caché par défaut
    panel.innerHTML = `
        <h4>URLs</h4>
        <div style="margin-bottom: 10px;">
            <label for="sort-select">Trier par:</label>
            <select id="sort-select" style="width: 100%; padding: 5px; margin-top: 5px;">
                <option value="frequency">Fréquence</option>
                <option value="name">Nom</option>
                <option value="upvotes">Upvotes</option>
            </select>
        </div>
        <ul id="url-list" style="margin: 0; padding: 0; list-style: none;"></ul>
        <div style="margin-top: 10px;">
            <label for="limit-select">Afficher:</label>
            <select id="limit-select" style="width: 100%; padding: 5px; margin-top: 5px;">
                <option value="all">Tout</option>
                <option value="10">Top 10</option>
                <option value="20">Top 20</option>
            </select>
        </div>
        <button id="copy-urls" style="margin-top: 10px; display: block; width: 100%; padding: 10px; background-color: #ff6600; color: #fff; border: none; border-radius: 5px; cursor: pointer;">Copier les URLs</button>
    `;
    document.body.appendChild(panel);

    // Créer une infobulle pour les aperçus
    const tooltip = document.createElement('div');
    tooltip.id = 'url-tooltip';
    tooltip.style.position = 'absolute';
    tooltip.style.backgroundColor = '#fff';
    tooltip.style.border = '1px solid #ccc';
    tooltip.style.borderRadius = '5px';
    tooltip.style.padding = '10px';
    tooltip.style.boxShadow = '0px 0px 10px rgba(0,0,0,0.2)';
    tooltip.style.maxWidth = '300px';
    tooltip.style.display = 'none';
    tooltip.style.zIndex = 1001;
    document.body.appendChild(tooltip);

    // Structure de données pour stocker les URLs avec leurs métadonnées
    const urlData = {};

    // Extraire les URLs des commentaires et les mettre en évidence
    const comments = document.querySelectorAll('.commtext');
    comments.forEach(comment => {
        const links = comment.querySelectorAll('a[href]');
        links.forEach(link => {
            const url = link.href;
            if (!urlData[url]) {
                urlData[url] = {
                    url: url,
                    count: 1,
                    upvotes: 0 // Placeholder, à implémenter si les upvotes sont disponibles
                };
                link.style.backgroundColor = '#ffff99'; // Couleur de surbrillance initiale

                // Ajouter l'URL à la liste dans le panneau
                const listItem = document.createElement('li');
                listItem.innerHTML = `<span>${url}</span> <span style="float: right; font-weight: bold;">1</span>`;
                listItem.style.marginBottom = '5px';
                listItem.style.wordWrap = 'break-word';
                listItem.style.cursor = 'pointer';
                listItem.dataset.url = url;
                panel.querySelector('#url-list').appendChild(listItem);
            } else {
                urlData[url].count += 1;
                // Mettre à jour le compteur dans le panneau
                const existingItem = panel.querySelector(`li[data-url="${CSS.escape(url)}"] span:last-child`);
                if (existingItem) {
                    existingItem.textContent = urlData[url].count;
                }
            }

            // Ajouter la fonctionnalité d'aperçu au survol des liens
            link.addEventListener('mouseover', () => {
                GM_xmlhttpRequest({
                    method: 'GET',
                    url: url,
                    onload: response => {
                        tooltip.innerHTML = '';
                        const parser = new DOMParser();
                        const doc = parser.parseFromString(response.responseText, 'text/html');
                        const title = doc.querySelector('title') ? doc.querySelector('title').innerText : 'No Title';
                        const description = doc.querySelector('meta[name="description"]') ? doc.querySelector('meta[name="description"]').content : 'No Description';

                        tooltip.innerHTML = `<strong>${title}</strong><p>${description}</p>`;
                        tooltip.style.display = 'block';
                    },
                    onerror: () => {
                        tooltip.innerHTML = '<strong>Preview unavailable</strong>';
                        tooltip.style.display = 'block';
                    }
                });

                const rect = link.getBoundingClientRect();
                tooltip.style.top = `${rect.bottom + window.scrollY + 5}px`;
                tooltip.style.left = `${rect.left + window.scrollX}px`;
            });

            link.addEventListener('mouseout', () => {
                tooltip.style.display = 'none';
            });
        });
    });

    // Fonction pour mettre à jour l'affichage du panneau selon les filtres
    function updatePanel() {
        const sortBy = panel.querySelector('#sort-select').value;
        const limit = panel.querySelector('#limit-select').value;

        // Convertir l'objet en tableau pour le tri
        let urlsArray = Object.values(urlData);

        // Trier en fonction du critère sélectionné
        if (sortBy === 'frequency') {
            urlsArray.sort((a, b) => b.count - a.count);
        } else if (sortBy === 'name') {
            urlsArray.sort((a, b) => a.url.localeCompare(b.url));
        } else if (sortBy === 'upvotes') {
            urlsArray.sort((a, b) => b.upvotes - a.upvotes);
        }

        // Appliquer la limite si nécessaire
        if (limit !== 'all') {
            const limitNumber = parseInt(limit);
            urlsArray = urlsArray.slice(0, limitNumber);
        }

        const urlList = panel.querySelector('#url-list');
        urlList.innerHTML = ''; // Vider la liste actuelle

        // Déterminer les fréquences pour la coloration
        const counts = urlsArray.map(item => item.count);
        const maxCount = Math.max(...counts);
        const minCount = Math.min(...counts);

        urlsArray.forEach(item => {
            const listItem = document.createElement('li');
            listItem.style.marginBottom = '5px';
            listItem.style.wordWrap = 'break-word';
            listItem.style.cursor = 'pointer';
            listItem.dataset.url = item.url;

            // Définir la couleur en fonction de la fréquence
            let color;
            const ratio = (item.count - minCount) / (maxCount - minCount + 1);
            if (ratio > 0.66) {
                color = COLORS.high;
            } else if (ratio > 0.33) {
                color = COLORS.medium;
            } else {
                color = COLORS.low;
            }
            listItem.style.backgroundColor = color;

            // Créer le contenu avec URL et score
            listItem.innerHTML = `
                <span>${item.url}</span>
                <span style="float: right; font-weight: bold;">${item.count}${item.upvotes > 0 ? ` / ${item.upvotes}` : ''}</span>
            `;

            // Ajouter l'événement de clic pour copier l'URL
            listItem.addEventListener('click', () => {
                GM_setClipboard(item.url, 'text');
                alert('URL copiée dans le presse-papiers!');
            });

            urlList.appendChild(listItem);
        });
    }

    // Initialiser le panneau
    updatePanel();

    // Écouter les changements dans les sélecteurs de tri et de limite
    panel.querySelector('#sort-select').addEventListener('change', updatePanel);
    panel.querySelector('#limit-select').addEventListener('change', updatePanel);

    // Gérer le bouton de bascule pour afficher/masquer le panneau
    toggleButton.addEventListener('click', () => {
        if (panel.style.display === 'none') {
            panel.style.display = 'block';
            toggleButton.textContent = 'Masquer les URLs';
        } else {
            panel.style.display = 'none';
            toggleButton.textContent = 'Afficher les URLs';
        }
    });

    // Gérer le bouton "Copier les URLs"
    panel.querySelector('#copy-urls').addEventListener('click', () => {
        const urlArray = Object.keys(urlData);
        GM_setClipboard(urlArray.join('\n'), 'text');
        alert('URLs copiées dans le presse-papiers!');
    });

    // Optionnel : Collecter les upvotes des commentaires pour chaque URL
    // Note : Hacker News n'expose pas directement les upvotes des commentaires via le DOM.
    // Si vous avez une méthode pour obtenir les upvotes, vous pouvez l'implémenter ici.
    // Par exemple, si les points des commentaires sont visibles, vous pouvez les extraire et les attribuer aux URLs.

    // Exemple de récupération des points des commentaires (si disponibles)
    const commentRows = document.querySelectorAll('tr.comtr');
    commentRows.forEach(row => {
        const commentLink = row.querySelector('a[href^="item?id="]');
        if (commentLink) {
            const pointsSpan = row.querySelector('.score');
            const points = pointsSpan ? parseInt(pointsSpan.textContent) : 0;
            const comment = row.querySelector('.commtext');
            if (comment) {
                const links = comment.querySelectorAll('a[href]');
                links.forEach(link => {
                    const url = link.href;
                    if (urlData[url]) {
                        urlData[url].upvotes += points;
                    }
                });
            }
        }
    });

    // Mettre à jour le panneau après avoir collecté les upvotes
    updatePanel();

})();