// hud.js : maj des elements html du hud (hp, cd, vagues, upgrades, end game)

import { UPGRADE_CATALOG, ABILITY_COOLDOWNS, DISPLACEMENT_COOLDOWNS, SCORE_PER_KILL, SCORE_PER_SOUL, SCORE_VICTORY, SCORE_PER_WAVE } from './constants.js';
import { showEndGameForm } from './leaderboard.js';
import { send } from './network.js';
import { setInputBlocked } from './input.js';


const BUFF_LABELS = {
    invulnerable: 'Invulnerable',
    casting:      'Incantation',
    flying:       'Vol',
    intangible:   'Intangible',
    combat_buff:  'Buff combat',
    damage_mult:  'Degats x3',
};

const WAVE_STATES = {
    combat:      'Combat',
    preparation: 'Preparation',
    boss:        'Boss',
    victory:     'Victoire',
};


export function updatePlayerHud(local) {
    document.getElementById('hud-class-name').textContent = (local.class ?? '').toUpperCase();
    document.getElementById('hud-souls').textContent = 'Ames : ' + (local.souls ?? 0);

    const hpPct = local.max_hp > 0 ? Math.max(0, local.hp / local.max_hp * 100) : 0;
    document.getElementById('hud-hp-fill').style.width = hpPct + '%';
    document.getElementById('hud-hp-text').textContent = local.hp + ' / ' + local.max_hp;

    _updateSkillCooldowns(local);
    _updateBuffTags(local);
}


function _updateSkillCooldowns(local) {
    const cds     = local.cooldowns ?? {};
    const abMaxes = ABILITY_COOLDOWNS[local.class] ?? [8, 12];

    [['hud-s1', 0], ['hud-s2', 1]].forEach(([id, i]) => {
        const el    = document.getElementById(id);
        const cd    = cds['ability_' + (i + 1)] ?? 0;
        const maxCd = abMaxes[i];
        const fill  = cd <= 0 ? 100 : (1 - cd / maxCd) * 100;
        el.querySelector('.cd-fill').style.height = fill + '%';
        el.classList.toggle('ready', cd <= 0);
        el.classList.remove('locked');
    });

    const elE    = document.getElementById('hud-se');
    const cdE    = cds['displacement'] ?? 0;
    const maxCdE = DISPLACEMENT_COOLDOWNS[local.class] ?? 6;
    const fillE  = cdE <= 0 ? 100 : (1 - cdE / maxCdE) * 100;
    elE.querySelector('.cd-fill').style.height = fillE + '%';
    elE.classList.toggle('ready', cdE <= 0);
    elE.classList.remove('locked', 'divine-ready');
}


function _updateBuffTags(local) {
    const buffsEl = document.getElementById('hud-buffs');
    buffsEl.innerHTML = '';

    for (const b of (local.buffs ?? [])) {
        const label = BUFF_LABELS[b.type];
        if (!label) continue;

        const tag = document.createElement('span');
        tag.className = 'buff-tag ' + b.type;
        tag.textContent = label;
        buffsEl.appendChild(tag);
    }
}


export function updateSoulgateBar(sg) {
    if (!sg) return;
    const pct = sg.max_hp > 0 ? Math.max(0, sg.hp / sg.max_hp * 100) : 0;
    document.getElementById('sg-fill').style.width = pct + '%';
    document.getElementById('sg-hp-text').textContent = sg.hp + ' / ' + sg.max_hp;
}


export function updateWaveInfo(wave) {
    if (!wave) return;
    document.getElementById('wave-label').textContent = 'Vague ' + wave.number + ' / 3';
    document.getElementById('wave-state-label').textContent = WAVE_STATES[wave.state] ?? wave.state;
    document.getElementById('wave-enemies').textContent = 'Ennemis : ' + (wave.enemies_remaining ?? 0);
}


export function updateBossBar(wave) {
    const isBoss = wave.state === 'boss' && wave.boss_max_hp > 0;
    document.getElementById('boss-bar').classList.toggle('hidden', !isBoss);

    if (isBoss) {
        document.getElementById('boss-bar-name').textContent = wave.boss_name.toUpperCase();
        const pct = Math.max(0, wave.boss_hp / wave.boss_max_hp * 100);
        document.getElementById('boss-bar-fill').style.width = pct + '%';
        document.getElementById('boss-bar-hp').textContent = wave.boss_hp + ' / ' + wave.boss_max_hp;
    }
}


