// main.js — point d'entree client, init Pixi et handlers reseau

import { Application, Container } from 'pixi.js';
import { connect, send, on } from './network.js';
import { showLeaderboard, hideLeaderboard } from './leaderboard.js';
import { updateIsoLayout, drawStaticArena, updatePlayers, updateProjectiles, updateEnemies, updateAoeZones, updateCamera, screenToWorld } from './renderer.js';
import { loadArenaMap } from './renderArena.js';
import { startInputTracking, isInputBlocked } from './input.js';
import { updatePlayerHud, updateSoulgateBar, updateWaveInfo, updateBossBar, updateUpgradePanel, checkGameEnd } from './hud.js';
import { bindEvents } from './bindings.js';
import { loadKaelAssets, loadSerisAssets, loadAldricAssets } from './renderPlayers.js';
import { loadFractureAssets, loadRampantAssets, loadColosseAssets, loadEclatAssets, loadVexarisAssets } from './renderEnemies.js';

let localUsername = null;
let localId = null;
let isHost = false;
let lobbyCode = '';
let camX = 0, camY = 0;
let gameStartTime = null;


async function main() {
    const app = new Application();
    await app.init({
        canvas: document.getElementById('game-canvas'),
        resizeTo: window,
        backgroundAlpha: 0,
        antialias: true,
        resolution: window.devicePixelRatio || 1,
        autoDensity: true,
    });

    let worldContainer   = null;
    let layerArena       = null;
    let layerAoe         = null;
    let layerEnemies     = null;
    let layerEntities    = null;
    let layerProjectiles = null;

    const playerPool = {};
    const projPool   = {};
    const enemyPool  = {};
    const aoePool    = {};

    async function initGameWorld() {
        await loadArenaMap();
        await loadKaelAssets();
        await loadSerisAssets();
        await loadAldricAssets();
        await loadFractureAssets();
        await loadRampantAssets();
        await loadColosseAssets();
        await loadEclatAssets();
        await loadVexarisAssets();

        worldContainer   = new Container();
        layerArena       = new Container();
        layerAoe         = new Container();
        layerEnemies     = new Container();
        layerEntities    = new Container();
        layerProjectiles = new Container();

        // ordre d'affichage : arene tout en bas, projectiles tout en haut
        worldContainer.addChild(layerArena, layerAoe, layerEnemies, layerEntities, layerProjectiles);
        app.stage.addChild(worldContainer);

        updateIsoLayout(app.screen.width, app.screen.height);

        layerArena.removeChildren();
        drawStaticArena(layerArena);

        updateCamera(worldContainer, app.screen.width, app.screen.height, camX, camY);

        app.renderer.on('resize', (w, h) => {
            updateIsoLayout(w, h);
            layerArena.removeChildren();
            drawStaticArena(layerArena);
            updateCamera(worldContainer, w, h, camX, camY);
        });
    }

    connect();

    on('_open',  () => setStatus('ok',  'Connected'));
    on('_close', () => setStatus('err', 'Disconnected'));

    on('username_set', (msg) => {
        if (msg.my_id) localId = msg.my_id;
        document.getElementById('home-buttons').classList.remove('hidden');
        document.getElementById('home-username').classList.add('hidden');
    });

    on('lobby_created', (msg) => {
        isHost = true;
        lobbyCode = msg.code;
        document.getElementById('code-display').textContent = msg.code;
        document.getElementById('start-btn').classList.remove('hidden');
        switchToLobby();
        notify('Lobby created — code: ' + msg.code);
    });

    on('lobby_joined', (msg) => {
        lobbyCode = msg.code;
        switchToLobby();
        document.getElementById('code-display').textContent = msg.code;
        notify('Joined lobby ' + msg.code);
    });

    on('player_joined', (msg) => notify(msg.player.username + ' joined'));

    on('player_ready', () => {
        const btn = document.getElementById('ready-btn');
        btn.textContent = 'READY!';
        btn.classList.add('mc-btn-gold');
        btn.disabled = true;
    });

    on('game_starting', async () => {
        gameStartTime = Date.now();
        document.getElementById('home-screen').classList.add('hidden');
        document.getElementById('lobby-screen').classList.add('hidden');
        document.getElementById('loading-screen').classList.remove('hidden');

        await initGameWorld();

        document.getElementById('loading-screen').classList.add('hidden');

        ['player-hud', 'soulgate-hud', 'wave-hud', 'fullscreen-btn'].forEach(id =>
            document.getElementById(id).classList.remove('hidden')
        );

        const getTarget = () => screenToWorld(mouseX, mouseY, worldContainer.x, worldContainer.y);
        startInputTracking(getTarget);

        app.canvas.addEventListener('click', (e) => {
            if (isInputBlocked()) return;
            const { wx, wy } = screenToWorld(e.clientX, e.clientY, worldContainer.x, worldContainer.y);
            send('attack', { tx: wx, ty: wy });
        });

        app.canvas.addEventListener('contextmenu', e => e.preventDefault());
    });

    on('game_state', (msg) => {
        if (!worldContainer) return;

        updatePlayers(layerEntities, playerPool, msg.players);
        updateEnemies(layerEnemies, enemyPool, msg.enemies);
        updateProjectiles(layerProjectiles, projPool, msg.projectiles);
        updateAoeZones(layerAoe, aoePool, msg.aoe_zones ?? []);

        // retrouver le joueur local : par id si dispo (fiable meme avec pseudos en doublon), sinon par username
        const local = localId
            ? msg.players.find(p => p.id === localId)
            : localUsername
                ? msg.players.find(p => p.username === localUsername)
                : null;

        if (local) {
            camX = local.x;
            camY = local.y;
            updateCamera(worldContainer, app.screen.width, app.screen.height, camX, camY);
            updatePlayerHud(local);
        }

        updateSoulgateBar(msg.soulgate);
        updateWaveInfo(msg.wave);
        updateBossBar(msg.wave);
        updateUpgradePanel(msg.wave, local);
        checkGameEnd(msg, gameStartTime, isHost, lobbyCode, localId);
    });

    on('error', (msg) => notify(msg.message, true));

    bindEvents({
        setUsername:     (v) => { localUsername = v; },
        switchToHome,
        notify,
        showLeaderboard,
        hideLeaderboard,
    });
}


