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

let userOpacity = 90;
let userZoom = 100;
let currentTab = 'team'; 

// --- INTERNAL DATABASE SCANNER (INDEXEDDB) ---
let zmTeamAssignments = null;
let zmAllTeams = null;

async function fetchZenmasterTeamsDirectly() {
    try {
        if (!indexedDB.databases) return;
        
        const dbs = await indexedDB.databases();
        let dbNamesToScan = dbs.map(db => db.name).filter(name => 
            name.toLowerCase().includes('team') || 
            name.toLowerCase().includes('point') ||
            name.toLowerCase().includes('zen')
        );

        if (dbNamesToScan.length === 0) {
            dbNamesToScan = ['teams', 'points-leaderboard', 'zenTeams'];
        }

        let foundAssignments = null;
        let foundTeams = null;

        for (let dbName of dbNamesToScan) {
            const db = await new Promise((resolve) => {
                const req = indexedDB.open(dbName);
                req.onsuccess = () => resolve(req.result);
                req.onerror = () => resolve(null);
            });

            if (!db) continue;

            for (let storeName of db.objectStoreNames) {
                const data = await new Promise((resolve) => {
                    try {
                        const tx = db.transaction(storeName, 'readonly');
                        const store = tx.objectStore(storeName);
                        const req = store.getAll();
                        req.onsuccess = () => resolve(req.result);
                        req.onerror = () => resolve(null);
                    } catch(e) { resolve(null); }
                });

                if (data && data.length > 0) {
                    const isAssignments = data.some(d => d.zwid !== undefined || d.athleteId !== undefined || (d.id !== undefined && typeof d.id === 'number' && d.id > 1000));
                    
                    if (isAssignments) {
                        foundAssignments = data;
                    } else if (data.some(d => d.color || d.bgColor || d.hex_color || storeName.toLowerCase().includes('team'))) {
                        foundTeams = data;
                    }
                }
            }
            db.close();
        }

        if (foundAssignments) zmTeamAssignments = foundAssignments;
        if (foundTeams) zmAllTeams = foundTeams;
        
    } catch(e) {}
}

fetchZenmasterTeamsDirectly();
setInterval(fetchZenmasterTeamsDirectly, 5000);

function getZenmasterOverride(athleteId, rawTeam) {
    let matchedTeamName = null;
    let matchedTeamColor = null;

    if (zmTeamAssignments) {
        let assignment = null;
        if (Array.isArray(zmTeamAssignments)) {
            assignment = zmTeamAssignments.find(t => String(t.zwid) === String(athleteId) || String(t.id) === String(athleteId) || String(t.athleteId) === String(athleteId));
        } else if (typeof zmTeamAssignments === 'object') {
            assignment = zmTeamAssignments[athleteId];
        }
        if (assignment) {
            matchedTeamName = assignment.team || assignment.teamId || assignment.teamName || assignment.name || (typeof assignment === 'string' ? assignment : null);
        }
    }

    let searchTeamName = matchedTeamName || rawTeam;
    if (searchTeamName && zmAllTeams) {
        let teamInfo = null;
        if (Array.isArray(zmAllTeams)) {
            teamInfo = zmAllTeams.find(t => 
                (t.name && String(t.name).toLowerCase() === String(searchTeamName).toLowerCase()) ||
                (t.team && String(t.team).toLowerCase() === String(searchTeamName).toLowerCase()) ||
                (t.id && String(t.id).toLowerCase() === String(searchTeamName).toLowerCase())
            );
        } else if (typeof zmAllTeams === 'object') {
            teamInfo = zmAllTeams[searchTeamName] || Object.values(zmAllTeams).find(t => t.name && String(t.name).toLowerCase() === String(searchTeamName).toLowerCase());
        }

        if (teamInfo) {
            matchedTeamColor = teamInfo.color || teamInfo.bgColor || teamInfo.hex_color || null;
            matchedTeamName = teamInfo.name || teamInfo.team || searchTeamName;
        }
    }

    return {
        name: (matchedTeamName && typeof matchedTeamName === 'string' && matchedTeamName.trim() !== '') ? matchedTeamName : null,
        color: (matchedTeamColor && matchedTeamColor !== '#FFF' && matchedTeamColor !== '#FFFFFF') ? matchedTeamColor : null
    };
}