export function updateUpgradePanel(wave, local) {
    const inPrep = wave.state === 'preparation';
    document.getElementById('upgrade-panel').classList.toggle('hidden', !inPrep);
    // pendant la prep on bloque les inputs pour focus sur le menu
    setInputBlocked(inPrep || gameOver);

    if (inPrep) {
        document.getElementById('prep-timer').textContent = Math.ceil(wave.prep_timer);
        const souls = local?.souls ?? 0;
        document.getElementById('soul-count').textContent = souls;
        _updateUpgradeList(souls, local?.upgrades ?? {});
    }
}


let _upgradeListBuilt = false;
let _upgradeClickBound = false;

function _updateUpgradeList(souls, upgrades) {
    // on construit la liste 1 seule fois et on met juste a jour les stacks/disabled apres
    // sinon on detruit les boutons pendant qu'on clique dessus
    const list = document.getElementById('upgrade-list');

    if (!_upgradeListBuilt) {
        list.innerHTML = '';
        for (const [id, spec] of Object.entries(UPGRADE_CATALOG)) {
            const item = document.createElement('div');
            item.className = 'upgrade-item';
            item.dataset.id = id;
            item.innerHTML = `
                <div class="upgrade-info">
                    <div class="upgrade-name">${spec.name}</div>
                    <div class="upgrade-desc">${spec.desc}</div>
                    <div class="upgrade-stacks"></div>
                </div>
                <button class="upgrade-buy" data-id="${id}"></button>`;
            list.appendChild(item);
        }
        _upgradeListBuilt = true;
    }

    if (!_upgradeClickBound) {
        // Délégation : 1 seul listener sur la liste, ne meurt jamais avec les boutons
        list.addEventListener('click', (e) => {
            const btn = e.target.closest('.upgrade-buy');
            if (!btn || btn.disabled) return;
            send('player_upgrade', { upgrade_id: btn.dataset.id });
        });
        _upgradeClickBound = true;
    }

    for (const [id, spec] of Object.entries(UPGRADE_CATALOG)) {
        const item = list.querySelector(`.upgrade-item[data-id="${id}"]`);
        if (!item) continue;
        const stacks = upgrades[id] ?? 0;
        const maxed  = stacks >= spec.max;
        item.querySelector('.upgrade-stacks').textContent =
            '\u25cf'.repeat(stacks) + '\u25cb'.repeat(spec.max - stacks);
        const btn = item.querySelector('.upgrade-buy');
        btn.disabled    = maxed || souls < spec.cost;
        btn.textContent = maxed ? 'MAX' : spec.cost + ' ames';
    }
}

export function resetUpgradeList() {
    _upgradeListBuilt = false;
    _upgradeClickBound = false;
}


let gameOver = false;

export function resetGameOver() { gameOver = false; }

export function checkGameEnd(msg, gameStartTime, isHost = false, lobbyCode = '', submitterId = '') {
    if (gameOver) return;

    const victory = msg.wave?.state === 'victory';
    const defeat  = msg.soulgate?.hp === 0;
    if (!victory && !defeat) return;

    gameOver = true;
    setInputBlocked(true);

    const timeSecs      = gameStartTime ? Math.floor((Date.now() - gameStartTime) / 1000) : 0;
    const wavesCompleted = msg.wave?.number ?? 1;
    const players        = msg.players ?? [];

    const totalKills = players.reduce((s, p) => s + (p.enemies_killed ?? 0), 0);
    const totalSouls = players.reduce((s, p) => s + (p.souls ?? 0), 0);
    const score = totalKills * SCORE_PER_KILL
                + totalSouls * SCORE_PER_SOUL
                + (victory ? SCORE_VICTORY : 0)
                + wavesCompleted * SCORE_PER_WAVE;

    showEndGameForm({
        victory,
        score,
        timeSecs,
        wavesCompleted,
        isHost,
        lobbyCode,
        submitterId,
        players: players.map(p => ({
            username:       p.username,
            class:          p.class,
            souls:          p.souls ?? 0,
            enemies_killed: p.enemies_killed ?? 0,
        })),
    });
}
