FMP Yetenek Analizcisi

FMP oyuncu sayfasını tam analiz eder: Mevki puanı, gizli yeteneklere göre revize edilmiş potansiyel tahmini ve antrenman tavsiyesi sunar. Artık yıldız derecelendirmesi ve hata bildirim özelliği içerir.

// ==UserScript==
// @name         FMP Yetenek Analizcisi
// @namespace    kalenderadam
// @version      1.3
// @description  FMP oyuncu sayfasını tam analiz eder: Mevki puanı, gizli yeteneklere göre revize edilmiş potansiyel tahmini ve antrenman tavsiyesi sunar. Artık yıldız derecelendirmesi ve hata bildirim özelliği içerir.
// @description:tr FMP oyuncu sayfasını tam analiz eder: Mevki puanı, gizli yeteneklere göre revize edilmiş potansiyel tahmini ve antrenman tavsiyesi sunar. Artık yıldız derecelendirmesi ve hata bildirim özelliği içerir.
// @author       Kalenderadam (ve AI Asistanı)
// @match        https://*.footballmanagerproject.com/Team/Player?id=*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=footballmanagerproject.com
// @grant        none
// @license      MIT
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    // --- AYARLAR ---
    const YOUR_FMP_USER_ID = "16531";

    const skillWeights = {
        DC: { "Markaj": 1.0, "Top Kapma": 1.0, "Kafa": 1.0, "Pozisyon Alma": 0.9, "Dayanıklılık": 0.8, "Uzaktan Şut": 0.6, "Teknik": 0.5, "Pas": 0.5, "Hız": 0.5, "Orta": 0.3, "Bitiricilik": 0.2 },
        DL: { "Top Kapma": 1.0, "Orta": 1.0, "Dayanıklılık": 0.8, "Markaj": 0.6, "Teknik": 0.6, "Pas": 0.6, "Pozisyon Alma": 0.6, "Uzaktan Şut": 0.6, "Kafa": 0.6, "Hız": 0.5, "Bitiricilik": 0.4 },
        DR: { "Top Kapma": 1.0, "Orta": 1.0, "Dayanıklılık": 0.8, "Markaj": 0.6, "Teknik": 0.6, "Pas": 0.6, "Pozisyon Alma": 0.6, "Uzaktan Şut": 0.6, "Kafa": 0.6, "Hız": 0.5, "Bitiricilik": 0.4 },
        DMC: { "Top Kapma": 0.9, "Kafa": 0.9, "Pozisyon Alma": 0.8, "Dayanıklılık": 0.8, "Markaj": 0.7, "Pas": 0.7, "Uzaktan Şut": 0.7, "Teknik": 0.6, "Hız": 0.5, "Bitiricilik": 0.4, "Orta": 0.3 },
        DML: { "Top Kapma": 1.0, "Orta": 1.0, "Dayanıklılık": 0.8, "Pas": 0.7, "Teknik": 0.6, "Pozisyon Alma": 0.6, "Uzaktan Şut": 0.6, "Kafa": 0.6, "Hız": 0.5, "Markaj": 0.5, "Bitiricilik": 0.4 },
        DMR: { "Top Kapma": 1.0, "Orta": 1.0, "Dayanıklılık": 0.8, "Pas": 0.7, "Teknik": 0.6, "Pozisyon Alma": 0.6, "Uzaktan Şut": 0.6, "Kafa": 0.6, "Hız": 0.5, "Markaj": 0.5, "Bitiricilik": 0.4 },
        MC: { "Pas": 1.0, "Teknik": 0.8, "Pozisyon Alma": 0.8, "Dayanıklılık": 0.8, "Top Kapma": 0.7, "Uzaktan Şut": 0.7, "Kafa": 0.6, "Markaj": 0.5, "Hız": 0.5, "Bitiricilik": 0.5, "Orta": 0.4 },
        ML: { "Orta": 1.0, "Pas": 0.8, "Dayanıklılık": 0.8, "Pozisyon Alma": 0.7, "Uzaktan Şut": 0.7, "Teknik": 0.6, "Top Kapma": 0.6, "Kafa": 0.6, "Bitiricilik": 0.6, "Hız": 0.5, "Markaj": 0.4 },
        MR: { "Orta": 1.0, "Pas": 0.8, "Dayanıklılık": 0.8, "Pozisyon Alma": 0.7, "Uzaktan Şut": 0.7, "Teknik": 0.6, "Top Kapma": 0.6, "Kafa": 0.6, "Bitiricilik": 0.6, "Hız": 0.5, "Markaj": 0.4 },
        AMC: { "Pas": 1.0, "Uzaktan Şut": 1.0, "Bitiricilik": 0.9, "Dayanıklılık": 0.8, "Teknik": 0.7, "Pozisyon Alma": 0.7, "Kafa": 0.7, "Hız": 0.5, "Orta": 0.4, "Markaj": 0.3, "Top Kapma": 0.3 },
        AML: { "Orta": 1.0, "Dayanıklılık": 0.8, "Pas": 0.8, "Pozisyon Alma": 0.8, "Teknik": 0.7, "Uzaktan Şut": 0.7, "Bitiricilik": 0.6, "Kafa": 0.6, "Top Kapma": 0.5, "Hız": 0.5, "Markaj": 0.3 },
        AMR: { "Orta": 1.0, "Dayanıklılık": 0.8, "Pas": 0.8, "Pozisyon Alma": 0.8, "Teknik": 0.7, "Uzaktan Şut": 0.7, "Bitiricilik": 0.6, "Kafa": 0.6, "Top Kapma": 0.5, "Hız": 0.5, "Markaj": 0.3 },
        FC: { "Bitiricilik": 1.0, "Kafa": 1.0, "Uzaktan Şut": 0.8, "Dayanıklılık": 0.8, "Teknik": 0.7, "Pas": 0.7, "Pozisyon Alma": 0.7, "Top Kapma": 0.5, "Hız": 0.5, "Orta": 0.4, "Markaj": 0.2 },
        GK: { "Elle Kontrol": 1.0, "Refleks": 1.0, "Bire Bir": 0.8, "Pozisyon Alma": 0.7, "Hava Hakimiyeti": 0.6, "Zıplama": 0.6, "Hız": 0.6, "Sıçrama": 0.5, "Degaj": 0.5, "Elle Pas": 0.5, "Dayanıklılık": 0.5 }
    };
    const skillAbbrToFullName = {
        Tec: 'Tecrübe', Day: 'Dayanıklılık', Hız: 'Hız', Mrkj: 'Markaj', TpK: 'Top Kapma', Poz: 'Pozisyon Alma',
        Pas: 'Pas', Ort: 'Orta', Tek: 'Teknik', Kaf: 'Kafa', Bit: 'Bitiricilik', Uza: 'Uzaktan Şut',
        ElK: 'Elle Kontrol', '1e1': 'Bire Bir', Ref: 'Refleks', HH: 'Hava Hakimiyeti', Sçr: 'Sıçrama',
        Deg: 'Degaj', Zıp: 'Zıplama', ElP: 'Elle Pas'
    };

    function scoreToStars(score) {
        const fullStar = '★'; const halfStar = '½'; const emptyStar = '☆';
        let stars = score / 5;
        let fullStars = Math.floor(stars);
        let halfStars = (stars - fullStars >= 0.5) ? 1 : 0;
        let emptyStars = 5 - fullStars - halfStars;
        return fullStar.repeat(fullStars) + halfStar.repeat(halfStars) + emptyStar.repeat(emptyStars);
    }

    function safeQuerySelector(selector) { return document.querySelector(selector); }

    // --- YENİLENMİŞ YETENEK OKUMA FONKSİYONU ---
    function getSkillsFromPage() {
        const skills = {};
        const skillTable = safeQuerySelector('.skilltable');
        if (!skillTable) return skills;

        // Sayfadaki TÜM yetenek başlıklarını (th) ve değerlerini (td > span.num) bul
        const allHeaders = skillTable.querySelectorAll('th');
        const allValues = skillTable.querySelectorAll('td > span.num');

        // Kısaltmalardan tam isimlere bir harita oluştur
        const abbrMap = new Map();
        allHeaders.forEach(th => {
            const abbr = th.textContent.trim();
            if (skillAbbrToFullName[abbr]) {
                abbrMap.set(th, skillAbbrToFullName[abbr]);
            }
        });

        // Değerleri doğru başlıklarla eşleştir
        allValues.forEach(valueSpan => {
            // Bir değerin başlığını bulmak için en yakın <th> elementini ara
            const parentRow = valueSpan.closest('tr');
            if (parentRow) {
                const valueIndex = Array.from(parentRow.children).indexOf(valueSpan.parentElement);
                const headerCell = parentRow.querySelector(`th:nth-child(${valueIndex})`) || parentRow.previousElementSibling?.querySelector(`th:nth-child(${valueIndex})`);

                if (headerCell && abbrMap.has(headerCell)) {
                     const fullName = abbrMap.get(headerCell);
                     skills[fullName] = parseInt(valueSpan.textContent, 10);
                }
            }
        });

        // Eğer ilk yöntemle 11'den az yetenek bulunduysa (kaleci gibi), daha genel bir arama yap
        if(Object.keys(skills).length < 11) {
             allHeaders.forEach((th, index) => {
                 const abbr = th.textContent.trim();
                 const fullName = skillAbbrToFullName[abbr];
                 if(fullName && allValues[index]){
                     skills[fullName] = parseInt(allValues[index].textContent, 10);
                 }
             });
        }
        return skills;
    }


    function analyzePlayer() {
        try {
            const positionEl = safeQuerySelector('.infotable .pitch-position');
            const position = positionEl ? positionEl.textContent.trim().replace('KL', 'GK') : null;
            const ageEl = safeQuerySelector('.infotable .age_year');
            if (!position || !ageEl) throw new Error("Temel oyuncu bilgileri (yaş/pozisyon) bulunamadı.");

            const age = parseInt(ageEl.textContent.trim(), 10);
            const skills = getSkillsFromPage();
            if (Object.keys(skills).length === 0) throw new Error("Oyuncu yetenekleri okunamadı.");

            // ... (geri kalan analiz mantığı aynı)

            const weights = skillWeights[position];
            if (!weights) throw new Error(`'${position}' mevkisi için ağırlık formülü bulunamadı.`);

            let weightedSum = 0, totalWeight = 0;
            const skillDetails = [];
            for (const skillName in weights) {
                if (skills.hasOwnProperty(skillName)) {
                    weightedSum += skills[skillName] * weights[skillName];
                    totalWeight += weights[skillName];
                    skillDetails.push({ name: skillName, value: skills[skillName], weight: weights[skillName] });
                }
            }
            if (totalWeight === 0) throw new Error("Yetenek ağırlıkları hesaplanamadı.");

            const positionalScore25 = (weightedSum / totalWeight / 20) * 25;

            let hiddenTalents = { professionalism: null, fitness: null };
            let trainingAnalysis = { text: "Antrenman bilgisi bulunamadı.", color: "#ccc" };
            const reportContainer = safeQuerySelector('#ScoutInfo');
            if (reportContainer) {
                const hiddenTalentContainer = Array.from(reportContainer.querySelectorAll('.skilldev')).pop();
                if (hiddenTalentContainer) {
                    hiddenTalentContainer.querySelectorAll('div > span').forEach(span => {
                        const match = span.textContent.match(/\((\d)\/8\)/);
                        if (match && match[1]) {
                            if (span.textContent.includes('Profesyonellik')) hiddenTalents.professionalism = parseInt(match[1]);
                            else if (span.textContent.includes('Fitness')) hiddenTalents.fitness = parseInt(match[1]);
                        }
                    });
                }
            }

            const trainingElement = safeQuerySelector('#TrainingBoard table tr:nth-child(2)');
            if (trainingElement?.cells?.[0]) {
                const trainingText = trainingElement.cells[0].textContent;
                const importantSkills = skillDetails.sort((a, b) => b.weight - a.weight).slice(0, 3).map(s => s.name);
                let matchCount = importantSkills.filter(skill => trainingText.toLowerCase().includes(skill.toLowerCase().substring(0, 3))).length;
                trainingAnalysis = matchCount >= 2 ? { text: "Doğru antrenmanı alıyor.", color: "#a6f704" } : { text: "Mevkisi için daha uygun bir antrenman seçilebilir.", color: "#ff7422" };
            }

            let potentialEstimate25, potentialSource = "";
            const latestReportElement = safeQuerySelector('#ScoutInfo .rec');

            if (latestReportElement) {
                potentialEstimate25 = parseFloat(latestReportElement.textContent);
                potentialSource = "Gözlemci Raporu";
                if (hiddenTalents.professionalism !== null) {
                    const professionalismBonus = (hiddenTalents.professionalism - 4) * 0.3;
                    const fitnessBonus = (hiddenTalents.fitness !== null) ? (hiddenTalents.fitness - 4) * 0.2 : 0;
                    potentialEstimate25 = Math.min(Math.max(potentialEstimate25 + professionalismBonus + fitnessBonus, 0), 25.0);
                    potentialSource = "Revize Edilmiş Rapor";
                }
            } else {
                let ageMultiplier = age < 18 ? 1.35 : age < 21 ? 1.25 : age < 24 ? 1.15 : age < 28 ? 1.05 : 1.0;
                potentialEstimate25 = Math.min(positionalScore25 * ageMultiplier, 25.0);
                potentialSource = "Yaş Tahmini";
            }

            displayReport({ position, positionalScore25, potentialEstimate25, age, skillDetails, potentialSource, trainingAnalysis });

        } catch (error) {
            console.error("FMP Analiz Betiği Hatası:", error);
            handleError(error);
        }
    }

    function handleError(error) {
        let oldReport = document.getElementById('aiScoutReport');
        if (oldReport) oldReport.remove();

        const errorPanel = document.createElement('div');
        errorPanel.id = 'aiScoutReport';
        errorPanel.style.cssText = `position: fixed; top: 100px; right: 20px; width: 300px; background-color: #4d2121; border: 2px solid #dc3545; border-radius: 8px; padding: 15px; z-index: 10000; color: #fff; font-family: 'Roboto', sans-serif; box-shadow: 0 0 15px rgba(0,0,0,0.5);`;

        const closeButton = document.createElement('button');
        closeButton.innerHTML = '&times;';
        closeButton.style.cssText = `position: absolute; top: 5px; right: 10px; background: none; border: none; color: #fff; font-size: 24px; cursor: pointer;`;
        closeButton.onclick = () => errorPanel.remove();

        const title = document.createElement('h3');
        title.textContent = 'Analiz Hatası!';
        title.style.cssText = `color: #ffc107; margin: 0 0 10px 0; border-bottom: 1px solid #dc3545; padding-bottom: 5px;`;

        const errorMessage = document.createElement('p');
        errorMessage.textContent = `Hata Mesajı: ${error.message}`;
        errorMessage.style.margin = '10px 0';

        const reportLink = createReportLink(error);
        const linkParagraph = document.createElement('p');
        linkParagraph.textContent = 'Bu hatayı geliştiriciye bildirmek için aşağıdaki linke tıklayın. Mesaj otomatik olarak oluşturulacaktır.';
        linkParagraph.style.marginTop = '15px';
        linkParagraph.appendChild(reportLink);

        errorPanel.appendChild(closeButton);
        errorPanel.appendChild(title);
        errorPanel.appendChild(errorMessage);
        errorPanel.appendChild(linkParagraph);
        document.body.appendChild(errorPanel);
    }

    function createReportLink(error) {
        const url = new URL(window.location.href);
        const playerId = url.searchParams.get('id');
        const subject = encodeURIComponent(`Yetenek Analizcisi Hata Raporu (Oyuncu ID: ${playerId})`);
        const body = encodeURIComponent(
            `Merhaba,\n\nFMP Yetenek Analizcisi betiği bir hata ile karşılaştı. Hata detayları aşağıdadır:\n\n` +
            `Hata Mesajı: ${error.message}\n` +
            `Oyuncu Sayfası: ${window.location.href}\n` +
            `Betiğin Sürümü: 1.4\n\n` + // Sürüm güncellendi
            `Stack Trace:\n${error.stack}`
        );
        const mailUrl = `/Team/Mail?mode=New&recipientId=${YOUR_FMP_USER_ID}&subj=${subject}&body=${body}`;
        const reportLink = document.createElement('a');
        reportLink.href = mailUrl;
        reportLink.textContent = "Hata Raporu Gönder";
        reportLink.target = "_blank";
        reportLink.style.cssText = `display: block; text-align: center; margin-top: 10px; padding: 8px; background-color: #007bff; color: white; text-decoration: none; border-radius: 4px;`;
        return reportLink;
    }

    function displayReport({ position, positionalScore25, potentialEstimate25, age, skillDetails, potentialSource, trainingAnalysis }) {
        let oldReport = document.getElementById('aiScoutReport');
        if (oldReport) oldReport.remove();

        const reportPanel = document.createElement('div');
        reportPanel.id = 'aiScoutReport';
        reportPanel.style.cssText = `position: fixed; top: 100px; right: 20px; width: 300px; background-color: #2a3128; border: 2px solid #53a12c; border-radius: 8px; padding: 15px; z-index: 10000; color: #fff; font-family: 'Roboto', sans-serif; box-shadow: 0 0 15px rgba(0,0,0,0.5);`;

        const closeButton = document.createElement('button');
        closeButton.innerHTML = '&times;';
        closeButton.style.cssText = `position: absolute; top: 5px; right: 10px; background: none; border: none; color: #fff; font-size: 24px; cursor: pointer;`;
        closeButton.onclick = () => reportPanel.remove();

        const title = document.createElement('h3');
        title.textContent = 'AI Gözlemci Raporu';
        title.style.cssText = `color: #a6f704; margin: 0 0 10px 0; border-bottom: 1px solid #53a12c; padding-bottom: 5px;`;

        const scoresDiv = document.createElement('div');
        scoresDiv.innerHTML = `
            <p style="margin: 5px 0; display: flex; justify-content: space-between; align-items: center;">
                <strong>Mevki Puanı (${position.replace('GK', 'KL')}):</strong>
                <span style="color: #a6f704; font-size: 1.2em;">
                    ${scoreToStars(positionalScore25)} (${positionalScore25.toFixed(1)})
                </span>
            </p>
            <p style="margin: 5px 0; display: flex; justify-content: space-between; align-items: center;">
                <strong>Potansiyel Tahmini (${potentialSource}):</strong>
                <span style="color: #e1d919; font-size: 1.2em;">
                    ${scoreToStars(potentialEstimate25)} (${potentialEstimate25.toFixed(1)})
                </span>
            </p>
        `;

        skillDetails.sort((a, b) => b.weight - a.weight);
        const keySkills = skillDetails.slice(0, 3).map(s => `<li style="color: #a6f704;">${s.name} (${s.value})</li>`).join('');
        const weakSkills = skillDetails.slice(-3).map(s => `<li style="color: #ff7422;">${s.name} (${s.value})</li>`).join('');

        const detailsDiv = document.createElement('div');
        detailsDiv.innerHTML = `
            <h4 style="margin-top: 15px; color: #fff;">Mevki İçin Önemli Yetenekler:</h4>
            <ul style="margin: 0; padding-left: 20px;">${keySkills}</ul>
            <h4 style="margin-top: 10px; color: #fff;">Mevki İçin Az Önemli Yetenekler:</h4>
            <ul style="margin: 0; padding-left: 20px;">${weakSkills}</ul>
            <h4 style="margin-top: 15px; color: #fff;">Antrenman Analizi:</h4>
            <p style="margin: 5px 0; color: ${trainingAnalysis.color};">${trainingAnalysis.text}</p>
        `;

        reportPanel.appendChild(closeButton);
        reportPanel.appendChild(title);
        reportPanel.appendChild(scoresDiv);
        reportPanel.appendChild(detailsDiv);
        document.body.appendChild(reportPanel);
    }

    function addButton() {
        if (document.getElementById('aiScoutButton')) return;
        const actionsContainer = document.querySelector('#ActionsBoard table');
        if (actionsContainer) {
            const newRow = document.createElement('tr');
            const newHeader = document.createElement('th');
            const newCell = document.createElement('td');
            newCell.className = 'td-cell';
            const button = document.createElement('div');
            button.id = 'aiScoutButton';
            button.textContent = 'AI Analizi';
            button.className = 'fmp-btn btn-yellow';
            button.style.width = '90px';
            button.onclick = analyzePlayer;
            const descriptionDl = document.createElement('dl');
            const dt = document.createElement('dt');
            dt.textContent = 'Yetenek Analizi';
            const dd = document.createElement('dd');
            dd.textContent = 'Oyuncunun mevcut yeteneklerine göre sayısal bir analiz yapar.';
            descriptionDl.appendChild(dt);
            descriptionDl.appendChild(dd);
            newHeader.appendChild(button);
            newCell.appendChild(descriptionDl);
            newRow.appendChild(newHeader);
            newRow.appendChild(newCell);
            actionsContainer.prepend(newRow);
        }
    }

    const observer = new MutationObserver((mutationsList, observer) => {
        const actionsContainer = document.querySelector('#ActionsBoard table');
        if (actionsContainer && !document.getElementById('aiScoutButton')) {
            addButton();
        }
    });
    observer.observe(document.body, { childList: true, subtree: true });

})();