// ==UserScript==
// @name         CF Filter Recent Actions
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Filter and display recent blog entries on Codeforces based on user rating and other criteria.
// @author       Saurabh Maurya
// @match        *://codeforces.com/
// @match        *://codeforces.com/top
// @match        *://codeforces.com/blog/*
// @match        *://codeforces.com/groups/*
// @match        *://codeforces.com/ratings/*
// @match        *://codeforces.com/recent-actions
// @match        *://codeforces.com/profile/*
// @match        *://codeforces.com/search?query=*
// @match        *://codeforces.com/help
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
var rating = 1500, atLeast50 = false;
var processedAuthors = new Set();
var processedBlogIds = new Set();
var elementCount = 0;

document.querySelector('.recent-actions').parentElement.firstChild.nextSibling.innerHTML += `<span style="font-size:10px; float:right; margin-right:10px; margin-top:5px;">rating >= ${rating}, ${atLeast50.toString().toUpperCase()[0]}</span>`;
fetchData();

function getClassNameByRank(rank) {
    const rankToClassName = {
        "legendary grandmaster": "rated-user user-legendary",
        "international grandmaster": "rated-user user-red",
        "grandmaster": "rated-user user-red",
        "international master": "rated-user user-orange",
        "master": "rated-user user-orange",
        "candidate master": "rated-user user-violet",
        "expert": "rated-user user-blue",
        "specialist": "rated-user user-cyan",
        "pupil": "rated-user user-green",
        "newbie": "rated-user user-gray",
        "unrated": "rated-user user-black",
        "headquarters": "rated-user user-admin",
    };

    return rankToClassName[rank.toLowerCase()] || "";
}

function getRankTitle(rank) {
    const words = rank.split(" ");
    const capitalizedWords = words.map(word => word.charAt(0).toUpperCase() + word.slice(1));
    return capitalizedWords.join(" ");
}

async function fetchUserDetails(handles) {
    const userInfoResponse = await fetch(`https://codeforces.com/api/user.info?handles=${handles}`);
    const userInfoData = await userInfoResponse.json();
    return userInfoData.result;
}

const specialHandles = new Set(["MikeMirzayanov", "Una_Shem", "atcoder_official", "CodeChef_admin", "ICPCNews"]);

async function fetchData() {
    try {
        const response = await fetch("https://codeforces.com/api/recentActions?maxCount=100");
        const data = await response.json();

        const recentActionsElement = document.querySelector('.recent-actions ul');
        recentActionsElement.innerHTML = "";

        const handlesToFetch = [];

        for (const entry of data.result) {
            if (elementCount >= 20) {
                break;
            }

            const authorHandle = entry.blogEntry.authorHandle;
            const blogId = entry.blogEntry.id;

            if (processedAuthors.has(authorHandle) || processedBlogIds.has(blogId)) {
                continue;
            }

            processedAuthors.add(authorHandle);
            processedBlogIds.add(blogId);

            handlesToFetch.push(authorHandle);
        }

        const userInfoData = await fetchUserDetails(handlesToFetch.join(';'));
        processedBlogIds.clear();

        for (const entry of data.result) {
            if (elementCount >= 20) {
                break;
            }

            const authorHandle = entry.blogEntry.authorHandle;
            const blogId = entry.blogEntry.id;
            const blogRating = entry.blogEntry.rating;
            const creationTimeInSeconds = entry.blogEntry.creationTimeSeconds;
            const currentTimeInSeconds = Math.floor(Date.now() / 1000);
            const timeDifferenceInSeconds = currentTimeInSeconds - creationTimeInSeconds;
            const daysDifference = Math.floor(timeDifferenceInSeconds / (3600 * 24));

            if (processedBlogIds.has(blogId)) continue;
            processedBlogIds.add(blogId);
            const userData = userInfoData.find(user => user.handle === authorHandle);
            if (userData && (specialHandles.has(userData.handle) || userData.rating >= rating || (atLeast50 && blogRating >= 50))) {
                let rank = userData.rank || "unrated";
                if (authorHandle == "MikeMirzayanov" || authorHandle == "Una_Shem") rank = "headquarters";

                let rankTitle = getRankTitle(rank);

                const liElement = document.createElement('li');
                liElement.innerHTML = `
                <div style="font-size:0.9em;padding:0.5em 0;">
                    <span style="display:inline">
                        <a href="/profile/${authorHandle}" title="${rankTitle}, ${authorHandle}" class="${getClassNameByRank(rank)}">${authorHandle}</a> →
                        <a href="/blog/entry/${blogId}">${entry.blogEntry.title.replace(/<p>/g, '').replace(/<\/p>/g, '')}</a>
                        &nbsp;&nbsp;${entry.comment !== undefined ? '<img alt="New comment(s)" title="New comment(s)" src="//codeforces.org/s/51792/images/icons/comment-12x12.png" style="vertical-align:middle;">' : '<img alt="Text created or updated" title="Text created or updated" src="//codeforces.org/s/51792/images/icons/x-update-12x12.png" style="vertical-align:middle;">'}
                        ${daysDifference > 56 ? '<img alt="Necropost" title="Necropost" src="//codeforces.org/s/51792/images/icons/hourglass.png" style="vertical-align:middle; position: relative; top: 1px;">' : ''}
                    </span>
                </div>
                `;
                recentActionsElement.appendChild(liElement);
                elementCount++;
            }
        }
    } catch (error) {
        console.error("Error fetching data:", error);
    }
}

})();