<?php
// game.php — Combat Pixel
require_once 'config.php';
require_once 'includes/db.php';

logVisitor($_SERVER['REQUEST_URI']);
$topScores = getTopScores(10);
$pageTitle = 'Combat Pixel | Kompaniec';
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <title><?= htmlspecialchars($pageTitle) ?></title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
    <style>
        :root {
            --bg: #0a0a0c;
            --panel: #141416;
            --line: rgba(255, 255, 255, 0.1);
            --text: #f5f5f7;
            --muted: #86868b;
            --accent: #0071e3;
            --danger: #ff453a;
            --safe-bottom: env(safe-area-inset-bottom, 0px);
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            -webkit-tap-highlight-color: transparent;
            user-select: none;
        }

        html, body {
            height: 100%;
        }

        body {
            background: var(--bg);
            color: var(--text);
            font-family: "Outfit", "Helvetica Neue", Helvetica, Arial, sans-serif;
            min-height: 100svh;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        .topbar {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0.75rem 1rem;
            border-bottom: 1px solid var(--line);
            background: rgba(20, 20, 22, 0.9);
            backdrop-filter: blur(16px);
            z-index: 20;
            flex-shrink: 0;
        }

        .topbar a {
            color: var(--muted);
            text-decoration: none;
            font-size: 0.85rem;
        }

        .topbar a:hover { color: #fff; }

        .topbar h1 {
            font-size: 0.95rem;
            font-weight: 600;
            letter-spacing: -0.02em;
        }

        .layout {
            flex: 1;
            display: grid;
            grid-template-columns: 1fr 260px;
            gap: 0;
            min-height: 0;
            overflow: hidden;
        }

        .screen-wrap {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 0.75rem;
            min-height: 0;
            background:
                radial-gradient(ellipse 60% 50% at 50% 40%, rgba(0, 113, 227, 0.12), transparent 60%),
                #000;
        }

        .canvas-frame {
            width: 100%;
            max-width: 1000px;
            background: #000;
            border-radius: 12px;
            overflow: hidden;
            border: 1px solid var(--line);
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
            line-height: 0;
        }

        canvas {
            display: block;
            width: 100%;
            height: auto;
            touch-action: none;
            cursor: crosshair;
        }

        .hint {
            margin-top: 0.65rem;
            font-size: 0.72rem;
            color: var(--muted);
            text-align: center;
        }

        .hint kbd {
            display: inline-block;
            padding: 0.15rem 0.45rem;
            margin: 0 0.1rem;
            border-radius: 6px;
            background: rgba(255, 255, 255, 0.08);
            border: 1px solid var(--line);
            font-family: inherit;
            font-size: 0.7rem;
            color: #fff;
        }

        .side-panel {
            background: var(--panel);
            border-left: 1px solid var(--line);
            padding: 1rem;
            overflow-y: auto;
            display: flex;
            flex-direction: column;
            gap: 1rem;
        }

        .side-panel h2 {
            font-size: 0.7rem;
            letter-spacing: 0.1em;
            text-transform: uppercase;
            color: var(--muted);
            font-weight: 600;
        }

        .scores-list {
            display: flex;
            flex-direction: column;
            gap: 0.35rem;
            flex: 1;
        }

        .score-row {
            display: flex;
            align-items: center;
            gap: 0.5rem;
            padding: 0.45rem 0.55rem;
            border-radius: 8px;
            background: rgba(255, 255, 255, 0.03);
            font-size: 0.8rem;
        }

        .score-rank {
            width: 1.5rem;
            color: var(--muted);
            font-variant-numeric: tabular-nums;
        }

        .score-name {
            flex: 1;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .score-value {
            color: #2997ff;
            font-weight: 600;
            font-variant-numeric: tabular-nums;
        }

        .boss-timer {
            text-align: center;
            padding: 1rem;
            border-radius: 12px;
            background: rgba(0, 113, 227, 0.1);
            border: 1px solid rgba(0, 113, 227, 0.25);
        }

        .boss-timer.is-boss {
            background: rgba(255, 69, 58, 0.12);
            border-color: rgba(255, 69, 58, 0.35);
        }

        .timer-label {
            font-size: 0.65rem;
            letter-spacing: 0.08em;
            text-transform: uppercase;
            color: var(--muted);
            margin-bottom: 0.35rem;
        }

        .timer-number {
            font-size: 2.25rem;
            font-weight: 700;
            font-variant-numeric: tabular-nums;
            letter-spacing: -0.03em;
            color: #2997ff;
            line-height: 1;
        }

        .timer-number.warning {
            color: var(--danger);
            animation: pulse 0.5s ease-in-out infinite;
        }

        @keyframes pulse {
            0%, 100% { transform: scale(1); }
            50% { transform: scale(1.06); }
        }

        /* Touch controls */
        .touch-controls {
            display: none;
            position: fixed;
            left: 0;
            right: 0;
            bottom: 0;
            z-index: 50;
            padding: 0.6rem 1rem calc(0.6rem + var(--safe-bottom));
            background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.85) 30%);
            justify-content: space-between;
            align-items: flex-end;
            pointer-events: none;
        }

        .control-group {
            display: flex;
            gap: 0.65rem;
            pointer-events: auto;
        }

        .ctrl-btn {
            width: 64px;
            height: 64px;
            border-radius: 50%;
            border: 1px solid rgba(255, 255, 255, 0.2);
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(12px);
            color: #fff;
            font-size: 1.35rem;
            font-weight: 600;
            display: grid;
            place-items: center;
            touch-action: manipulation;
            box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
        }

        .ctrl-btn:active,
        .ctrl-btn.is-active {
            background: rgba(255, 255, 255, 0.22);
            transform: scale(0.94);
        }

        .ctrl-btn.fire {
            background: rgba(255, 69, 58, 0.85);
            border-color: rgba(255, 255, 255, 0.25);
            width: 72px;
            height: 72px;
        }

        .ctrl-btn.jump {
            background: rgba(0, 113, 227, 0.85);
            border-color: rgba(255, 255, 255, 0.25);
        }

        .name-popup {
            position: fixed;
            inset: 0;
            z-index: 100;
            background: rgba(0, 0, 0, 0.82);
            backdrop-filter: blur(12px);
            display: none;
            align-items: center;
            justify-content: center;
            padding: 1.25rem;
        }

        .name-popup-content {
            background: #1c1c1e;
            border: 1px solid var(--line);
            border-radius: 20px;
            padding: 1.75rem 1.5rem;
            width: min(340px, 100%);
            text-align: center;
        }

        .name-popup-content h3 {
            font-size: 1.25rem;
            margin-bottom: 0.35rem;
            letter-spacing: -0.02em;
        }

        .name-popup-content p {
            color: var(--muted);
            font-size: 0.9rem;
            margin-bottom: 1rem;
        }

        .name-popup-content input {
            width: 100%;
            padding: 0.85rem 1rem;
            margin-bottom: 1rem;
            border-radius: 12px;
            border: 1px solid var(--line);
            background: #000;
            color: #fff;
            font: inherit;
            text-align: center;
            font-size: 1rem;
        }

        .name-popup-content input:focus {
            outline: none;
            border-color: var(--accent);
        }

        .popup-actions {
            display: flex;
            gap: 0.5rem;
        }

        .popup-actions button {
            flex: 1;
            padding: 0.8rem;
            border-radius: 980px;
            border: none;
            font: inherit;
            font-weight: 560;
            cursor: pointer;
        }

        .popup-actions .save {
            background: var(--accent);
            color: #fff;
        }

        .popup-actions .skip {
            background: rgba(255, 255, 255, 0.1);
            color: #fff;
        }

        @media (max-width: 900px) {
            .layout {
                grid-template-columns: 1fr;
                grid-template-rows: 1fr auto;
            }

            .side-panel {
                border-left: none;
                border-top: 1px solid var(--line);
                flex-direction: row;
                align-items: stretch;
                gap: 0.75rem;
                padding: 0.75rem 0.75rem calc(96px + var(--safe-bottom));
                max-height: none;
                overflow: visible;
            }

            .scores-block {
                flex: 1;
                min-width: 0;
            }

            .scores-list {
                max-height: 88px;
                overflow-y: auto;
            }

            .boss-timer {
                flex-shrink: 0;
                min-width: 100px;
                display: flex;
                flex-direction: column;
                justify-content: center;
                padding: 0.65rem;
            }

            .timer-number {
                font-size: 1.75rem;
            }

            .hint {
                display: none;
            }

            .touch-controls {
                display: flex;
            }

            .screen-wrap {
                padding: 0.5rem;
                justify-content: flex-start;
                padding-top: 0.5rem;
            }

            .canvas-frame {
                border-radius: 8px;
            }
        }

        @media (max-width: 480px) {
            .ctrl-btn {
                width: 56px;
                height: 56px;
                font-size: 1.15rem;
            }

            .ctrl-btn.fire {
                width: 64px;
                height: 64px;
            }

            .side-panel {
                padding-bottom: calc(88px + var(--safe-bottom));
            }
        }

        @media (max-height: 700px) and (max-width: 900px) {
            .scores-list {
                max-height: 56px;
            }
        }
    </style>
</head>
<body>
    <div class="topbar">
        <a href="/">Назад</a>
        <h1>Combat Pixel</h1>
        <span style="width: 3.5rem"></span>
    </div>

    <div class="layout">
        <div class="screen-wrap">
            <div class="canvas-frame">
                <canvas id="gameCanvas" width="1000" height="600"></canvas>
            </div>
            <p class="hint">
                <kbd>A</kbd><kbd>D</kbd> ход
                <kbd>Space</kbd> прыжок
                <kbd>Shift</kbd> / клик — огонь
            </p>
        </div>

        <aside class="side-panel">
            <div class="scores-block">
                <h2>Топ-10</h2>
                <div class="scores-list" id="scoresList">
                    <?php if (empty($topScores)): ?>
                        <div class="score-row"><span class="score-name" style="color:var(--muted)">Пока нет рекордов</span></div>
                    <?php else: ?>
                        <?php foreach ($topScores as $index => $score): ?>
                        <div class="score-row">
                            <div class="score-rank">#<?= $index + 1 ?></div>
                            <div class="score-name"><?= htmlspecialchars($score['player_name']) ?></div>
                            <div class="score-value"><?= (int)$score['score'] ?></div>
                        </div>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </div>
            </div>
            <div class="boss-timer" id="bossTimer">
                <div class="timer-label" id="timerLabel">До босса</div>
                <div class="timer-number" id="timerCount">60</div>
            </div>
        </aside>
    </div>

    <div class="touch-controls" id="touchControls">
        <div class="control-group">
            <button type="button" class="ctrl-btn" data-action="left" aria-label="Влево">←</button>
            <button type="button" class="ctrl-btn" data-action="right" aria-label="Вправо">→</button>
        </div>
        <div class="control-group">
            <button type="button" class="ctrl-btn jump" data-action="jump" aria-label="Прыжок">↑</button>
            <button type="button" class="ctrl-btn fire" data-action="fire" aria-label="Огонь">●</button>
        </div>
    </div>

    <div class="name-popup" id="namePopup">
        <div class="name-popup-content">
            <h3>Новый рекорд</h3>
            <p>Введите имя для таблицы лидеров</p>
            <input type="text" id="playerName" maxlength="30" placeholder="Ваше имя" autocomplete="nickname">
            <div class="popup-actions">
                <button type="button" class="save" onclick="saveScore()">Сохранить</button>
                <button type="button" class="skip" onclick="skipScore()">Пропустить</button>
            </div>
        </div>
    </div>

<script>
(function () {
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');

    const sprites = {
        soldierR: new Image(),
        soldierL: new Image(),
        enemyR: new Image(),
        enemyL: new Image(),
        ogonR: new Image(),
        ogonL: new Image(),
        background: new Image(),
        bossR: new Image(),
        bossL: new Image()
    };

    sprites.soldierR.src = '/assets/images/game/soldat1.png';
    sprites.soldierL.src = '/assets/images/game/soldat2.png';
    sprites.enemyR.src = '/assets/images/game/vrag1.png';
    sprites.enemyL.src = '/assets/images/game/vrag2.png';
    sprites.ogonR.src = '/assets/images/game/ogon.png';
    sprites.ogonL.src = '/assets/images/game/ogon2.png';
    sprites.background.src = '/assets/images/game/foon.jpg';
    sprites.bossR.src = '/assets/images/game/boss2.png';
    sprites.bossL.src = '/assets/images/game/boss1.png';

    let spritesLoaded = false;
    let gameStarted = false;
    let loadCounter = 0;
    const totalSprites = Object.keys(sprites).length;

    function onSpriteDone() {
        loadCounter++;
        if (loadCounter >= totalSprites) startOnce();
    }

    Object.values(sprites).forEach((img) => {
        if (img.complete && img.naturalWidth > 0) {
            onSpriteDone();
        } else {
            img.onload = onSpriteDone;
            img.onerror = onSpriteDone;
        }
    });

    setTimeout(startOnce, 2500);

    const GROUND_Y = 540;
    let score = 0;
    let lives = 3;
    const maxLives = 5;
    let gameRunning = true;
    let invincibleFrames = 0;
    let pendingScore = 0;
    let heartSpawnCounter = 0;
    let boss = null;
    let bossSpawnTimer = 60;
    const bossMaxHealth = 50;
    let bossTimerId = null;
    let fireHeld = false;

    const platforms = [
        { x: 0, y: GROUND_Y, w: 1000, h: 20 },
        { x: 80, y: 510, w: 100, h: 15 },
        { x: 250, y: 480, w: 100, h: 15 },
        { x: 420, y: 450, w: 100, h: 15 },
        { x: 590, y: 420, w: 100, h: 15 },
        { x: 760, y: 390, w: 100, h: 15 },
        { x: 180, y: 360, w: 100, h: 15 },
        { x: 380, y: 330, w: 100, h: 15 },
        { x: 580, y: 300, w: 100, h: 15 },
        { x: 780, y: 270, w: 100, h: 15 },
        { x: 120, y: 240, w: 100, h: 15 },
        { x: 320, y: 210, w: 100, h: 15 },
        { x: 520, y: 180, w: 100, h: 15 },
        { x: 720, y: 150, w: 100, h: 15 },
        { x: 920, y: 120, w: 80, h: 15 },
        { x: 50, y: 90, w: 100, h: 15 },
        { x: 450, y: 60, w: 100, h: 15 }
    ];

    const player = {
        x: 100,
        y: GROUND_Y - 42,
        width: 34,
        height: 42,
        vx: 0,
        vy: 0,
        gravity: 0.65,
        jumpPower: -11,
        facingRight: true,
        onGround: true,
        shootingCooldown: 0
    };

    let bullets = [];
    let enemyBullets = [];
    let enemies = [];
    let hearts = [];

    const keys = {
        KeyA: false,
        KeyD: false,
        Space: false,
        spacePressed: false,
        ShiftLeft: false
    };

    const timerEl = document.getElementById('timerCount');
    const timerLabel = document.getElementById('timerLabel');
    const bossTimerBox = document.getElementById('bossTimer');

    function updateTimerUI() {
        if (!timerEl) return;
        if (boss) {
            timerLabel.textContent = 'Босс на карте';
            timerEl.textContent = Math.max(0, boss.health);
            timerEl.classList.remove('warning');
            bossTimerBox.classList.add('is-boss');
        } else {
            timerLabel.textContent = 'До босса';
            timerEl.textContent = String(bossSpawnTimer);
            timerEl.classList.toggle('warning', bossSpawnTimer <= 10);
            bossTimerBox.classList.remove('is-boss');
        }
    }

    function spawnHeart() {
        const platform = platforms[Math.floor(Math.random() * (platforms.length - 1)) + 1];
        hearts.push({
            x: platform.x + Math.random() * (platform.w - 20),
            y: platform.y - 25,
            width: 22,
            height: 22
        });
    }

    function spawnEnemy() {
        if (boss) return;
        const type = Math.random() > 0.5 ? 'ranged' : 'melee';
        const platform = platforms[Math.floor(Math.random() * (platforms.length - 1)) + 1];
        enemies.push({
            x: platform.x + Math.random() * (platform.w - 40),
            y: platform.y - 42,
            width: 34,
            height: 42,
            health: type === 'ranged' ? 2 : 3,
            facingRight: Math.random() > 0.5,
            type,
            shootCooldown: 0,
            attackCooldown: 0,
            moveSpeed: 1.5,
            moveDir: Math.random() > 0.5 ? 1 : -1,
            currentPlatform: platform
        });
    }

    function spawnBoss() {
        boss = {
            x: canvas.width / 2 - 60,
            y: GROUND_Y - 100,
            width: 100,
            height: 100,
            health: bossMaxHealth,
            facingRight: true,
            attackCooldown: 0,
            moveSpeed: 0.9,
            moveDir: 1
        };
        enemies = [];
        enemyBullets = [];
        updateTimerUI();
    }

    function defeatBoss() {
        boss = null;
        score += 100;
        bossSpawnTimer = 60;
        updateTimerUI();
    }

    function startOnce() {
        if (gameStarted) return;
        gameStarted = true;
        spritesLoaded = true;
        initGame();
        requestAnimationFrame(gameLoop);
    }

    function initGame() {
        score = 0;
        lives = 3;
        invincibleFrames = 0;
        bullets = [];
        enemyBullets = [];
        enemies = [];
        hearts = [];
        boss = null;
        bossSpawnTimer = 60;
        player.x = 100;
        player.y = GROUND_Y - 42;
        player.vx = 0;
        player.vy = 0;
        gameRunning = true;
        heartSpawnCounter = 0;
        fireHeld = false;

        for (let i = 0; i < 4; i++) setTimeout(() => { if (gameRunning) spawnEnemy(); }, i * 800);
        for (let i = 0; i < 2; i++) setTimeout(() => { if (gameRunning) spawnHeart(); }, i * 5000 + 3000);

        if (bossTimerId) clearInterval(bossTimerId);
        bossTimerId = setInterval(() => {
            if (!gameRunning || boss) return;
            if (bossSpawnTimer > 0) {
                bossSpawnTimer--;
                updateTimerUI();
                if (bossSpawnTimer <= 0) spawnBoss();
            }
        }, 1000);

        updateTimerUI();
    }

    function checkPlatformCollision() {
        player.onGround = false;
        for (const p of platforms) {
            if (player.x + player.width > p.x && player.x < p.x + p.w) {
                if (
                    player.vy >= 0 &&
                    player.y + player.height <= p.y + 15 &&
                    player.y + player.height + player.vy >= p.y
                ) {
                    player.y = p.y - player.height;
                    player.vy = 0;
                    player.onGround = true;
                }
            }
        }
        if (player.y + player.height >= GROUND_Y + 20) {
            player.y = GROUND_Y + 20 - player.height;
            player.vy = 0;
            player.onGround = true;
        }
        if (player.y <= 0) {
            player.y = 0;
            if (player.vy < 0) player.vy = 0;
        }
    }

    function tryShoot() {
        if (!gameRunning || player.shootingCooldown > 0) return;
        bullets.push({
            x: player.x + (player.facingRight ? player.width : -14),
            y: player.y + player.height / 2 - 4,
            w: 16,
            h: 6,
            direction: player.facingRight ? 1 : -1,
            life: 100
        });
        player.shootingCooldown = 10;
    }

    function hitPlayer() {
        if (invincibleFrames > 0) return;
        lives--;
        invincibleFrames = 45;
        if (lives <= 0) {
            gameRunning = false;
            showGameOver();
        }
    }

    function updateGame() {
        if (!gameRunning) return;

        if (invincibleFrames > 0) invincibleFrames--;
        if (player.shootingCooldown > 0) player.shootingCooldown--;

        player.vx = 0;
        if (keys.KeyA) { player.vx = -5; player.facingRight = false; }
        if (keys.KeyD) { player.vx = 5; player.facingRight = true; }
        player.x += player.vx;

        player.vy += player.gravity;
        player.y += player.vy;
        checkPlatformCollision();

        if (keys.Space && !keys.spacePressed && player.onGround) {
            player.vy = player.jumpPower;
            player.onGround = false;
            keys.spacePressed = true;
        }
        if (!keys.Space) keys.spacePressed = false;

        player.x = Math.max(20, Math.min(canvas.width - player.width - 20, player.x));

        if ((keys.ShiftLeft || fireHeld) && player.shootingCooldown === 0) {
            tryShoot();
        }

        // Player bullets
        for (let i = 0; i < bullets.length; i++) {
            const b = bullets[i];
            b.x += b.direction * 10;
            b.life--;
            if (b.x > canvas.width || b.x + b.w < 0 || b.life <= 0) {
                bullets.splice(i, 1);
                i--;
                continue;
            }

            let hit = false;
            for (let j = 0; j < enemies.length; j++) {
                const e = enemies[j];
                if (b.x < e.x + e.width && b.x + b.w > e.x && b.y < e.y + e.height && b.y + b.h > e.y) {
                    e.health--;
                    bullets.splice(i, 1);
                    i--;
                    hit = true;
                    if (e.health <= 0) {
                        enemies.splice(j, 1);
                        score += 10;
                    }
                    break;
                }
            }
            if (hit) continue;

            if (
                boss &&
                b.x < boss.x + boss.width &&
                b.x + b.w > boss.x &&
                b.y < boss.y + boss.height &&
                b.y + b.h > boss.y
            ) {
                boss.health--;
                bullets.splice(i, 1);
                i--;
                updateTimerUI();
                if (boss.health <= 0) defeatBoss();
            }
        }

        // Hearts
        for (let i = 0; i < hearts.length; i++) {
            const h = hearts[i];
            if (
                player.x < h.x + h.width &&
                player.x + player.width > h.x &&
                player.y < h.y + h.height &&
                player.y + player.height > h.y
            ) {
                if (lives < maxLives) lives++;
                hearts.splice(i, 1);
                i--;
            }
        }

        // Enemies
        for (let i = 0; i < enemies.length; i++) {
            const e = enemies[i];
            let newX = e.x + e.moveDir * e.moveSpeed;
            if (e.currentPlatform) {
                if (newX + e.width > e.currentPlatform.x + e.currentPlatform.w) {
                    e.moveDir = -1;
                    e.facingRight = false;
                } else if (newX < e.currentPlatform.x) {
                    e.moveDir = 1;
                    e.facingRight = true;
                } else {
                    e.x = newX;
                }
            }

            if (
                e.type === 'ranged' &&
                e.shootCooldown <= 0 &&
                Math.abs(e.x - player.x) < 400 &&
                Math.abs(e.y - player.y) < 100
            ) {
                enemyBullets.push({
                    x: e.x + (e.facingRight ? e.width : -12),
                    y: e.y + 18,
                    w: 10,
                    h: 5,
                    direction: e.facingRight ? 1 : -1,
                    life: 60
                });
                e.shootCooldown = 45;
            }
            if (e.shootCooldown > 0) e.shootCooldown--;

            if (
                e.type === 'melee' &&
                e.attackCooldown <= 0 &&
                Math.abs(e.x - player.x) < 45 &&
                Math.abs(e.y - player.y) < 55
            ) {
                hitPlayer();
                e.attackCooldown = 45;
                if (!gameRunning) return;
            }
            if (e.attackCooldown > 0) e.attackCooldown--;
        }

        // Enemy bullets
        for (let i = 0; i < enemyBullets.length; i++) {
            const eb = enemyBullets[i];
            eb.x += eb.direction * 7;
            eb.life--;
            if (eb.x > canvas.width || eb.x + eb.w < 0 || eb.life <= 0) {
                enemyBullets.splice(i, 1);
                i--;
                continue;
            }
            if (
                eb.x < player.x + player.width &&
                eb.x + eb.w > player.x &&
                eb.y < player.y + player.height &&
                eb.y + eb.h > player.y
            ) {
                hitPlayer();
                enemyBullets.splice(i, 1);
                i--;
                if (!gameRunning) return;
            }
        }

        // Boss
        if (boss) {
            let newX = boss.x + boss.moveDir * boss.moveSpeed;
            if (newX + boss.width > canvas.width - 50) {
                boss.moveDir = -1;
                boss.facingRight = false;
            } else if (newX < 50) {
                boss.moveDir = 1;
                boss.facingRight = true;
            } else {
                boss.x = newX;
            }

            if (
                boss.attackCooldown <= 0 &&
                Math.abs(boss.x - player.x) < 80 &&
                Math.abs(boss.y + boss.height / 2 - (player.y + player.height / 2)) < 70
            ) {
                hitPlayer();
                boss.attackCooldown = 60;
                if (!gameRunning) return;
            }
            if (boss.attackCooldown > 0) boss.attackCooldown--;
        }

        if (!boss && enemies.length < 5 && Math.random() < 0.012) {
            spawnEnemy();
        }

        heartSpawnCounter++;
        if (heartSpawnCounter > 500 && hearts.length < 3 && lives < maxLives) {
            spawnHeart();
            heartSpawnCounter = 0;
        }
    }

    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        if (sprites.background.complete && sprites.background.naturalWidth > 0) {
            ctx.drawImage(sprites.background, 0, 0, canvas.width, canvas.height);
        } else {
            ctx.fillStyle = '#0a0a1a';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
        }

        for (const p of platforms) {
            ctx.fillStyle = '#4a4a52';
            ctx.fillRect(p.x, p.y, p.w, p.h);
            ctx.fillStyle = '#6e6e73';
            ctx.fillRect(p.x, p.y - 3, p.w, 3);
        }

        for (const h of hearts) {
            ctx.fillStyle = '#ff453a';
            ctx.fillRect(h.x, h.y, h.width, h.height);
            ctx.fillStyle = '#ff8a80';
            ctx.fillRect(h.x + 5, h.y + 5, 5, 5);
            ctx.fillRect(h.x + 12, h.y + 5, 5, 5);
        }

        const playerImg = player.facingRight ? sprites.soldierR : sprites.soldierL;
        if (invincibleFrames > 0 && Math.floor(Date.now() / 50) % 2 === 0) ctx.globalAlpha = 0.45;
        if (playerImg.complete && playerImg.naturalWidth > 0) {
            ctx.drawImage(playerImg, player.x, player.y, player.width, player.height);
        } else {
            ctx.fillStyle = '#2997ff';
            ctx.fillRect(player.x, player.y, player.width, player.height);
        }
        ctx.globalAlpha = 1;

        for (const e of enemies) {
            const enemyImg = e.type === 'ranged'
                ? (e.facingRight ? sprites.enemyR : sprites.enemyL)
                : (e.facingRight ? sprites.ogonR : sprites.ogonL);
            if (enemyImg.complete && enemyImg.naturalWidth > 0) {
                ctx.drawImage(enemyImg, e.x, e.y, e.width, e.height);
            } else {
                ctx.fillStyle = '#ff9f0a';
                ctx.fillRect(e.x, e.y, e.width, e.height);
            }
        }

        if (boss) {
            const bossImg = boss.facingRight ? sprites.bossR : sprites.bossL;
            if (bossImg.complete && bossImg.naturalWidth > 0) {
                ctx.drawImage(bossImg, boss.x, boss.y, boss.width, boss.height);
            } else {
                ctx.fillStyle = '#ff453a';
                ctx.fillRect(boss.x, boss.y, boss.width, boss.height);
            }
            ctx.fillStyle = 'rgba(0,0,0,0.65)';
            ctx.fillRect(canvas.width / 2 - 150, 20, 300, 22);
            ctx.fillStyle = '#ff453a';
            ctx.fillRect(canvas.width / 2 - 150, 20, 300 * (boss.health / bossMaxHealth), 22);
            ctx.fillStyle = '#fff';
            ctx.font = '600 13px Outfit, sans-serif';
            ctx.fillText('БОСС  ' + boss.health + '/' + bossMaxHealth, canvas.width / 2 - 48, 36);
        }

        for (const b of bullets) {
            ctx.fillStyle = '#ffd60a';
            ctx.fillRect(b.x, b.y, b.w, b.h);
        }
        for (const eb of enemyBullets) {
            ctx.fillStyle = '#ff9f0a';
            ctx.fillRect(eb.x, eb.y, eb.w, eb.h);
        }

        for (let i = 0; i < lives; i++) {
            ctx.fillStyle = '#ff453a';
            ctx.fillRect(15 + i * 36, 15, 28, 28);
            ctx.fillStyle = '#ff8a80';
            ctx.fillRect(21 + i * 36, 21, 5, 5);
            ctx.fillRect(32 + i * 36, 21, 5, 5);
        }

        ctx.fillStyle = '#fff';
        ctx.font = '700 22px Outfit, sans-serif';
        ctx.fillText('SCORE  ' + score, canvas.width - 160, 38);

        if (invincibleFrames > 0) {
            ctx.fillStyle = '#ffd60a';
            ctx.font = '600 12px Outfit, sans-serif';
            ctx.fillText('SHIELD', player.x - 4, player.y - 12);
        }
    }

    function showGameOver() {
        pendingScore = score;
        if (score > 0) {
            document.getElementById('namePopup').style.display = 'flex';
            const input = document.getElementById('playerName');
            setTimeout(() => input && input.focus(), 100);
        } else {
            location.reload();
        }
    }

    window.saveScore = function () {
        const name = (document.getElementById('playerName').value.trim() || 'Anonymous').slice(0, 30);
        fetch('/includes/game-stats.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ score: pendingScore, player_name: name })
        }).finally(() => location.reload());
    };

    window.skipScore = function () {
        location.reload();
    };

    function gameLoop() {
        if (!spritesLoaded) return;
        updateGame();
        draw();
        requestAnimationFrame(gameLoop);
    }

    window.addEventListener('keydown', (e) => {
        if (['Space', 'KeyA', 'KeyD', 'ShiftLeft', 'ArrowLeft', 'ArrowRight', 'ArrowUp'].includes(e.code)) {
            e.preventDefault();
        }
        if (e.code === 'Space' || e.code === 'ArrowUp') keys.Space = true;
        if (e.code === 'KeyA' || e.code === 'ArrowLeft') keys.KeyA = true;
        if (e.code === 'KeyD' || e.code === 'ArrowRight') keys.KeyD = true;
        if (e.code === 'ShiftLeft' || e.code === 'ShiftRight') keys.ShiftLeft = true;
    });

    window.addEventListener('keyup', (e) => {
        if (e.code === 'Space' || e.code === 'ArrowUp') keys.Space = false;
        if (e.code === 'KeyA' || e.code === 'ArrowLeft') keys.KeyA = false;
        if (e.code === 'KeyD' || e.code === 'ArrowRight') keys.KeyD = false;
        if (e.code === 'ShiftLeft' || e.code === 'ShiftRight') keys.ShiftLeft = false;
    });

    canvas.addEventListener('pointerdown', () => {
        if (gameRunning) fireHeld = true;
    });
    window.addEventListener('pointerup', () => { fireHeld = false; });
    window.addEventListener('pointercancel', () => { fireHeld = false; });

    document.querySelectorAll('.ctrl-btn').forEach((btn) => {
        const action = btn.dataset.action;
        const start = (e) => {
            e.preventDefault();
            btn.classList.add('is-active');
            if (action === 'left') keys.KeyA = true;
            if (action === 'right') keys.KeyD = true;
            if (action === 'jump') keys.Space = true;
            if (action === 'fire') fireHeld = true;
        };
        const end = (e) => {
            e.preventDefault();
            btn.classList.remove('is-active');
            if (action === 'left') keys.KeyA = false;
            if (action === 'right') keys.KeyD = false;
            if (action === 'jump') keys.Space = false;
            if (action === 'fire') fireHeld = false;
        };
        btn.addEventListener('touchstart', start, { passive: false });
        btn.addEventListener('touchend', end, { passive: false });
        btn.addEventListener('touchcancel', end, { passive: false });
        btn.addEventListener('mousedown', start);
        btn.addEventListener('mouseup', end);
        btn.addEventListener('mouseleave', end);
    });
})();
</script>
</body>
</html>
