// Debug client — gestion WebSocket, lobby et affichage live du game state

const WS_URL = `ws://${location.hostname}:8000/ws`;

let ws = null;
let isHost = false;
let inLobby = false;
let gameStarted = false;
let myConnId = null;  // identifié via lobby_created / lobby_joined
let lastTickTime = null;
let lastTick = null;


// Connexion

function connect() {
    ws = new WebSocket(WS_URL);
    ws.onopen = () => setStatus("Connecté", "ok");
    ws.onclose = () => {
        setStatus("Déconnecté", "error");
        gameStarted = false;
        inLobby = false;
    };
    ws.onerror = () => setStatus("Erreur WebSocket", "error");
    ws.onmessage = (e) => {
        try {
            handleMessage(JSON.parse(e.data));
        } catch {
            log("⚠ message non-JSON reçu");
        }
    };
}

function send(type, data = {}) {
    if (ws?.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify({ type, ...data }));
    }
}


// Dispatch des messages

function handleMessage(msg) {
    if (msg.type === "game_state") {
        updateGameState(msg);
        return;  // pas de log à 20 Hz
    }
    if (msg.type === "error") {
        log(`⚠ ${msg.code}: ${msg.message}`, "err");
        return;
    }
    log(`← ${msg.type}: ${JSON.stringify(msg).slice(0, 100)}`);

    switch (msg.type) {
        case "username_set":    onUsernameSet(msg);   break;
        case "lobby_created":   onLobbyCreated(msg);  break;
        case "lobby_joined":    onLobbyJoined(msg);   break;
        case "player_joined":   onPlayerJoined(msg);  break;
        case "player_left":     onPlayerLeft(msg);    break;
        case "class_selected":  onClassSelected(msg); break;
        case "player_ready":    onPlayerReady(msg);   break;
        case "game_starting":   onGameStarting(msg);  break;
    }
}


// Handlers lobby

function onUsernameSet(msg) {
    $("create-btn").disabled = false;
    $("join-btn").disabled = false;
    log(`Pseudo défini : ${msg.username}`, "ok");
}

function onLobbyCreated(msg) {
    isHost = true;
    inLobby = true;
    $("code-input").value = msg.code;
    $("class-kael").disabled = false;
    $("class-seris").disabled = false;
    $("class-aldric").disabled = false;
    $("start-btn").disabled = false;
    log(`Lobby créé — code : ${msg.code}`, "ok");
    renderLobbyPlayers([{ username: $("username-input").value, player_class: null, ready: false, host: true }]);
}

function onLobbyJoined(msg) {
    inLobby = true;
    $("code-input").value = msg.code;
    $("class-kael").disabled = false;
    $("class-seris").disabled = false;
    $("class-aldric").disabled = false;
    renderLobbyPlayers(msg.players);
}

function onPlayerJoined(msg) {
    refreshLobbyFromEvent("player_joined", msg.player);
}

function onPlayerLeft(msg) {
    refreshLobbyFromEvent("player_left", { id: msg.player_id });
}

function onClassSelected(msg) {
    // met à jour le bouton de classe si c'est nous
    if (msg.player_id === myConnId || !myConnId) {
        ["kael", "seris", "aldric"].forEach(c => {
            $(`class-${c}`).classList.toggle("active", c === msg.class);
        });
    }
}

function onPlayerReady(msg) {
    if (msg.player_id === myConnId || !myConnId) {
        $("ready-btn").classList.add("active");
        $("ready-btn").textContent = "✓ Prêt";
    }
}

function onGameStarting(msg) {
    gameStarted = true;
    log(`▶ Partie démarrée ! (countdown: ${msg.countdown}s)`, "ok");
    $("streaming").textContent = "● streaming 20 Hz";
    $("streaming").style.color = "#4caf50";
}


// Game state