let mouseX = 0, mouseY = 0;
document.addEventListener('mousemove', e => {
    mouseX = e.clientX;
    mouseY = e.clientY;
});


function switchToLobby() {
    document.getElementById('home-screen').classList.add('hidden');
    document.getElementById('lobby-screen').classList.remove('hidden');
}

function switchToHome() {
    isHost = false;
    lobbyCode = '';
    document.getElementById('lobby-screen').classList.add('hidden');
    document.getElementById('home-screen').classList.remove('hidden');
    document.getElementById('home-buttons').classList.remove('hidden');
    document.getElementById('home-username').classList.add('hidden');
    document.getElementById('join-row').classList.add('hidden');
    document.getElementById('code-input').value = '';
    document.getElementById('code-display').textContent = '------';
    const readyBtn = document.getElementById('ready-btn');
    readyBtn.disabled = true;
    readyBtn.textContent = 'Ready';
    readyBtn.classList.remove('mc-btn-gold');
    document.getElementById('start-btn').classList.add('hidden');
    document.querySelectorAll('.class-btn').forEach(b => b.classList.remove('active'));
}


function setStatus(cls, text) {
    const el = document.getElementById('home-status');
    el.className = 'home-status ' + cls;
    el.textContent = text;
}

function notify(text, isError = false) {
    const el = document.getElementById('overlay-msg');
    if (!el) return;
    el.textContent = text;
    el.className = 'msg' + (isError ? ' err' : '');
}


main().catch(console.error);
