<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes, viewport-fit=cover">
    <title>Апгрейд — CS2 Simulator</title>
    <link rel="stylesheet" href="/static/css/style.css">
</head>
<body class="upgrade-page">
    {% include "_nav.html" %}

    <main class="upgrade-container">
        <div class="container">
            <div class="upgrade-header">
                <h1>🆙 Апгрейд</h1>
                <p>Рискни предметом ради более дорогого</p>
            </div>

            <div class="upgrade-layout">
                <!-- Inventory -->
                <div class="inventory-panel">
                    <div class="panel-header">
                        <div class="panel-title">
                            <span>📦 Инвентарь</span>
                            <span style="font-size: 0.65rem; color: #6b6b7a;">{{ inventory_items|length }}</span>
                        </div>
                        <div class="inv-filter-bar">
                            <input type="text" class="inv-search-input" id="invSearch" placeholder="Поиск..." oninput="onInvSearch()">
                            <div class="inv-sort-group">
                                <button class="inv-sort-btn" onclick="setInvSort('default', this)">📋</button>
                                <button class="inv-sort-btn" onclick="setInvSort('price_asc', this)">💰↑</button>
                                <button class="inv-sort-btn" onclick="setInvSort('price_desc', this)">💰↓</button>
                            </div>
                        </div>
                    </div>
                    <div class="inventory-list" id="inventoryList"></div>
                </div>

                <!-- Wheel -->
                <div class="wheel-panel" style="position: relative;">
                    <div class="selected-items-display">
                        <div class="selected-item-mini" id="selectedInputDisplay">
                            <div class="item-frame">
                                <img src="/static/placeholder.png" id="displayInputImage">
                            </div>
                            <div class="selected-item-mini-name" id="displayInputName">Не выбрано</div>
                            <div class="selected-item-mini-price" id="displayInputPrice">—</div>
                        </div>
                        <div class="arrow-icon">➡</div>
                        <div class="selected-item-mini" id="selectedTargetDisplay">
                            <div class="item-frame">
                                <img src="/static/placeholder.png" id="displayTargetImage">
                            </div>
                            <div class="selected-item-mini-name" id="displayTargetName">Не выбрано</div>
                            <div class="selected-item-mini-price" id="displayTargetPrice">—</div>
                        </div>
                    </div>

                    <div class="wheel-container">
                        <div class="wheel-outer-ring"></div>
                        <div class="wheel" id="upgradeWheel" style="--probability: 0;"></div>
                        <div class="wheel-ticks"></div>
                        <div class="wheel-pointer-container" id="pointerContainer">
                            <div class="wheel-pointer"></div>
                        </div>
                        <div class="wheel-center" id="wheelProbability">0%</div>
                    </div>

                    <div class="upgrade-actions">
                        {% if user %}
                        <button class="upgrade-btn" onclick="executeUpgrade()" id="upgradeBtn" disabled>
                            🎲 Апгрейд
                        </button>
                        <button class="quick-btn" id="quickModeBtn" onclick="toggleQuickMode()" title="Быстрый режим">⚡</button>
                        {% else %}
                        <div style="display:flex;align-items:center;gap:1rem;width:100%;justify-content:center;padding:1rem;">
                            <span style="color:var(--text-secondary);">🔒 Войдите, чтобы совершать апгрейды</span>
                            <a href="/login" class="btn btn-primary">Войти</a>
                            <a href="/register" class="btn btn-outline">Регистрация</a>
                        </div>
                        {% endif %}
                    </div>

                </div>

                <!-- Target -->
                <div class="target-panel">
                    <div class="target-header">
                        <div class="panel-title" style="margin-bottom: 0.4rem;">
                            <span>🎯 Цель</span>
                        </div>
                        <input type="text" class="target-search-input" id="targetSearch" placeholder="Поиск..." oninput="searchTargetItems()">
                        <div class="sort-controls">
                            <button class="sort-btn" onclick="setTargetSort('closest', this)">🎯 Ближайшие</button>
                            <button class="sort-btn" onclick="setTargetSort('price_desc', this)">💎 Дорогие</button>
                            <button class="sort-btn" onclick="setTargetSort('price_asc', this)">💰 Дешёвые</button>
                            <button class="sort-btn" onclick="setTargetSort('name', this)">📋 Имя</button>
                        </div>
                        <div class="price-filter-bar" id="priceFilterBar" style="display: none;">
                            <span style="font-size:0.55rem;color:#4a4a5a;text-transform:uppercase;letter-spacing:0.04em;padding:0.2rem 0;margin-right:0.15rem;">Шанс</span>
                            <button class="pf-btn" onclick="setPriceFilter('probhigh', this)">75%</button>
                            <button class="pf-btn" onclick="setPriceFilter('probmid', this)">50%</button>
                            <button class="pf-btn" onclick="setPriceFilter('probalow', this)">25%</button>
                            <button class="pf-btn" onclick="setPriceFilter('proba10', this)">10%</button>
                            <span style="font-size:0.55rem;color:#4a4a5a;text-transform:uppercase;letter-spacing:0.04em;padding:0.2rem 0;margin:0 0.15rem;">×</span>
                            <button class="pf-btn" onclick="setPriceFilter('2', this)">2×</button>
                            <button class="pf-btn" onclick="setPriceFilter('4', this)">4×</button>
                            <button class="pf-btn" onclick="setPriceFilter('8', this)">8×</button>
                            <button class="pf-btn" onclick="setPriceFilter('10', this)">10×</button>
                        </div>
                    </div>
                    <div class="target-list" id="targetList">
                        <div class="empty-state">Выберите предмет</div>
                    </div>
                </div>
            </div>

            <!-- History -->
            <div class="history-section">
                <h3 class="history-title">📜 История <span class="history-count" id="historyCount">{{ recent_upgrades|length }}</span></h3>
                <div class="history-grid" id="historyGrid"></div>
            </div>
        </div>
    </main>

    <script>
        // === Фразы для побед/поражений ===
        const PHRASE_PARTS = {
            win: {
                pre: ['🎉','🔥','⭐','🏆','💎','✨','🎯','👑','💫','🌟','🎰','💪','🥇','🎊','🏅'],
                verb: ['Победа','Джекпот','Успех','Красава','В дамках','Есть контакт','Повезло','Забрал','Выбил','Сорвал куш','Всё пучком','Лут','Топчик','Козырь','Фартануло'],
                noun: ['! 🔥','! 💎','! 🏆','! 👑','! ✨','! 💪','!','!','!'],
            },
            lose: {
                pre: ['😔','💔','😢','💀','😭','😤','😩','💸','😞','😓','🤡','💀','😅','🙃','🤷'],
                verb: ['Не повезло','Облом','Мимо','Пролёт','Не выпал','Не срослось','Пусто','Мимо кассы','В следующий раз','Не фортануло','Повезёт потом','Ноль','Минус','Увы','Печаль'],
                noun: [' 😔',' 💔','...',' 😢',' 😭',' 💸','...'],
            }
        };
        let usedPhraseKeys = new Set();
        function getRandomPhrase(type) {
            const parts = PHRASE_PARTS[type];
            for (let attempt = 0; attempt < 100; attempt++) {
                const pre = parts.pre[Math.floor(Math.random() * parts.pre.length)];
                const verb = parts.verb[Math.floor(Math.random() * parts.verb.length)];
                const noun = parts.noun[Math.floor(Math.random() * parts.noun.length)];
                const key = pre + '|' + verb + '|' + noun;
                if (!usedPhraseKeys.has(key)) {
                    usedPhraseKeys.add(key);
                    return pre + ' ' + verb + noun;
                }
            }
            usedPhraseKeys.clear();
            return getRandomPhrase(type);
        }

        let selectedInput = null;
        let selectedTarget = null;
        let inventoryItems = {{ inventory_items|tojson }};
        let allTargetItems = [];
        let currentSearchQuery = '';
        let currentSort = 'closest';
        let currentPriceFilter = null;
        let isSpinning = false;
        let quickMode = false;
        let invSearchQuery = '';
        let invSort = 'default';

        document.addEventListener('DOMContentLoaded', () => {
            loadInitialTargets();
            renderHistory({{ recent_upgrades|tojson }});
            renderInventory();
        });

        function renderInventory() {
            let items = [...inventoryItems];

            if (invSearchQuery.length >= 1) {
                const q = invSearchQuery.toLowerCase();
                items = items.filter(i => i.name.toLowerCase().includes(q));
            }

            if (invSort === 'price_asc') {
                items.sort((a, b) => a.price_rub - b.price_rub);
            } else if (invSort === 'price_desc') {
                items.sort((a, b) => b.price_rub - a.price_rub);
            }

            const container = document.getElementById('inventoryList');
            if (items.length === 0) {
                container.innerHTML = '<div class="empty-state" style="padding:1rem;text-align:center;color:var(--text-secondary)">Ничего не найдено</div>';
                return;
            }
            container.innerHTML = items.map(item => `
                <div class="inventory-item-card ${selectedInput && selectedInput.inventory_id === item.id ? 'selected' : ''}"
                     onclick="selectInputItem(${item.id})" data-id="${item.id}" data-price="${item.price_rub}">
                    <img src="${item.image_url || '/static/placeholder.png'}" onerror="this.src='/static/placeholder.png'">
                    <div class="inventory-item-info">
                        <div class="inventory-item-name" title="${item.name}">${item.name}</div>
                        <div class="inventory-item-meta">
                            <span>${item.rarity}</span>
                            <span class="inventory-item-price">${Math.floor(item.price_rub).toLocaleString()} ₽</span>
                        </div>
                    </div>
                </div>
            `).join('');
        }

        async function loadInitialTargets() {
            try {
                const response = await fetch(`/admin/api/items/search?q=&limit=600`);
                allTargetItems = await response.json();
                allTargetItems = allTargetItems.filter((item, index, self) =>
                    index === self.findIndex(t => t.id === item.id)
                );
                currentSort = 'closest';
                document.querySelectorAll('.sort-btn').forEach(b => b.classList.remove('active'));
                document.querySelector('.sort-btn[onclick*="closest"]')?.classList.add('active');
                applySortAndFilter();
            } catch (e) {}
        }

        async function loadTargetsForInput(inputPrice) {
            try {
                // Поиск только по цене — больше выбора и приколюх
                const minP = Math.round(inputPrice * 1.05);
                const maxP = Math.round(inputPrice * 19);
                const resp = await fetch(`/admin/api/items/search?q=&min_price=${minP}&max_price=${maxP}&limit=600`);
                const items = await resp.json();
                allTargetItems = items.filter((item, index, self) =>
                    index === self.findIndex(t => t.id === item.id)
                );
                currentSort = 'closest';
                document.querySelectorAll('.sort-btn').forEach(b => b.classList.remove('active'));
                document.querySelector('.sort-btn[onclick*="closest"]')?.classList.add('active');
                applySortAndFilter();
            } catch (e) {
                console.error('Failed to load targets:', e);
                applySortAndFilter();
            }
        }

        function selectInputItem(itemId) {
            if (isSpinning) return;
            const item = inventoryItems.find(i => i.id === itemId);
            if (!item) return;

            selectedInput = {
                inventory_id: item.id,
                item_id: item.item_id,
                name: item.name,
                price: item.price_rub,
                image_url: item.image_url,
                rarity: item.rarity
            };

            renderInventory();
            document.getElementById('displayInputImage').src = item.image_url || '/static/placeholder.png';
            document.getElementById('displayInputName').textContent = item.name.substring(0, 25);
            document.getElementById('displayInputPrice').textContent = `${Math.floor(item.price_rub).toLocaleString()} ₽`;
            document.getElementById('selectedInputDisplay').classList.add('selected');

            document.getElementById('priceFilterBar').style.display = 'flex';
            currentPriceFilter = null;
            document.querySelectorAll('.pf-btn').forEach(b => b.classList.remove('active'));
            currentSort = 'closest';
            document.querySelectorAll('.sort-btn').forEach(b => b.classList.remove('active'));
            document.querySelector('.sort-btn[onclick*="closest"]')?.classList.add('active');

            loadTargetsForInput(item.price_rub);
            updateProbability();
        }

        function applySortAndFilter() {
            if (!allTargetItems.length) return;

            let filtered = [...allTargetItems];

            if (currentSearchQuery.length >= 2) {
                filtered = filtered.filter(item =>
                    item.name.toLowerCase().includes(currentSearchQuery.toLowerCase())
                );
            }

            if (selectedInput) {
                const inputPrice = selectedInput.price;
                filtered = filtered.filter(item => {
                    const price = item.price_rub || 100;
                    if (price <= inputPrice) return false;
                    const maxPrice = inputPrice * 19;
                    return price <= maxPrice;
                });

                if (currentPriceFilter) {
                    filtered = filtered.filter(item => {
                        const price = item.price_rub || 100;
                        const ratio = price / inputPrice;
                        const prob = (inputPrice / price) * 100;
                        switch (currentPriceFilter) {
                            case '2':    return ratio >= 1.8 && ratio <= 2.5;
                            case '4':    return ratio >= 3.5 && ratio <= 5;
                            case '8':    return ratio >= 7 && ratio <= 10;
                            case '10':   return ratio >= 8.5 && ratio <= 12;
                            case 'probalow':  return prob >= 20 && prob <= 30;
                            case 'probmid':   return prob >= 45 && prob <= 55;
                            case 'probhigh':  return prob >= 70 && prob <= 75;
                            case 'proba10':   return prob >= 8 && prob <= 12;
                            default: return true;
                        }
                    });
                }
            }

            if (currentSort === 'closest' && selectedInput) {
                const inputPrice = selectedInput.price;
                filtered.sort((a, b) => {
                    const pa = (inputPrice / (a.price_rub || 100)) * 100;
                    const pb = (inputPrice / (b.price_rub || 100)) * 100;
                    const da = Math.abs(Math.min(75, pa) - 75);
                    const db = Math.abs(Math.min(75, pb) - 75);
                    if (da !== db) return da - db;
                    return (a.price_rub || 0) - (b.price_rub || 0);
                });
            } else if (currentSort === 'price_asc') {
                filtered.sort((a, b) => (a.price_rub || 0) - (b.price_rub || 0));
            } else if (currentSort === 'price_desc') {
                filtered.sort((a, b) => (b.price_rub || 0) - (a.price_rub || 0));
            } else {
                filtered.sort((a, b) => a.name.localeCompare(b.name));
            }

            displayTargetItems(filtered.slice(0, 120));
        }

        function setTargetSort(sort, btn) {
            currentSort = sort;
            document.querySelectorAll('.sort-btn').forEach(b => b.classList.remove('active'));
            if (btn) btn.classList.add('active');
            applySortAndFilter();
        }

        function setPriceFilter(mult, btn) {
            currentPriceFilter = mult === currentPriceFilter ? null : mult;
            document.querySelectorAll('.pf-btn').forEach(b => b.classList.remove('active'));
            if (currentPriceFilter && btn) btn.classList.add('active');
            applySortAndFilter();
        }

        function onInvSearch() {
            invSearchQuery = document.getElementById('invSearch').value;
            renderInventory();
        }

        function setInvSort(sort, btn) {
            invSort = sort;
            document.querySelectorAll('.inv-sort-btn').forEach(b => b.classList.remove('active'));
            if (btn) btn.classList.add('active');
            renderInventory();
        }

        function toggleQuickMode() {
            quickMode = !quickMode;
            document.getElementById('quickModeBtn').classList.toggle('active', quickMode);
        }

        async function searchTargetItems() {
            const query = document.getElementById('targetSearch').value;
            currentSearchQuery = query;
            const container = document.getElementById('targetList');

            if (query.length < 2) {
                applySortAndFilter();
                return;
            }

            container.innerHTML = '<div class="empty-state">🔍 Поиск…</div>';

            try {
                const response = await fetch(`/admin/api/items/search?q=${encodeURIComponent(query)}&limit=600`);
                const items = await response.json();
                allTargetItems = items.filter((item, index, self) =>
                    index === self.findIndex(t => t.id === item.id)
                );
                applySortAndFilter();
            } catch (e) {
                container.innerHTML = '<div class="empty-state">Ошибка</div>';
            }
        }

        function displayTargetItems(items) {
            const container = document.getElementById('targetList');

            if (items.length === 0) {
                container.innerHTML = '<div class="empty-state">Ничего не найдено</div>';
                return;
            }

            container.innerHTML = items.map(item => {
                const price = item.price_rub || 100;
                const imageUrl = item.image_url || '/static/placeholder.png';

                let isDisabled = false;
                let disabledReason = '';
                if (selectedInput) {
                    const minPrice = selectedInput.price * 0.5;
                    const maxPrice = selectedInput.price * 19;
                    if (price < minPrice) {
                        isDisabled = true;
                        disabledReason = 'Слишком дешёвый';
                    } else if (price > maxPrice) {
                        isDisabled = true;
                        disabledReason = 'Слишком дорогой';
                    }
                }

                const safeName = item.name.replace(/'/g, "\\'");
                const safeUrl = imageUrl.replace(/'/g, "\\'");

                return `
                    <div class="target-item-card ${isDisabled ? 'disabled' : ''}"
                         onclick="selectTargetItem(${item.id}, '${safeName}', ${price}, '${safeUrl}', '${item.rarity || 'Unknown'}')"
                         data-price="${price}"
                         title="${isDisabled ? disabledReason : ''}">
                        <img src="${imageUrl}" onerror="this.src='/static/placeholder.png'">
                        <div class="target-item-info">
                            <div class="target-item-name" title="${item.name}">${item.name}</div>
                            <div class="target-item-meta">
                                <span>${item.rarity || ''}</span>
                                <span class="target-item-price">${price.toLocaleString()} ₽</span>
                            </div>
                        </div>
                    </div>
                `;
            }).join('');

            if (selectedTarget) {
                document.querySelectorAll('.target-item-card').forEach(card => {
                    if (card.onclick && card.onclick.toString().includes(`selectTargetItem(${selectedTarget.item_id}`)) {
                        card.classList.add('selected');
                    }
                });
            }
        }

        function selectTargetItem(id, name, price, imageUrl, rarity) {
            if (isSpinning) return;
            const card = event.target.closest('.target-item-card');
            if (card.classList.contains('disabled')) {
                Notify.error('Этот предмет не подходит!');
                return;
            }

            document.querySelectorAll('.target-item-card').forEach(c => c.classList.remove('selected'));
            card.classList.add('selected');

            selectedTarget = {
                item_id: id,
                name: name,
                price: price,
                image_url: imageUrl,
                rarity: rarity
            };

            document.getElementById('displayTargetImage').src = imageUrl || '/static/placeholder.png';
            document.getElementById('displayTargetName').textContent = name.substring(0, 25);
            document.getElementById('displayTargetPrice').textContent = `${price.toLocaleString()} ₽`;
            document.getElementById('selectedTargetDisplay').classList.add('selected');

            updateProbability();
        }

        async function updateProbability() {
            if (!selectedInput || !selectedTarget) return;

            const formData = new FormData();
            formData.append('input_inventory_id', selectedInput.inventory_id);
            formData.append('target_item_id', selectedTarget.item_id);

            try {
                const response = await fetch('/web/api/upgrade/calculate', {
                    method: 'POST',
                    body: formData
                });

                const data = await response.json();

                if (data.success) {
                    const prob = data.adjusted_probability.toFixed(1);
                    document.getElementById('wheelProbability').textContent = `${prob}%`;

                    const wheel = document.getElementById('upgradeWheel');
                    wheel.style.setProperty('--probability', prob);

                    document.getElementById('upgradeBtn').disabled = false;
                }
            } catch (e) {}
        }

        function sparkles(container) {
            for (let i = 0; i < 24; i++) {
                const s = document.createElement('div');
                s.className = 'sparkle';
                s.style.left = Math.random() * 100 + '%';
                s.style.top = Math.random() * 100 + '%';
                s.style.setProperty('--dx', (Math.random() - 0.5) * 140 + 'px');
                s.style.setProperty('--dy', -(Math.random() * 120 + 50) + 'px');
                s.style.animationDelay = Math.random() * 0.6 + 's';
                s.style.width = (2 + Math.random() * 5) + 'px';
                s.style.height = s.style.width;
                s.style.background = ['#f59e0b', '#10b981', '#ffd700', '#fff', '#ff6b6b'][Math.floor(Math.random() * 5)];
                container.appendChild(s);
            }
        }

        async function refreshBalance() {
            try {
                const r = await fetch('/web/api/user/balance');
                const d = await r.json();
                if (d.success) {
                    document.querySelectorAll('.user-balance').forEach(el => {
                        el.textContent = `${Math.floor(d.balance).toLocaleString()} ₽`;
                    });
                }
            } catch (e) {}
        }

        async function refreshHistory() {
            try {
                const r = await fetch('/web/api/upgrade/history');
                const d = await r.json();
                if (d.success) renderHistory(d.history);
            } catch (e) {}
        }

        function renderHistory(items) {
            const grid = document.getElementById('historyGrid');
            const count = document.getElementById('historyCount');
            if (count) count.textContent = items.length;

            if (!items.length) {
                grid.innerHTML = '<div class="empty-state" style="grid-column:1/-1;text-align:center;padding:1rem;color:var(--text-secondary)">История пуста</div>';
                return;
            }

            grid.innerHTML = items.map(u => `
                <div class="history-card ${u.success ? 'success' : 'fail'}">
                    ${u.success
                        ? `<img src="${u.input_image_url || '/static/placeholder.png'}" onerror="this.src='/static/placeholder.png'" loading="lazy">
                           <div class="history-info">
                               <div class="history-names">${(u.input_item_name || '').substring(0, 12)}… → ${(u.target_item_name || '').substring(0, 12)}…</div>
                               <div class="history-meta">
                                   <span>${u.probability}%</span>
                                   <span class="history-result success">✅</span>
                               </div>
                           </div>
                           <img src="${u.target_image_url || '/static/placeholder.png'}" onerror="this.src='/static/placeholder.png'" loading="lazy" style="width:32px;height:28px;">`
                        : `<img src="${u.target_image_url || '/static/placeholder.png'}" onerror="this.src='/static/placeholder.png'" loading="lazy" style="opacity:0.5;">
                           <div class="history-info">
                               <div class="history-names">${(u.input_item_name || '').substring(0, 12)}… → ${(u.target_item_name || '').substring(0, 12)}…</div>
                               <div class="history-meta">
                                   <span>${u.probability}%</span>
                                   <span class="history-result fail">❌</span>
                               </div>
                           </div>`
                    }
                </div>
            `).join('');
        }

        async function executeUpgrade() {
            if (!selectedInput || !selectedTarget || isSpinning) return;

            // Lock the chosen items at spin start
            const lockedInputId = selectedInput.inventory_id;
            const lockedTargetId = selectedTarget.item_id;
            const lockedPrice = selectedInput.price;

            const formData = new FormData();
            formData.append('input_inventory_id', lockedInputId);
            formData.append('target_item_id', lockedTargetId);
            formData.append('quick_mode', quickMode ? 'true' : 'false');

            const btn = document.getElementById('upgradeBtn');

            isSpinning = true;
            btn.disabled = true;
            btn.textContent = '🎰 Крутим…';

            const pointer = document.getElementById('pointerContainer');
            pointer.style.transition = 'none';
            pointer.style.transform = 'rotate(0deg)';
            void pointer.offsetHeight;

            try {
                const response = await fetch('/web/api/upgrade/execute', {
                    method: 'POST',
                    body: formData
                });

                const data = await response.json();

                if (data.success) {
                    if (typeof handleAchievements === 'function') handleAchievements(data);
                    const spinDuration = quickMode ? 4 : 12;
                    pointer.style.transition = `transform ${spinDuration}s cubic-bezier(0.4, 0.0, 0.15, 1.0)`;
                    pointer.style.transform = `rotate(${data.final_angle}deg)`;

                    // Тики колеса: быстрая фаза каждые 15°, медленная (последние 90°) — 30°
                    let tickLastDeg = 0, tickCumulative = 0, tickNextThreshold = 15;
                    let tickLastTickCumulative = 0;
                    let tickControlPlayed = false;
                    const tickSlowStart = data.final_angle - 90;
                    const tickStartTime = performance.now();
                    const tickMaxDuration = spinDuration * 1000 + 500;
                    let tickRAF = null;
                    function tickLoop() {
                        const elapsed = performance.now() - tickStartTime;
                        if (elapsed > tickMaxDuration) return;
                        const style = window.getComputedStyle(pointer);
                        let deg = 0;
                        const tf = style.transform;
                        if (tf && tf !== 'none') {
                            const m = tf.match(/matrix\(([^)]+)\)/);
                            if (m) {
                                const v = m[1].split(', ').map(Number);
                                deg = Math.atan2(v[1], v[0]) * (180 / Math.PI);
                            } else {
                                const m2 = tf.match(/rotate\(([-\d.]+)deg\)/);
                                if (m2) deg = parseFloat(m2[1]);
                            }
                        }
                        let delta = deg - tickLastDeg;
                        if (delta > 180) delta -= 360;
                        if (delta < -180) delta += 360;
                        tickCumulative += delta;
                        tickLastDeg = deg;
                        if (tickCumulative >= tickNextThreshold) {
                            SoundManager.wheelSpin();
                            tickLastTickCumulative = tickCumulative;
                            tickNextThreshold += tickCumulative < tickSlowStart ? 15 : 30;
                        }
                        // Контрольный тик: если до финала <10°, а последний тик был >15° назад
                        const remaining = data.final_angle - tickCumulative;
                        const gap = tickCumulative - tickLastTickCumulative;
                        if (remaining < 10 && remaining > 0 && gap > 15 && !tickControlPlayed) {
                            SoundManager.wheelSpin();
                            tickControlPlayed = true;
                        }
                        tickRAF = requestAnimationFrame(tickLoop);
                    }
                    tickRAF = requestAnimationFrame(tickLoop);

                    let resultShown = false;
                    const onTransitionEnd = () => {
                        pointer.removeEventListener('transitionend', onTransitionEnd);
                        if (tickRAF) cancelAnimationFrame(tickRAF);
                        showResult();
                    };
                    pointer.addEventListener('transitionend', onTransitionEnd);

                    const showResult = () => {
                        if (resultShown) return;
                        resultShown = true;
                        if (data.upgrade_success && data.received_item) {
                            document.getElementById('displayTargetImage').src = data.received_item.image_url || '/static/placeholder.png';
                            document.getElementById('displayTargetName').textContent = data.received_item.name.substring(0, 25);
                            document.getElementById('displayTargetPrice').textContent = `${Math.floor(data.received_item.price).toLocaleString()} ₽`;
                            document.getElementById('selectedTargetDisplay').style.borderColor = '#10b981';
                            document.getElementById('selectedTargetDisplay').style.boxShadow = '0 0 20px rgba(16,185,129,0.3)';
                            Notify.success(`${getRandomPhrase('win')} ${data.received_item.name}`);
                            SoundManager.wheelWin();
                        } else {
                            document.getElementById('selectedInputDisplay').style.borderColor = '#ef4444';
                            document.getElementById('selectedInputDisplay').style.boxShadow = '0 0 20px rgba(239,68,68,0.3)';
                            Notify.error(getRandomPhrase('lose'));
                            SoundManager.wheelLose();
                        }

                        refreshBalance();

                        setTimeout(() => {
                            document.getElementById('selectedInputDisplay').style.borderColor = '';
                            document.getElementById('selectedInputDisplay').style.boxShadow = '';
                            document.getElementById('selectedTargetDisplay').style.borderColor = '';
                            document.getElementById('selectedTargetDisplay').style.boxShadow = '';

                            inventoryItems = inventoryItems.filter(i => i.id !== lockedInputId);
                            selectedInput = null;
                            selectedTarget = null;
                            document.getElementById('selectedInputDisplay').classList.remove('selected');
                            document.getElementById('selectedTargetDisplay').classList.remove('selected');
                            document.getElementById('displayInputImage').src = '/static/placeholder.png';
                            document.getElementById('displayInputName').textContent = 'Не выбрано';
                            document.getElementById('displayInputPrice').textContent = '—';
                            document.getElementById('displayTargetImage').src = '/static/placeholder.png';
                            document.getElementById('displayTargetName').textContent = 'Не выбрано';
                            document.getElementById('displayTargetPrice').textContent = '—';
                            document.getElementById('wheelProbability').textContent = '0%';
                            document.getElementById('upgradeWheel').style.setProperty('--probability', '0');
                            btn.disabled = true;
                            btn.textContent = '🎲 Апгрейд';
                            isSpinning = false;
                            refreshInventoryAjax();
                            refreshHistory();
                            pointer.style.transition = 'none';
                            pointer.style.transform = 'rotate(0deg)';
                        }, 2000);
                    };

                    // Запасной таймер на случай если transitionend не сработает
                    setTimeout(showResult, spinDuration * 1000 + 300);
                } else {
                    Notify.error(data.error || 'Ошибка');
                    isSpinning = false;
                    btn.disabled = false;
                    btn.textContent = '🎲 Апгрейд';
                }
            } catch (e) {
                Notify.error('Ошибка соединения');
                isSpinning = false;
                btn.disabled = false;
                btn.textContent = '🎲 Апгрейд';
            }
        }

        async function refreshInventoryAjax() {
            try {
                const resp = await fetch('/web/api/inventory/items');
                const serverItems = await resp.json();
                // Enrich with price/image from server data
                inventoryItems = serverItems.map(item => {
                    const img = item.image_url || (item.item_id ? `/static/placeholder.png` : '/static/placeholder.png');
                    return {
                        id: item.id,
                        item_id: item.item_id,
                        name: item.name,
                        rarity: item.rarity,
                        price_rub: item.price || item.price_rub || 100,
                        image_url: img,
                        wear: item.wear || '',
                        float: item.float || item.float_value || 0
                    };
                });
                renderInventory();
            } catch (e) {
                console.error('Failed to refresh inventory:', e);
                renderInventory();
            }
        }

        async function logout() {
            await fetch('/web/api/auth/logout', { method: 'POST' });
            window.location.href = '/';
        }
    </script>
    <script src="/static/js/sounds.js"></script>
    <script src="/static/js/websocket.js"></script>
    <script src="/static/js/notifications.js"></script>
    <script src="/static/js/safemode.js"></script>
    <script>
        function handleAchievements(data) {
            if (data && data.achievements_unlocked && Array.isArray(data.achievements_unlocked) && data.achievements_unlocked.length > 0) {
                data.achievements_unlocked.forEach(ach => {
                    const title = ach.title || ach.name || 'Достижение';
                    const reward = ach.reward || '';
                    showAchievementPopup(title, reward);
                });
            }
        }
    </script>
    <script>
        function toggleSound() {
            const enabled = SoundManager.toggle();
            document.getElementById('soundToggle').textContent = enabled ? '🔊' : '🔇';
        }
        document.addEventListener('DOMContentLoaded', () => {
            const btn = document.getElementById('soundToggle');
            if (btn) btn.textContent = localStorage.getItem('sound_enabled') !== 'false' ? '🔊' : '🔇';
        });
    </script>
{% if user %}{% include '_activity_sidebar.html' %}{% endif %}
</body>
</html>