function updateGameState(msg) {
    // Tick + estimation du tick rate
    const now = performance.now();
    if (lastTick !== null && lastTickTime !== null) {
        const dt = now - lastTickTime;
        const rate = (1000 / dt).toFixed(0);
        $("tick-rate").textContent = `~${rate}/s`;
    }
    lastTick = msg.tick;
    lastTickTime = now;
    $("tick").textContent = msg.tick;

    // Soulgate
    const sg = msg.soulgate;
    const sgPct = Math.round(sg.hp / sg.max_hp * 100);
    $("sg-hp").textContent = `${sg.hp} / ${sg.max_hp}`;
    $("sg-pct").textContent = `${sgPct}%`;
    $("sg-bar").style.width = `${sgPct}%`;

    // Vague
    const w = msg.wave;
    const badge = $("wave-info");
    badge.innerHTML = `<span class="wave-badge ${w.state}">Vague ${w.number} — ${w.state}${w.enemies_remaining > 0 ? ` (${w.enemies_remaining} ennemis)` : ""}</span>`;

    // Joueurs
    const container = $("players-list");
    container.innerHTML = msg.players.map(p => {
        const pct = p.alive ? Math.round(p.hp / p.max_hp * 100) : 0;
        return `
        <div class="player-card ${p.alive ? "" : "dead"}">
            <div class="phead">
                <span class="pname">${p.username}</span>
                <span class="pclass">${p.class}</span>
            </div>
            <div style="display:flex; justify-content:space-between">
                <span class="php">${p.hp} / ${p.max_hp} HP</span>
                <span style="color:#444; font-size:11px">${p.alive ? pct + "%" : "mort"}</span>
            </div>
            <div class="hp-bar">
                <div class="hp-fill ${p.alive ? p.class : "dead"}" style="width:${pct}%"></div>
            </div>
        </div>`;
    }).join("");
}


// Helpers UI

function setStatus(text, cls = "") {
    const el = $("status");
    el.textContent = text;
    el.className = "status " + cls;
}

function log(text, cls = "") {
    const pre = $("log");
    const ts = new Date().toLocaleTimeString("fr");
    const line = document.createElement("span");
    line.className = cls;
    line.textContent = `[${ts}] ${text}\n`;
    pre.appendChild(line);
    pre.scrollTop = pre.scrollHeight;
}

function $(id) { return document.getElementById(id); }

let _lobbyPlayers = [];

function renderLobbyPlayers(players) {
    _lobbyPlayers = players;
    const container = $("lobby-players");
    if (!players.length) {
        container.innerHTML = `<span style="color:#333">Aucun joueur</span>`;
        return;
    }
    container.innerHTML = players.map(p => `
        <div class="lobby-player">
            <span class="pname">${p.username ?? p.id ?? "?"}</span>
            <span class="pclass">${p.class ?? p.player_class ?? "—"}</span>
            ${p.ready ? `<span class="pready">✓</span>` : ""}
            ${p.host ? `<span class="phost">[chef]</span>` : ""}
        </div>
    `).join("");
}

function refreshLobbyFromEvent(eventType, data) {
    // re-render best-effort sans refetch complet
    if (eventType === "player_joined") {
        _lobbyPlayers.push(data);
    } else if (eventType === "player_left") {
        _lobbyPlayers = _lobbyPlayers.filter(p => p.id !== data.id);
    }
    renderLobbyPlayers(_lobbyPlayers);
}


// Event listeners

$("username-btn").addEventListener("click", () => {
    const v = $("username-input").value.trim();
    if (v) send("set_username", { username: v });
});

$("username-input").addEventListener("keydown", e => {
    if (e.key === "Enter") $("username-btn").click();
});

$("create-btn").addEventListener("click", () => send("create_lobby"));

$("join-btn").addEventListener("click", () => {
    const code = $("code-input").value.trim().toUpperCase();
    if (code) send("join_lobby", { code });
});

$("code-input").addEventListener("keydown", e => {
    if (e.key === "Enter") $("join-btn").click();
});

["kael", "seris", "aldric"].forEach(cls => {
    $(`class-${cls}`).addEventListener("click", () => {
        send("select_class", { class: cls });
    });
});

$("ready-btn").addEventListener("click", () => {
    $("ready-btn").disabled = true;
    send("ready");
});

$("start-btn").addEventListener("click", () => send("start_game"));

// Activer Ready dès qu'une classe est sélectionnée
["kael", "seris", "aldric"].forEach(cls => {
    $(`class-${cls}`).addEventListener("click", () => {
        $("ready-btn").disabled = false;
        $("ready-btn").classList.remove("active");
        $("ready-btn").textContent = "Prêt";
    });
});


// Init

connect();
