import * as common from '/pages/src/common.mjs';

let lastScan = 0;
let cachedSubgroupId = null;
let cachedEventStart = null;

// --- LA BASE DE DONNÉES "ZENMASTER" ---
// Conserve en mémoire le groupe de tous les cyclistes croisés depuis le lancement
const knownEventRiders = new Map();

export async function main() {
    if (common && common.initInteractionListeners) {
        common.initInteractionListeners();
    }

    // ALIMENTATION DE LA MÉMOIRE SÉCURISÉE EN TÂCHE DE FOND
    if (common && common.subscribe) {
        // 1. On attrape les objets complets des athlètes (radar actif)
        common.subscribe('athletes', (athletes) => {
            if (!athletes) return;
            for (const ath of athletes) {
                if (ath && ath.state) {
                    let subId = ath.state.eventSubgroupId;
                    if (subId === undefined) subId = ath.state.subgroupId;
                    
                    // Si on a l'objet complet et qu'il n'a pas de groupe, c'est la preuve formelle que c'est un Free-Rider (0)
                    if (subId === undefined) subId = 0; 
                    
                    knownEventRiders.set(Number(ath.id), Number(subId));
                }
            }
        });

        // 2. On attrape les mises à jour partielles (deltas) SANS écraser la mémoire par erreur
        common.subscribe('states', (states) => {
            if (!states) return;
            for (const s of states) {
                let subId = s.eventSubgroupId;
                if (subId === undefined) subId = s.subgroupId;

                // On met à jour uniquement si Zwift envoie explicitement l'info
                // S'il est undefined ici, on ne touche à rien pour ne pas effacer les vrais coureurs de l'event !
                if (subId !== undefined) {
                    knownEventRiders.set(Number(s.id), Number(subId));
                }
            }
        });
    }

    const container = document.body;
    container.innerHTML = `
        <h3 style="color: white; margin-top: 0; border-bottom: 1px solid #555; padding-bottom: 5px;">🏆 TESTEUR DE MAILLOTS (MÉMOIRE SÉCURISÉE)</h3>
        <div style="margin-bottom: 10px; font-size: 11px; color: #aaa;">Analyse les victoires multiples avec filtrage strict des événements...</div>
        <button id="btn-copy" style="width: 100%; padding: 10px; background-color: #fc6719; color: white; font-weight: bold; border: none; cursor: pointer; border-radius: 4px; margin-bottom: 5px; -webkit-app-region: no-drag;">📋 COPIER LE RAPPORT</button>
        <textarea id="debug-out" style="width: 100%; height: calc(100vh - 105px); background: #111; color: #00ff00; font-family: monospace; font-size: 11px; border: 1px solid #444; padding: 10px; resize: none;" readonly></textarea>
    `;

    const out = document.getElementById('debug-out');
    const btnCopy = document.getElementById('btn-copy');

    if (btnCopy) {
        btnCopy.onclick = () => {
            out.select();
            try {
                document.execCommand('copy');
                btnCopy.innerText = '✅ COPIÉ DANS LE PRESSE-PAPIER !';
                btnCopy.style.backgroundColor = '#44ff44';
                btnCopy.style.color = 'black';
                setTimeout(() => {
                    btnCopy.innerText = '📋 COPIER LE RAPPORT';
                    btnCopy.style.backgroundColor = '#fc6719';
                    btnCopy.style.color = 'white';
                }, 3000);
            } catch(e) {
                btnCopy.innerText = '❌ ERREUR';
                btnCopy.style.backgroundColor = '#ff4444';
            }
        };
    }

    if (common && common.subscribe) {
        common.subscribe('athlete/watching', async (packet) => {
            if (!packet) return;

            const now = Date.now();
            if (now - lastScan < 3000) return;
            lastScan = now;

            let text = "--- DIAGNOSTIC DES MAILLOTS EN COURS ---\n\n";

            // 1. RÉCUPÉRATION DE L'HEURE ET DE L'ID DE L'ÉVÉNEMENT
            const subId = common.athlete?.state?.eventSubgroupId || packet?.state?.eventSubgroupId;
            if (subId && subId !== cachedSubgroupId) {
                cachedSubgroupId = subId;
                cachedEventStart = null; 
                try {
                    const sg = await common.rpc.getEventSubgroup(subId);
                    if (sg && (sg.eventSubgroupStart || sg.startDate)) {
                        cachedEventStart = new Date(sg.eventSubgroupStart || sg.startDate).getTime();
                    }
                } catch(e) {}
            }

            if (cachedEventStart) {
                text += `🏁 Course officielle détectée (Départ : ${new Date(cachedEventStart).toLocaleTimeString()})\n\n`;
            } else {
                text += `🚴‍♂️ Mode Free Ride (Aucun filtre de départ)\n\n`;
            }

            const dataSource = packet.segmentData || (common.athlete ? common.athlete.segmentData : null);
            if (!dataSource) {
                out.value = text + "Aucune donnée de segment détectée.";
                return;
            }

            let entries = [];
            if (typeof dataSource.values === 'function') entries = Array.from(dataSource.values());
            else if (Array.isArray(dataSource)) entries = dataSource;
            else entries = Object.values(dataSource);

            // 2. EXTRACTION DES SEGMENTS
            let allSegments = [];
            for (const entry of entries) {
                if (Array.isArray(entry) && entry.length > 0 && entry[0].id !== undefined) {
                    allSegments = allSegments.concat(entry);
                } else if (entry && typeof entry === 'object' && entry.id && !Array.isArray(entry)) {
                    allSegments.push(entry);
                }
            }

            let uniqueSegments = new Map();
            for (const seg of allSegments) {
                if (seg.id && seg.name && !seg.name.toLowerCase().includes('finish')) {
                    uniqueSegments.set(seg.id, seg);
                }
            }

            if (uniqueSegments.size === 0) {
                out.value = text + "Aucun segment exploitable trouvé.";
                return;
            }

            let sprintLeaders = new Map();
            let komLeaders = new Map();
            let lapLeaders = new Map();
            let riderNames = new Map(); 

            text += `=== 📊 ANALYSE DES SEGMENTS (${uniqueSegments.size}) ===\n`;

            // 3. ANALYSE ET FILTRAGE STRICT
            for (const seg of uniqueSegments.values()) {
                try {
                    let results = null;
                    if (common.rpc && typeof common.rpc.getSegmentResults === 'function') {
                        results = await common.rpc.getSegmentResults(seg.id);
                    }

                    let timeRejectedCount = 0;
                    let groupRejectedCount = 0;

                    if (results) {
                        results = results.filter(r => {
                            const athId = Number(r.athleteId || r.zwid || r.id);

                            // FILTRE 1 : ANTI-ÉCHAUFFEMENT
                            if (cachedEventStart) {
                                let resultTime = r.ts || r.timestamp || r.endTime || 0;
                                if (resultTime > 0 && resultTime < 20000000000) resultTime *= 1000; 
                                
                                if (resultTime > 0 && resultTime <= cachedEventStart) {
                                    timeRejectedCount++;
                                    return false;
                                }
                            }

                            // FILTRE 2 : EXCLUSION DES INTRUS PROUVÉS
                            if (cachedSubgroupId) {
                                let rSubId = r.eventSubgroupId || r.subgroupId || (r.state && r.state.eventSubgroupId) || (r.state && r.state.subgroupId);
                                
                                // Interrogation de notre base de données sécurisée
                                if (rSubId === undefined && knownEventRiders.has(athId)) {
                                    rSubId = knownEventRiders.get(athId);
                                }
                                
                                // Radar actif en dernier recours
                                if (rSubId === undefined) {
                                    const fullAth = common.athletes && common.athletes.get(athId);
                                    if (fullAth && fullAth.state) {
                                        rSubId = fullAth.state.eventSubgroupId || fullAth.state.subgroupId;
                                        if (rSubId === undefined) rSubId = 0; // Confirmé Free-rider
                                    }
                                }

                                // Soi-même !
                                if (rSubId === undefined && athId === Number(common.athleteId) && common.athlete && common.athlete.state) {
                                    rSubId = common.athlete.state.eventSubgroupId || common.athlete.state.subgroupId;
                                }
                                
                                // REJET INTELLIGENT :
                                // On bloque UNIQUEMENT si on a la preuve formelle qu'il appartient à un autre groupe (ou 0 = free ride).
                                // S'il est resté 'undefined', c'est un échappé inconnu. On le laisse passer !
                                if (rSubId !== undefined && String(rSubId) !== String(cachedSubgroupId)) {
                                    groupRejectedCount++;
                                    return false; 
                                }
                            }
                            
                            return true;
                        });
                    }

                    if (results && results.length > 0) {
                        let ftsRes = results.slice().sort((a, b) => (a.elapsed || 99999999) - (b.elapsed || 99999999));
                        
                        let leaderMale = null;
                        let leaderFemale = null;

                        for (const r of ftsRes) {
                            let isFemale = false;
                            if (r.gender === 'female' || r.gender === 2 || r.male === false) isFemale = true;
                            else if (r.gender === 'male' || r.gender === 1 || r.male === true) isFemale = false;
                            else {
                                const athId = Number(r.athleteId || r.zwid || r.id);
                                const fullAth = common.athletes && common.athletes.get(athId);
                                if (fullAth && fullAth.athlete) {
                                    isFemale = (fullAth.athlete.gender === 'female' || fullAth.athlete.gender === 2 || fullAth.athlete.male === false);
                                }
                            }

                            if (isFemale && !leaderFemale) leaderFemale = r;
                            if (!isFemale && !leaderMale) leaderMale = r;
                            if (leaderMale && leaderFemale) break;
                        }

                        const processLeader = (leader, categoryStr) => {
                            if (leader) {
                                const leaderId = String(leader.athleteId || leader.zwid || leader.id);
                                const name = leader.name || (leader.firstName ? `${leader.firstName} ${leader.lastName}` : `ID ${leaderId}`);
                                riderNames.set(leaderId, name);

                                const segNameUpper = seg.name.toUpperCase();
                                let typeStr = "";
                                
                                if (segNameUpper.includes('KOM') || segNameUpper.includes('EPIC') || segNameUpper.includes('CLIMB')) {
                                    komLeaders.set(leaderId, (komLeaders.get(leaderId) || 0) + 1);
                                    typeStr = "KOM ⛰️";
                                } else if (segNameUpper.includes('LAP') || segNameUpper.includes('ROUTE') || segNameUpper.includes('LOOP')) {
                                    lapLeaders.set(leaderId, (lapLeaders.get(leaderId) || 0) + 1);
                                    typeStr = "LAP 🟧";
                                } else {
                                    sprintLeaders.set(leaderId, (sprintLeaders.get(leaderId) || 0) + 1);
                                    typeStr = "SPRINT ⚡";
                                }

                                text += `- ${seg.name} (${typeStr}) -> ${name} [${categoryStr}]\n`;
                            }
                        };

                        processLeader(leaderMale, "Hommes");
                        processLeader(leaderFemale, "Femmes");
                    } else {
                        let msg = `- ${seg.name} -> Aucun chrono validé en course.`;
                        if (groupRejectedCount > 0) msg += ` (🛡️ ${groupRejectedCount} intrus bloqués)`;
                        text += msg + `\n`;
                    }
                } catch (e) {}
            }

            text += `\n=== 👕 ATTRIBUTION FINALE DES MAILLOTS ===\n`;
            let hasJerseys = false;

            const allLeaderIds = new Set([...sprintLeaders.keys(), ...komLeaders.keys(), ...lapLeaders.keys()]);

            for (const id of allLeaderIds) {
                const name = riderNames.get(id);
                const k = komLeaders.get(id) || 0;
                const s = sprintLeaders.get(id) || 0;
                const l = lapLeaders.get(id) || 0;

                let imgAssigned = "Aucun";

                if (k > 0 && s > 0) {
                    imgAssigned = "maillot-vert-apois.png";
                } else if (k > 0) {
                    imgAssigned = k > 1 ? `maillot-apois-${Math.min(k, 4)}.png` : "maillot-apois.png";
                } else if (s > 0) {
                    imgAssigned = s > 1 ? `maillot-vert-${Math.min(s, 4)}.png` : "maillot-vert.png";
                } else if (l > 0) {
                    imgAssigned = l > 1 ? `maillot-orange-${Math.min(l, 2)}.png` : "maillot-orange.png";
                }

                text += `> ${name}\n`;
                text += `  Victoires : ${s} Sprint(s), ${k} KOM(s), ${l} Lap(s)\n`;
                text += `  Fichier   : 📁 ${imgAssigned}\n\n`;
                hasJerseys = true;
            }

            if (!hasJerseys) text += "Aucun maillot attribué pour l'instant.\n";

            out.value = text;
        });
    }
}