// --- TABS MANAGEMENT ---
window.switchTab = function(tab) {
    currentTab = tab;
    const tabTeam = document.getElementById('tab-team');
    const tabIndiv = document.getElementById('tab-indiv');
    if (tabTeam) tabTeam.className = tab === 'team' ? 'tab-btn active' : 'tab-btn';
    if (tabIndiv) tabIndiv.className = tab === 'indiv' ? 'tab-btn active' : 'tab-btn';
    
    if (tab === 'team') {
        document.getElementById('list-team').classList.remove('hidden');
        document.getElementById('list-indiv').classList.add('hidden');
    } else {
        document.getElementById('list-team').classList.add('hidden');
        document.getElementById('list-indiv').classList.remove('hidden');
    }
}

// --- SETTINGS ---
function loadSettings() {
    const sOp = localStorage.getItem('myMod_Team_Op');
    const sZoom = localStorage.getItem('myMod_Team_Zoom');

    if(sOp) userOpacity = parseInt(sOp);
    if(sZoom) userZoom = parseInt(sZoom);

    document.getElementById('in-opacity').value = userOpacity;
    document.getElementById('in-zoom').value = userZoom;
    
    applyVisuals();
}

function saveSettings() {
    userOpacity = parseInt(document.getElementById('in-opacity').value);
    userZoom = parseInt(document.getElementById('in-zoom').value);
    
    localStorage.setItem('myMod_Team_Op', userOpacity);
    localStorage.setItem('myMod_Team_Zoom', userZoom);

    applyVisuals();
    document.getElementById('settings-panel').style.display = 'none';
}

function applyVisuals() {
    document.getElementById('op-label').innerText = userOpacity;
    document.getElementById('dash').style.backgroundColor = `rgba(0, 0, 0, ${userOpacity/100})`;
    document.getElementById('zoom-label').innerText = (userZoom/100).toFixed(1);
    document.getElementById('wrapper').style.transform = `scale(${userZoom/100})`;
}

// --- UTILITIES ---
function formatGap(sec) {
    if (sec == null || isNaN(sec)) return '';
    if (Math.abs(sec) < 0.5) return '';
    const sign = sec > 0 ? '+' : '-';
    const color = sec > 0 ? '#ff5555' : '#55ff55';
    return `<span style="color:${color}">${sign}${Math.round(Math.abs(sec))}s</span>`;
}

function formatName(first, last) {
    if (!last) return first || 'Unknown';
    const fInitial = first ? first.charAt(0).toUpperCase() + '.' : '';
    return `${fInitial} ${last.toUpperCase()}`;
}

function stringToColorHSL(str) {
    let hash = 0;
    let safeStr = String(str || "");
    for (let i = 0; i < safeStr.length; i++) {
        hash = safeStr.charCodeAt(i) + ((hash << 5) - hash);
    }
    const h = Math.abs(hash) % 360;
    const s = 80;
    const l = 70;
    return `hsl(${h}, ${s}%, ${l}%)`;
}

function sanitizeTeamName(rawTeam) {
    if (!rawTeam) return "Independent";
    if (Array.isArray(rawTeam)) rawTeam = rawTeam[0];
    if (typeof rawTeam === 'object' && rawTeam !== null) {
        rawTeam = rawTeam.name || rawTeam.teamName || String(rawTeam);
    }
    const str = String(rawTeam).trim();
    return str === '' ? "Independent" : str;
}

