MZ - Incoming NT Challenges

Checks if there are incoming national team challenges

// ==UserScript==
// @name         MZ - Incoming NT Challenges
// @namespace    douglaskampl
// @version      1.9
// @description  Checks if there are incoming national team challenges
// @author       Douglas
// @match        https://www.managerzone.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=managerzone.com
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_addStyle
// @grant        GM_getResourceText
// @require      https://cdnjs.cloudflare.com/ajax/libs/toastify-js/1.6.1/toastify.js
// @resource     TOASTIFY_CSS https://cdnjs.cloudflare.com/ajax/libs/toastify-js/1.6.1/toastify.css
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    GM_addStyle(GM_getResourceText('TOASTIFY_CSS'));

    const CONFIG = {
        USERNAME: '',
        COUNTRY_NAME: '',
        COUNTRY_ID: null,
        SENIOR_NT_ID: null,
        U21_NT_ID: null
    };

    const ENDPOINTS = {
        COUNTRIES_DATA: 'https://u18mz.vercel.app/mz/countriesData.json',
        USER_DATA: u => `https://www.managerzone.com/xml/manager_data.php?sport_id=1&username=${u}`,
        NATIONAL_TEAM: (nt, cid) => `https://www.managerzone.com/ajax.php?p=nationalTeams&sub=team&ntid=${nt}&cid=${cid}&type=national_team&sport=soccer`,
        CHALLENGES: 'https://www.managerzone.com/ajax.php?p=nationalTeams&sub=challenge'
    };

    const ERROR_MESSAGES = {
        COUNTRY_FETCH_FAILED: '',
        COUNTRIES_FETCH_FAILED: '',
        CHALLENGES_FETCH_FAILED: '',
        COACH_STATUS_FAILED: ''
    };

    const NOTIFICATION_SETTINGS = {
        DURATION: 5000,
        CLOSE: true,
        GRAVITY: 'top',
        POSITION: 'right',
        STYLE: {
            background: 'linear-gradient(135deg, #00b4db, #0083b0)'
        }
    };

    async function initializeConfig() {
        const u = CONFIG.USERNAME || getCurrentUsername();
        if (!u) return false;
        const cc = await fetchUserCountry(u);
        if (!cc) return false;
        const cData = await fetchCountryData(cc);
        if (!cData) return false;
        CONFIG.USERNAME = u;
        CONFIG.COUNTRY_NAME = cData.name;
        CONFIG.COUNTRY_ID = cData.cid;
        CONFIG.SENIOR_NT_ID = cData.ntid;
        CONFIG.U21_NT_ID = cData.u21ntid;
        return true;
    }

    async function fetchUserCountry(u) {
        try {
            const r = await fetch(ENDPOINTS.USER_DATA(u));
            const t = await r.text();
            const x = new DOMParser().parseFromString(t, 'text/xml');
            return x.querySelector('UserData')?.getAttribute('countryShortname');
        } catch (e) {
            return null;
        }
    }

    async function fetchCountryData(c) {
        try {
            const r = await fetch(ENDPOINTS.COUNTRIES_DATA);
            const js = await r.json();
            return js.find(a => a.name.toLowerCase() === c.toLowerCase() || a.code === c);
        } catch (e) {
            return null;
        }
    }

    function getCurrentUsername() {
        const el = document.querySelector('#header-username');
        return el ? el.textContent.trim() : '';
    }

    async function verifyNCStatus() {
        try {
            const u = ENDPOINTS.NATIONAL_TEAM(CONFIG.SENIOR_NT_ID, CONFIG.COUNTRY_ID);
            const r = await fetch(u);
            const h = await r.text();
            const doc = new DOMParser().parseFromString(h, 'text/html');
            const links = doc.querySelectorAll('a[href*="/?p=profile"]');
            for (const lk of links) {
                if (lk.textContent.trim() === CONFIG.USERNAME) return true;
            }
            return false;
        } catch (e) {
            return false;
        }
    }

    function processIncomingChallenges(cat, tid) {
        const p = new URLSearchParams({
            ntid: tid,
            cid: CONFIG.COUNTRY_ID,
            type: cat === 'U21' ? 'national_team_u21' : 'national_team',
            sport: 'soccer'
        });
        const url = `${ENDPOINTS.CHALLENGES}&${p.toString()}`;
        fetch(url)
            .then(r => r.text())
            .then(d => {
                const doc = new DOMParser().parseFromString(d, 'text/html');
                const tab = doc.querySelector('#matches_in');
                if (!tab) return;
                const rows = tab.querySelectorAll('tbody tr');
                rows.forEach(rw => {
                    const opp = rw.querySelector('td:nth-child(1) a');
                    const tim = rw.querySelector('td:nth-child(3)');
                    if (!opp || !tim) return;
                    const oppName = opp.textContent.trim();
                    const timeText = tim.textContent.trim();
                    const sk = `challenge_${oppName}_${cat}_${timeText}`;
                    if (!GM_getValue(sk, false)) {
                        Toastify({
                            text: `Incoming National Team challenge from ${oppName} (${cat}), ${timeText}`,
                            duration: NOTIFICATION_SETTINGS.DURATION,
                            close: NOTIFICATION_SETTINGS.CLOSE,
                            gravity: NOTIFICATION_SETTINGS.GRAVITY,
                            position: NOTIFICATION_SETTINGS.POSITION,
                            style: NOTIFICATION_SETTINGS.STYLE,
                        }).showToast();
                        GM_setValue(sk, true);
                    }
                });
            })
            .catch(() => {});
    }

    async function main() {
        const ok = await initializeConfig();
        if (!ok) return;
        const isNC = await verifyNCStatus();
        if (!isNC) return;
        processIncomingChallenges('senior', CONFIG.SENIOR_NT_ID);
        processIncomingChallenges('U21', CONFIG.U21_NT_ID);
    }

    main();
})();