// --- LOGIC (REVERSED POINTS SCORE) ---
function updateRanking(data) {
    let riders = [];
    if (Array.isArray(data)) riders = data;
    else if (data && data.riders) riders = data.riders;
    else if (data && data.nearby) riders = data.nearby;

    if (!riders || riders.length === 0) return;

    // Tri par position sur la route (gap décroissant)
    riders.sort((a, b) => (a.gap || 0) - (b.gap || 0));

    let teams = {};
    let indivHtml = '';
    
    // Le nombre de coureurs total sert de base de points
    const totalRiders = riders.length;

    riders.forEach((r, index) => {
        let athleteId = (r.athlete && r.athlete.id) ? r.athlete.id : r.id;
        let teamName = sanitizeTeamName(r.athlete && r.athlete.team ? r.athlete.team : null);
        let teamColor = null;

        // Override Zenmaster
        let zmOverride = getZenmasterOverride(athleteId, teamName);
        if (zmOverride.name) teamName = String(zmOverride.name).trim();
        if (zmOverride.color) teamColor = zmOverride.color;
        
        if (!teamColor) teamColor = stringToColorHSL(teamName);

        let name = "Unknown";
        if (r.athlete) name = formatName(r.athlete.firstName, r.athlete.lastName);

        const position = index + 1;
        const pointsEarned = totalRiders - index; // NOUVEAU : 1er gagne N points, Dernier gagne 1 point
        const isMe = r.watching;

        if (!teams[teamName]) {
            teams[teamName] = { name: teamName, score: 0, count: 0, isMyTeam: false, color: teamColor };
        }
        
        teams[teamName].score += pointsEarned; // On AJOUTE les points
        teams[teamName].count += 1;
        if (isMe) teams[teamName].isMyTeam = true;

        let rowClass = isMe ? 'row indiv-row watching' : 'row indiv-row';
        indivHtml += `
            <div class="${rowClass}" data-id="${athleteId}" title="Cliquer pour observer ce coureur (Points rapportés : ${pointsEarned})">
                <div class="i-pos">${position}</div>
                <div class="i-name" title="${name}">${name}</div>
                <div class="i-team" title="${teamName}" style="color:${teamColor}">${teamName.substring(0,12)}</div>
                <div class="i-gap">${formatGap(r.gap || 0)}</div>
            </div>
        `;
    });

    // Exclure les indépendants du classement par équipe
    let ranking = Object.values(teams).filter(t => t.name.toLowerCase() !== 'independent' && t.name.toLowerCase() !== 'indépendant');
    
    // NOUVEAU : Tri décroissant car le plus grand score gagne
    ranking.sort((a, b) => b.score - a.score);

    let teamHtml = '';
    ranking.forEach((t, i) => {
        let style = t.isMyTeam ? 'color: #fc6719; font-weight: 900;' : '';
        teamHtml += `
            <div class="row team-row" style="border-left: 4px solid ${t.color};">
                <div class="t-rank">${i + 1}</div>
                <div class="t-name" title="${t.name}" style="${style}">
                    ${t.name} <span class="riders-count" style="color:${t.color}">(${t.count})</span>
                </div>
                <div class="t-score">${t.score} pts</div>
            </div>
        `;
    });

    document.getElementById('list-team').innerHTML = teamHtml || '<div class="msg">No data</div>';
    document.getElementById('list-indiv').innerHTML = indivHtml || '<div class="msg">No data</div>';
}

// --- MAIN ---
export async function main() {
    loadSettings();

    document.getElementById('btn-settings').addEventListener('click', () => {
        const p = document.getElementById('settings-panel');
        p.style.display = p.style.display === 'block' ? 'none' : 'block';
    });
    document.getElementById('btn-save').addEventListener('click', saveSettings);
    
    document.getElementById('in-opacity').addEventListener('input', (e) => {
        userOpacity = e.target.value; applyVisuals();
    });
    document.getElementById('in-zoom').addEventListener('input', (e) => {
        userZoom = e.target.value; applyVisuals();
    });

    // --- ECOUTEUR DE CLIC (VUE FAN) ---
    const listIndiv = document.getElementById('list-indiv');
    if (listIndiv) {
        listIndiv.addEventListener('click', async (e) => {
            const row = e.target.closest('.indiv-row');
            if (row && row.dataset.id) {
                const targetId = Number(row.dataset.id);
                try {
                    if (common.rpc && typeof common.rpc.watch === 'function') {
                        await common.rpc.watch(targetId);
                    }
                } catch (err) {
                    console.warn("Impossible de changer la caméra vers ce coureur :", err);
                }
            }
        });
    }

    if (common && common.initInteractionListeners) {
        common.initInteractionListeners();
        
        common.subscribe('status', (data) => {
            if (data && !data.connected) {
                document.getElementById('list-team').innerHTML = '<div class="msg">Waiting for Zwift...</div>';
            }
        });

        common.subscribe('nearby', updateRanking);
    }
}