/*
========================================
DEVELOPMENT MODE CONFIGURATION GUIDE
========================================

🚨 IMPORTANT: This file contains development-specific configurations!

TO REVERT TO PRODUCTION (ORIGINAL ALGORITHM):
1. Find the line: const DEV_MODE = true;
2. Change it to: const DEV_MODE = false;
3. Save the file

DEVELOPMENT MODE CHANGES:
- Trade Opened Alert: 5 minutes (instead of 4 seconds)
- Trade Closed Alert: 5 minutes (instead of 5 seconds) 
- PNL Box Alert: 4 seconds (unchanged)
- Trade Duration: 3 seconds (instead of 60+ seconds)

PRODUCTION MODE (ORIGINAL):
- Trade Opened Alert: 4 seconds
- Trade Closed Alert: 5 seconds
- PNL Box Alert: 4 seconds
- Trade Duration: Normal timing (60+ seconds)

The system will automatically log the current mode in the browser console.
========================================
*/

// Audio Manager
class AudioManager {
    constructor() {
        this.sounds = {
            tradePlace: new Audio('./audios/deal_open.mp3'),
            tradeWin: new Audio('./audios/deal_close_profit.mp3'),
            tradeLoss: new Audio('./audios/deal_close_wasted.mp3')
        };
        Object.values(this.sounds).forEach(audio => { audio.preload = 'auto'; audio.volume = 0.7; });
    }
    play(type) { this.sounds[type].currentTime = 0; this.sounds[type].play().catch(() => { }); }
    playTradePlace() { this.play('tradePlace'); }
    playTradeWin() { this.play('tradeWin'); }
    playTradeLoss() { this.play('tradeLoss'); }
}

// ========================================
// DEVELOPMENT CONFIGURATION SYSTEM
// ========================================
// 🔧 DEVELOPMENT MODE INACTIVE - Production settings active
const DEV_MODE = false; // 🔧 PRODUCTION MODE

// 🔧 DEVELOPMENT CONFIGURATION (ACTIVE)
// Set DEV_MODE = true above to activate development mode with extended durations

// Alert Duration Configuration
const ALERT_CONFIG = {
    // Production durations (original algorithm)
    PRODUCTION: {
        TRADE_OPENED_DURATION: 3000,    // 3 seconds
        TRADE_CLOSED_DURATION: 3000,    // 3 seconds  
        TRADE_RESULT_DURATION: 5000,    // 5 seconds
        TRADE_DURATION_SECONDS: 60      // 1 minute trades
    },
    // Development durations (extended for testing)
    DEVELOPMENT: {
        TRADE_OPENED_DURATION: 300000,  // 5 minutes (300 seconds)
        TRADE_CLOSED_DURATION: 300000,  // 5 minutes (300 seconds)
        TRADE_RESULT_DURATION: 600000,  // 10 minutes (300 seconds)
        TRADE_DURATION_SECONDS: 3       // 3 seconds for quick testing
    }
};

// Get current configuration based on mode
const getCurrentConfig = () => DEV_MODE ? ALERT_CONFIG.DEVELOPMENT : ALERT_CONFIG.PRODUCTION;

// Development mode helper functions
const getDevTradeDuration = () => DEV_MODE ? ALERT_CONFIG.DEVELOPMENT.TRADE_DURATION_SECONDS : ALERT_CONFIG.PRODUCTION.TRADE_DURATION_SECONDS;
const isDevMode = () => DEV_MODE;
const getDevAlertDuration = (type) => {
    const config = getCurrentConfig();
    switch (type) {
        case 'opened': return config.TRADE_OPENED_DURATION;
        case 'closed': return config.TRADE_CLOSED_DURATION;
        case 'result': return config.TRADE_RESULT_DURATION;
        default: return config.TRADE_OPENED_DURATION;
    }
};

// Force 3-second trade duration in development mode
const getActualTradeDuration = () => {
    if (DEV_MODE) {
        return 3;
    }
    return 60; // Production default
};

// Override any existing trade duration functions
const enforceDevelopmentTradeDuration = () => {
    if (DEV_MODE) {
        // Force all trade durations to 3 seconds in development
        window.TRADE_DURATION = 3;
        window.tradeDuration = 3;
        window.currentTradeDuration = 3;
    }
};

// Make configuration globally available
window.DEV_MODE = DEV_MODE;
window.getCurrentConfig = getCurrentConfig;
window.getDevTradeDuration = getDevTradeDuration;
window.getActualTradeDuration = getActualTradeDuration;
window.isDevMode = isDevMode;
window.getDevAlertDuration = getDevAlertDuration;
window.ALERT_CONFIG = ALERT_CONFIG;
window.enforceDevelopmentTradeDuration = enforceDevelopmentTradeDuration;

// Enforce development settings immediately
enforceDevelopmentTradeDuration();

// Global trade duration override for development mode
window.getTradeDuration = function () {
    if (DEV_MODE) {
        return 3;
    }
    return 60; // Default production duration
};

// Override common trade duration variables
if (DEV_MODE) {
    Object.defineProperty(window, 'TRADE_DURATION', {
        get: function () { return 3; },
        set: function (value) { }
    });

    Object.defineProperty(window, 'tradeDuration', {
        get: function () { return 3; },
        set: function (value) { }
    });
}

// Platform JavaScript
window.pageLoadTime = Date.now(); // Origin for unified 8-second delay

document.addEventListener('DOMContentLoaded', async function () {
    // Initialize flag detection algorithm with timeout
    if (window.flagDetectionAlgorithm) {
        try {
            await Promise.race([
                window.flagDetectionAlgorithm.readyPromise,
                new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000))
            ]);
        } catch (error) {
        }
    }

    // Hide skeleton loader after 5 seconds
    setTimeout(() => {
        const skeleton = document.getElementById('skeleton-loader');
        const overlay = document.querySelector('.skeleton-header-right-overlay');
        if (skeleton) {
            skeleton.style.transition = 'opacity 0.3s ease';
            skeleton.style.opacity = '0';
            setTimeout(() => skeleton.style.display = 'none', 300);
        }
        if (overlay) {
            overlay.style.transition = 'opacity 0.3s ease';
            overlay.style.opacity = '0';
            setTimeout(() => overlay.style.display = 'none', 300);
        }
    }, 5000);

    const audioManager = new AudioManager();
    window.audioManager = audioManager;
    const tabs = document.querySelectorAll('.tab');
    const tabContents = document.querySelectorAll('.tab-content');
    let activeTab = 'trades';
    let tradeCount = 0;
    let orderCount = 0;

    // Demo balance system
    let demoBalance = parseFloat(localStorage.getItem('demoBalance')) || 10000;

    // Asset switching debounce flag
    let isAssetSwitching = false;

    // 🔧 Development Mode Indicator (ACTIVE)
    if (DEV_MODE) {
        // Add visual indicator to page
        const devIndicator = document.createElement('div');
        devIndicator.id = 'dev-mode-indicator';
        devIndicator.innerHTML = '🔧 DEV MODE - 3s Trades';
        devIndicator.style.cssText = `
            position: fixed;
            top: 10px;
            right: 10px;
            background: #ff4444;
            color: white;
            padding: 5px 10px;
            border-radius: 5px;
            font-weight: bold;
            font-size: 12px;
            z-index: 9999;
            box-shadow: 0 2px 5px rgba(0,0,0,0.3);
        `;
        document.body.appendChild(devIndicator);

        // Override any existing trade duration variables
        setInterval(() => {
            if (window.TRADE_DURATION !== 3) {
                window.TRADE_DURATION = 3;
            }
        }, 1000);
    }





    // Trade history system
    let tradeHistory = JSON.parse(localStorage.getItem('tradeHistory')) || [];

    function updateBalanceDisplay() {
        const el = document.querySelector('.account-balance');
        if (el) {
            const formattedBalance = demoBalance.toFixed(2);
            el.textContent = `$${formattedBalance}`;
        }

        // Update percentage investment display when balance changes
        setTimeout(() => {
            if (typeof isPercentageMode !== 'undefined' && isPercentageMode && typeof updatePercentagePayout === 'function') {
                updatePercentagePayout(percentageAmount);
            }
        }, 0);
    }

    function addTradeToHistory(trade) {
        // Enforce development mode trade duration
        if (DEV_MODE) {
            trade.duration = 3;
        }

        tradeHistory.unshift(trade);
        if (tradeHistory.length > 50) tradeHistory.pop();
        localStorage.setItem('tradeHistory', JSON.stringify(tradeHistory));

        // Update running trades count immediately
        const runningTradesCount = tradeHistory.filter(t => t.result === 'pending').length;
        tradeCount = runningTradesCount;
        localStorage.setItem('tradeCount', tradeCount);

        updateTradeHistoryDisplay();
    }

    // Global function to create trades with proper duration
    window.createTradeWithDuration = function (tradeData) {
        const duration = DEV_MODE ? 3 : (tradeData.duration || 60);
        const trade = {
            ...tradeData,
            duration: duration,
            startTime: Date.now()
        };

        return trade;
    };

    async function generateTradeFlags(assetName) {
        if (window.flagDetectionAlgorithm) {
            return await window.flagDetectionAlgorithm.generateTradeFlags(assetName, 'trade-history-flag');
        }
        return '';
    }

    // Update right sidebar asset section flags
    async function updateAssetSectionFlags(assetName) {
        if (window.flagDetectionAlgorithm) {
            await window.flagDetectionAlgorithm.updateAssetSectionFlags(assetName);
        }
    }

    // Update asset card flags
    async function updateAssetCardFlags(assetName) {
        if (window.flagDetectionAlgorithm) {
            await window.flagDetectionAlgorithm.updateAssetCardFlags();
        }
    }

    // Update asset name and flags everywhere
    async function updateAssetDisplay(assetName) {
        // Update asset name in sidebar
        const assetNameElement = document.querySelector('.asset-name');
        if (assetNameElement) {
            assetNameElement.textContent = assetName;

            // Layout is now handled by CSS Flexbox (auto-centering)
            // No need for manual height calculation or class toggling
        }

        // Update asset name in card
        const assetCardLabel = document.querySelector('.asset-card-label');
        if (assetCardLabel) {
            assetCardLabel.textContent = assetName;
        }

        // Update flags in all areas
        await updateAssetSectionFlags(assetName);
        await updateAssetCardFlags(assetName);
    }

    function formatAssetName(assetName) {
        if (!assetName) return 'USD/BDT (...';

        // Use mapping from asset-name-mapping.json for history display
        if (window.getHistoryName) {
            return window.getHistoryName(assetName);
        }

        // Fallback: If asset name contains (OTC), show it as "PAIR (..."
        if (assetName.includes('(OTC)')) {
            const pair = assetName.replace(/\s*\(OTC\).*$/, '');
            return `${pair} (...`;
        }

        // Otherwise show full asset name
        return assetName;
    }



    // ========================================
    // DYNAMIC STYLES INJECTION
    // ========================================
    // Add CSS for trade history flags and direction icons
    if (!document.getElementById('trade-history-flag-styles')) {
        const style = document.createElement('style');
        style.id = 'trade-history-flag-styles';
        style.textContent = `
            .trade-history-flag {
                width: 16px !important;
                height: 16px !important;
                border: 2px solid #353a4d !important;
                border-radius: 50% !important;
                margin-left: -10px;
            }
            /* Right sidebar asset section flags */
            .asset-header .flag-container .flag {
                width: 16px !important;
                height: 16px !important;
                border: 2px solid #353a4d !important;
                border-radius: 50% !important;
                margin-left: 1px;
                display: inline-block;
            }
            .asset-header .flag-container .flag:first-child {
                margin-left: 0;
            }
            /* Right sidebar asset name width limit */
            .asset-header .asset-name {
                max-width: 105px !important;
                overflow-wrap: break-word !important;
                word-wrap: break-word !important;
                word-break: break-word !important;
            }

            /* Asset card flags */
            .asset-card-flags .asset-card-flag {
                width: 14px !important;
                height: 14px !important;
                border: none !important;
                margin-left: -1.4px !important;
                display: inline-block;
            }
            .asset-card-flags .asset-card-flag:first-child {
                margin-top: -18px !important;
                margin-left: 0 !important;
                border-radius: 0 !important;
            }
            .asset-card-flags .asset-card-flag:last-child {
                border: 2px solid #2b3040 !important;
                margin-left: 5px !important;
                margin-top: -4px;
            }
            .asset-card-tab:hover .asset-card-flags .asset-card-flag:last-child {
                border: 2px solid #5a6078 !important;
            }
            .asset-card-tab.active .asset-card-flags .asset-card-flag:last-child {
                border: 2px solid #000000 !important;
            }
            /* Trade closed alert flags */
            .trade-closed-alert .asset-flags .flag {
                width: 16px !important;
                height: 16px !important;
                border: 2px solid #353a4d !important;
                margin-left: 4px;
                display: inline-block;
            }
            .trade-closed-alert .asset-flags .flag:first-child {
                margin-left: -8px;
            }
            .trade-item .direction-icon {
                width: 16px !important;
                height: 16px !important;
                font-size: 8px !important;
            }
            .trade-item .trade-time {
                font-size: 12px !important;
            }
            .icon-trade-x2 {
                height: 16px;
                margin: 0 auto 6px;
                width: 16px;
                fill: #fff;
            }
            .tabs-header .history-icon {
                height: 16px ;
                width: 16px;
                fill: #fff;
            }
            .icon-deal-list-trades {
                width: 16px !important;
                height: 16px !important;
                fill: #fff !important;
            }
            .icon-deal-list-trades * {
                fill: #fff !important;
            }
            .trade-item {
                border-bottom: 1px solid #4a5066 !important;
            }
            .trade-amount.up {
                color: #0FA054 !important;
            }
            .trade-amount.down {
                color: #E75B4D !important;
            }
            /* History section color schemes */
            .trade-item.completed {
                opacity: 0.85;
            }
            .trade-result-alert {
                position: absolute;
                z-index: 1000;
                padding: 7px 14px 18px 14px;
                border-radius: 6px;
                color: rgba(255, 255, 255, 0.8);
                font-size: 15px;
                font-weight: bold;
                width: 94px;
                height: 29px;
                text-transform: uppercase;
                animation: none !important;
                transition: none !important;
            }
            .trade-result-alert::after {
                content: '';
                position: absolute;
                top: 50%;
                right: -7px;
                transform: translateY(-50%);
                width: 0;
                height: 0;
                border-left: 9px solid;
                border-top: 8px solid transparent;
                border-bottom: 8px solid transparent;
            }
            .trade-result-alert.point-left::after {
                right: auto;
                left: -7px;
                border-left: none;
                border-right: 9px solid;
            }
            .trade-result-alert.point-up::after {
                top: -7px;
                right: auto;
                left: 50%;
                transform: translateX(-50%);
                border-left: 8px solid transparent;
                border-right: 8px solid transparent;
                border-bottom: 9px solid;
                border-top: none;
            }
            .trade-result-alert.point-down::after {
                top: auto;
                bottom: -7px;
                right: auto;
                left: 50%;
                transform: translateX(-50%);
                border-left: 8px solid transparent;
                border-right: 8px solid transparent;
                border-top: 9px solid;
                border-bottom: none;
            }
            .trade-result-alert.win {
                background: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert.win::after {
                border-left-color: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert.win.point-left::after {
                border-right-color: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert.win.point-up::after {
                border-bottom-color: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert.win.point-down::after {
                border-top-color: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert.loss {
                background: rgba(231, 91, 77, 0.9);
            }
            .trade-result-alert.loss::after {
                border-left-color: rgba(231, 91, 77, 0.9);
            }
            .trade-result-alert.loss.point-left::after {
                border-right-color: rgba(231, 91, 77, 0.9);
            }
            .trade-result-alert.loss.point-up::after {
                border-bottom-color: rgba(231, 91, 77, 0.9);
            }
            .trade-result-alert.loss.point-down::after {
                border-top-color: rgba(231, 91, 77, 0.9);
            }
            .trade-result-alert.refund {
                background: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert.refund::after {
                border-left-color: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert.refund.point-left::after {
                border-right-color: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert.refund.point-up::after {
                border-bottom-color: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert.refund.point-down::after {
                border-top-color: rgba(15, 160, 84, 0.9);
            }
            .trade-result-alert .close-btn {
                position: absolute;
                top: 4px;
                right: 6px;
                cursor: pointer;
                font-size: 20px;
                opacity: 0.8;
                font-weight: normal;
            }

            .trade-result-alert .result-title {
                margin-bottom: 4px;
                font-size: 10px;
                opacity: 0.9;
            }
            .trade-result-alert .payout-amount {
                font-size: 14px;
                font-weight: bolder;
            }

            @keyframes tradeAlertSlide {
                from { transform: translateX(-20px); opacity: 0; }
                to { transform: translateX(0); opacity: 1; }
            }
            .trade-opened-alert {
                position: absolute;
                z-index: 11;
                background: #0FA054;
                border: 1px solid #0d8a47;
                color: white;
                padding: 6px 12px;
                border-radius: 6px;
                font-size: 12px;
                font-weight: Normal;
                box-shadow: 0 4px 10px rgba(53, 183, 113, .25);
                animation: tradeOpenedSlideDown 0.4s ease-out;
                width: auto;
                height: 20px;
                transition: top 0.3s ease;
                display: flex;
                align-items: center;
                justify-content: space-between;
                white-space: nowrap;
            }
            .trade-opened-alert .close-btn {
                width: 18px;
                height: 18px;
                background: #353A4D;
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                margin-left: 6px;
                flex-shrink: 0;
                font-weight: 300;
            }
            .trade-opened-alert-price-asset-info{
                font-size: 13px;
            }
            .trade-opened-alert .close-btn::after {
                content: '×';
                color: white;
                font-size: 14px;
                margin-top: -1px;
            }
            @keyframes tradeOpenedSlideDown {
                from { transform: translateY(-14px); opacity: 0; }
                to { transform: translateY(0); opacity: 1; }
            }
            @keyframes tradeOpenedSlideLeft {
                from { transform: translateX(0); opacity: 1; }
                to { transform: translateX(-20px); opacity: 0; }
            }
            .trade-closed-alert {
                font: arial ,sans-serif;
                position: absolute;
                z-index: 1000;
                background: #353A4D;
                color: white;
                padding: 15px 15px;
                border-radius: 6px;
                font-size: 13px;
                min-width: 180px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                animation: tradeClosedSlideDown 0.4s ease-out;
                transition: bottom 0.3s ease;
            }

            .trade-closed-alert .first-line {
                display: flex;
                align-items: center;
                margin-bottom: 6px;
                font-weight: 500;
                gap: 4px;
            }
            .trade-closed-alert .asset-flags {
                display: flex;
                gap: 2px;
                flex-shrink: 0;
                align-items: center;
                margin-right: 8px;
            }
            .trade-closed-alert .asset-flags svg {
                width: 16px;
                height: 16px;
                border-radius: 50%;
                margin-left: -10px;
                border: 3px solid #6a6b6eff;
                display: block;
            }
            .trade-closed-alert .asset-flags svg:first-child {
                margin-left: 0;
            }
            .trade-closed-alert .asset-name {
                flex: 1;
            }
            .trade-closed-alert .trade-alert-asset-name {
                flex-shrink: 0;
                margin-left: 17px;
                font-weight: 900;
                font-size: 14px;
            }
            .trade-closed-alert .circle-divider {
                color: #717589;
                font-size: 8px;
                margin: 0 3px;
                flex-shrink: 0;
            }
            .trade-closed-alert .duration {
                font-size: 13px;
                font-weight: bold;
                color: #9093a3ff;
                flex-shrink: 0;
            }
            .trade-closed-alert .second-line {
                font-size: 17px;
                font-weight: bold;
                margin-top: 11px;
            }
            .trade-closed-alert .second-line.win {
                color: #0FA054;
            }
            .trade-closed-alert .second-line.loss {
                color: #E75B4D;
            }
            .trade-closed-alert .close-btn {
                position: absolute;
                top: -1px;
                right: -2px;
                color: #717589;
                cursor: pointer;
                font-size: 18px;
                font-weight: bold;
                width: 24px;
                height: 24px;
                display: flex;
                align-items: center;
                justify-content: center;
                border-radius: 50%;
                font-weight: 50;
            }
                
            .trade-closed-alert .close-btn:hover {
                color: #ffffff;
            }

            @keyframes tradeClosedSlideDown {
                from { transform: translateY(-20px); opacity: 0; }
                to { transform: translateY(0); opacity: 1; }
            }
            
            .trade-closed-alert.closing {
                animation: tradeClosedSlideLeft 0.3s ease-out forwards;
            }
            
            @keyframes tradeClosedSlideLeft {
                from { transform: translateX(0); opacity: 1; }
                to { transform: translateX(-20px); opacity: 0; }
            }
            .tournament-alert {
                position: absolute;
                top: 0px;
                left: 37px;
                background: #026FD3;
                color: white;
                border-radius: 50%;
                width: 15px;
                height: 15px;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 10px;
                font-weight: bold;
                z-index: 10;
            }
            .main-content {
                transition: transform 0.3s ease, width 0.3s ease;
            }
            .app-container.panel-active .main-content {
                width: calc(100vw - 300px);
            }
            .trade-end-line {
                position: absolute;
                background: #fff;
                width: 1px !important;
                z-index: 999;
                pointer-events: none;
                animation: none !important;
                transition: none !important;
            }
            .trade-end-circle {
                position: absolute;
                background: white;
                border-radius: 50%;
                width: 100px;
                height: 100px;
                z-index: 1000;
                pointer-events: none;
                transform: translate(-50%, -50%);
                display: flex;
                justify-content: center;
                align-items: center;
            }
            .trade-end-circle::after {
                content: '';
                width: 40px;
                height: 40px;
                background: #0FA054;
                border-radius: 50%;
            }
            .trade-end-circle.loss::after {
                background: #E75B4D;
            }
            .trade-end-circle.draw::after {
                background: #0FA054;
            }
            .app-container.panel-active #chartContainer {
                width: calc(100vw - 600px) !important;
            }
            .withdraw-btn:hover {
                background-color: #000000 !important;
            }
            .not-available {
                align-items: center;
                display: flex;
                height: 100%;
                justify-content: center;
                width: 100%;
            }
.not-available__content {
  text-align: center;
  padding: 40px;
  max-width: 300px;
}

.not-available__icons {
  width: 64px;
  height: 64px;
  margin-bottom: 24px;
  fill: #535661;
}

.not-available__title {
  font-size: 18px;
  font-weight: 900;
  color: #ffffff;
  margin-bottom: 16px;
  line-height: 1.4;
}

.not-available__color-red {
  color: #E75B4D;
}

.not-available__subtitle {
  font-size: 14px;
  color: #a0a4b8;
  line-height: 1.5;
}

            .trade-progress-bar {
                position: absolute;
                bottom: 0;
                left: 0;
                height: 3px;
                width: 100%;
                background: rgba(255, 255, 255, 0.1);
                border-radius: 0 0 4px 4px;
                overflow: hidden;
                z-index: 8;
            }
            .trade-progress-fill {
                height: 100%;
                background: #0FA054;
                transition: width 0.3s ease, background-color 0.3s ease;
                transform-origin: left;
                border-radius: inherit;
            }
            .trade-progress-fill.losing {
                background: #E75B4D;
            }
            .trade-progress-fill.winning {
                background: #0FA054;
            }
            .btn-up, .btn-down {
                box-shadow: 0 7px 15px rgba(0,0,0,0.3) !important;
            }
            .control-btn {
                border-radius: 50% !important;
                width: 40px !important;
                height: 40px !important;
                aspect-ratio: 1 !important;
            }
            /* Input section hover and focus effects */
            .time-section, .timer-section, .investment-section {
                transition: border-color 0.2s ease, box-shadow 0.2s ease;
            }
            .time-section:hover, .timer-section:hover, .investment-section:hover {
                border-color: rgba(255, 255, 255, 0.6) !important;
            }
            .time-section:focus-within, .timer-section:focus-within, .investment-section:focus-within,
            .time-section.dropdown-open, .timer-section.dropdown-open {
                border-color: #ffffff !important;
            }
            .investment-value:focus {
                outline: none;
            }
            /* GPU acceleration for chart price line timer */
            .price-line-timer, .candle-timer, .chart-timer, .price-countdown,
            .horizontal-price-line, .current-price-line, .dashed-price-line,
            [class*="price-line"], [class*="candle-timer"], [class*="countdown"],
            .chart-price-indicator, .price-label, .time-label {
                will-change: transform !important;
                transform: translateZ(0) !important;
                backface-visibility: hidden !important;
                -webkit-font-smoothing: antialiased !important;
                -moz-osx-font-smoothing: grayscale !important;
                text-rendering: optimizeSpeed !important;
                font-feature-settings: "kern" 0 !important;
                contain: layout style paint !important;
            }

            /* Dropdown flag styles */
            .activate-asset-item {
                display: flex;
                align-items: center;
                gap: 8px;
            }
        `;
        document.head.appendChild(style);
    }

    async function updateTradeHistoryDisplay() {
        const tab = document.getElementById('trades-tab');
        const runningTrades = tradeHistory.filter(trade => trade.result === 'pending');
        const allTrades = tradeHistory.slice(0, 10); // Show last 10 trades

        // Update trade count to only show running trades
        tradeCount = runningTrades.length;
        localStorage.setItem('tradeCount', tradeCount);
        updateTabDisplay();

        if (!tab) return;

        if (!allTrades.length) {
            tab.innerHTML = '<div class="empty-state-icon"><svg class="icon-trades-empty" style="width: 50px; height: 50px; fill: white; color: white;"><use xlink:href="./svg/spritemap.svg#icon-trades-empty"></use></svg></div><p>You don\'t have any trade history yet. You can open a trade using the form above.</p>';
            return;
        }

        // Group trades by date
        const tradesByDate = {};
        allTrades.forEach(trade => {
            const tradeDate = new Date(trade.startTime).toDateString();
            if (!tradesByDate[tradeDate]) {
                tradesByDate[tradeDate] = [];
            }
            tradesByDate[tradeDate].push(trade);
        });

        let htmlContent = '';
        for (const dateStr of Object.keys(tradesByDate)) {
            const trades = tradesByDate[dateStr];
            const date = new Date(dateStr);
            const day = date.getDate();
            const month = date.toLocaleDateString('en-US', { month: 'long' });
            const formattedDate = `${day} ${month}`;

            // Add date separator with trade count
            htmlContent += `<div style="display: flex; align-items: center; justify-content: center; margin-top: 6px; margin-bottom: 10px; color: #a0a4b8; font-size: 14px;">
                <span style="font-size: 10px; font-weight: 900; text-transform: uppercase;">${formattedDate}</span>
                <div style="width: 16px; height: 16px; background: #9598A0; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-left: 10px; font-size: 10px; font-weight: bold; color: #2B3040;">${trades.length}</div>
            </div>`;

            // Add trades for this date
            const tradeHtmlPromises = trades.map(async trade => {
                const elapsed = Math.floor((Date.now() - trade.startTime) / 1000);
                const remaining = Math.max(0, trade.duration - elapsed);
                let timeDisplay = '00:00:00', payoutDisplay, resultClass;

                // Use stored asset info or fallback
                const originalAssetName = trade.assetName || 'USD/BDT (OTC)';
                const displayAssetName = formatAssetName(originalAssetName);
                const flagsHtml = await generateTradeFlags(originalAssetName);

                if (trade.result === 'pending' && remaining > 0) {
                    const h = Math.floor(remaining / 3600), m = Math.floor((remaining % 3600) / 60), s = remaining % 60;
                    timeDisplay = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;

                    // Get current price from multi-chart manager or fallback to global chart
                    let currentPrice = trade.startPrice;
                    let tradeLinePrice = trade.startPrice;

                    if (window.multiChartManager && window.multiChartManager.activeAsset) {
                        const activeChart = window.multiChartManager.getChart(window.multiChartManager.activeAsset);
                        if (activeChart) {
                            currentPrice = activeChart.currentPrice || trade.startPrice;
                            const tradeLine = activeChart.tradelines?.find(line => line.tradeId === trade.id);
                            tradeLinePrice = tradeLine?.price || trade.startPrice;
                        }
                    } else if (window.chart) {
                        currentPrice = window.chart.currentPrice || trade.startPrice;
                        const tradeLine = window.chart.tradelines?.find(line => line.tradeId === trade.id);
                        tradeLinePrice = tradeLine?.price || trade.startPrice;
                    }

                    // Refund threshold based on asset pip value
                    const assetConfig = getAssetConfig(originalAssetName);

                    // Convert to integer pips to avoid floating-point errors
                    const pipMultiplier = 1 / assetConfig.pipValue;
                    const currentPips = Math.round(currentPrice * pipMultiplier);
                    const tradePips = Math.round(tradeLinePrice * pipMultiplier);
                    const pipDiff = Math.abs(currentPips - tradePips);

                    if (pipDiff === 0) {
                        payoutDisplay = `+${parseFloat(trade.amount || 0).toFixed(2)} $`; resultClass = 'refund';
                    } else if ((trade.type === 'up' && currentPrice > tradeLinePrice) || (trade.type === 'down' && currentPrice < tradeLinePrice)) {
                        // Use stored payout percentage if available
                        let exactPayout;
                        if (trade.payoutPercentage) {
                            const percentage = parseFloat(trade.payoutPercentage.replace('%', '')) || 80;
                            const profit = trade.amount * (percentage / 100);
                            exactPayout = trade.amount + profit;
                        } else {
                            exactPayout = window.calculateExactPayout ? window.calculateExactPayout(trade.amount) : (trade.amount || 0) * getDynamicPayoutMultiplier();
                        }
                        payoutDisplay = `+${parseFloat(exactPayout || 0).toFixed(2)} $`; resultClass = 'win';
                    } else {
                        payoutDisplay = '0.00 $'; resultClass = 'loss';
                    }
                } else {
                    // Completed trade - show final result
                    const h = Math.floor(trade.duration / 3600), m = Math.floor((trade.duration % 3600) / 60), s = trade.duration % 60;
                    timeDisplay = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;

                    if (trade.result === 'win') {
                        let winPayout = trade.payout;
                        if (!winPayout && trade.payoutPercentage) {
                            const percentage = parseFloat(trade.payoutPercentage.replace('%', '')) || 80;
                            const profit = trade.amount * (percentage / 100);
                            winPayout = trade.amount + profit;
                        }
                        payoutDisplay = `+${parseFloat(winPayout || 0).toFixed(2)} $`;
                        resultClass = 'win';
                    } else if (trade.result === 'refund') {
                        payoutDisplay = `+${parseFloat(trade.amount || 0).toFixed(2)} $`;
                        resultClass = 'refund';
                    } else {
                        payoutDisplay = '0.00 $';
                        resultClass = 'loss';
                    }
                }

                const doubleUpBox = (trade.result === 'pending' && remaining > 60) ? `<div class="double-up-box" style="align-items: center; background: hsla(0,0%,100%,.05); border-radius: 4px; cursor: pointer; display: flex; height: 52px; justify-content: center; position: relative; -webkit-user-select: none; -moz-user-select: none; user-select: none; width: 100%; margin-top: 8px; flex-direction: column;"><svg class="icon-trade-x2"><use xlink:href="./svg/spritemap.svg#icon-trade-x2"></use></svg><div style="font-size: 12px; color: #a0a4b8;">Double up</div></div>` : '';

                const remainingTime = trade.duration - elapsed;
                const sellPercentage = Math.max(0, 30 - elapsed);
                const sellNowAmount = (trade.amount * (sellPercentage / 100)).toFixed(2);
                const sellNowBox = (trade.result === 'pending' && elapsed < 30 && remainingTime > 20) ? `<div class="sell-now-box" style="align-items: center; background: #026FD3; border-radius: 4px; cursor: pointer; display: flex; height: 32px; justify-content: space-between; position: relative; -webkit-user-select: none; -moz-user-select: none; user-select: none; width: 100%; margin-top: 5px; padding: 0 8px; overflow: hidden; box-sizing: border-box;"><div style="font-size: 12px; color: #ffffff;">Sell now</div><div style="font-size: 12px; color: #ffffff;">$${sellNowAmount}</div></div>` : '';

                const completedClass = trade.result !== 'pending' ? 'completed' : '';
                return `<div class="trade-item ${completedClass}" style="position: relative; padding-left: 25px;"><svg class="icon-caret" style="width: 9px; height: 6px; fill: #ffffff; position: absolute; left: 1px; top: 13px; z-index: 10;"><use xlink:href="./svg/spritemap.svg#icon-caret"></use></svg><div class="trade-main"><div class="trade-header"><div class="flag-container">${flagsHtml}</div><div class="trade-asset">${displayAssetName}</div><div class="trade-time">${timeDisplay}</div></div><div class="trade-details"><div class="trade-direction"><div class="direction-icon ${trade.type}"><i class="fas fa-arrow-${trade.type === 'up' ? 'up' : 'down'}"></i></div><span class="trade-amount ${trade.type}">$${parseFloat(trade.amount || 0).toFixed(2)}</span></div><div class="trade-result ${resultClass}">${payoutDisplay}</div></div></div>${doubleUpBox}${sellNowBox}</div>`;
            });
            htmlContent += (await Promise.all(tradeHtmlPromises)).join('');
        }

        tab.innerHTML = htmlContent;
    }

    updateBalanceDisplay();
    updateTradeHistoryDisplay();

    // Tab functionality
    function initializeTabs() {
        document.querySelector(`.tab[data-tab="${activeTab}"]`).classList.add('active');
        document.getElementById(`${activeTab}-tab`).classList.add('active');
        updateTabDisplay();
    }

    function updateTabDisplay() {
        const runningTradesCount = tradeHistory.filter(trade => trade.result === 'pending').length;

        tabs.forEach(tab => {
            const tabId = tab.getAttribute('data-tab'), isActive = tabId === activeTab;
            // Remove inline styles to let CSS handle the styling
            tab.style.flex = '';
            tab.style.width = '';

            tab.innerHTML = isActive ?
                (tabId === 'trades' ? `<span>Trades</span><span class="trade-count">${runningTradesCount}</span>` : `<span>Orders</span><span class="order-count">${orderCount}</span>`) :
                (tabId === 'orders' ? `<svg class="icon-time-setting section-deal__pending-time tab-icon"><use xlink:href="./svg/spritemap.svg#icon-time-setting"></use></svg><span class="order-count">${orderCount}</span>` : `<svg class="icon-deal-list-trades tab-icon" style="width: 16px; height: 16px; fill: #CBCCCF;"><use xlink:href="./svg/spritemap.svg#icon-deal-list-trades"></use></svg><span class="trade-count">${runningTradesCount}</span>`);
        });
    }

    tabs.forEach(tab => {
        tab.addEventListener('click', function () {
            activeTab = this.getAttribute('data-tab');
            tabs.forEach(t => t.classList.remove('active'));
            tabContents.forEach(c => c.classList.remove('active'));
            this.classList.add('active');
            document.getElementById(`${activeTab}-tab`).classList.add('active');
            updateTabDisplay();
        });
    });

    // Time controls
    const timeValue = document.querySelector('.time-value');
    const timeMinusBtn = document.querySelector('.time-control.minus');
    const timePlusBtn = document.querySelector('.time-control.plus');
    let minutes = 0;
    let baseTime = null;
    let isManualTimeSet = false;

    function updateAllTimeDisplays() {
        // Delegate to centralized time display controller
        if (window.timeDisplayController) {
            window.timeDisplayController.updateAllTimeDisplays();
        }

        // Update time controls state
        timeMinusBtn.classList.toggle('disabled', minutes <= 0);
    }

    const checkChartData = setInterval(() => {
        if (window.chart?.candleData?.length && !baseTime) {
            baseTime = new Date(window.chart.candleData[0].timestamp);
            updateTimeDisplay();
            clearInterval(checkChartData);
        }
    }, 100);

    timeMinusBtn?.addEventListener('click', function () {
        if (minutes > 0) {
            minutes--;
            if (minutes === 0) {
                isManualTimeSet = false;
                window.isManualTimeSet = false;
                window.manualTimeOffset = undefined;
            } else {
                isManualTimeSet = true;
                window.isManualTimeSet = true;
                window.manualTimeOffset = minutes;
            }
            updateAllTimeDisplays();
        }
    });

    timePlusBtn?.addEventListener('click', function () {
        minutes++;
        isManualTimeSet = true;
        window.isManualTimeSet = true;
        window.manualTimeOffset = minutes;
        updateAllTimeDisplays();
    });
    updateAllTimeDisplays();

    window.getTimeOffsetMinutes = function () { return minutes; };
    window.incrementTimeOffset = function (amount) { minutes += amount; updateAllTimeDisplays(); };
    window.generateTimeOptions = generateTimeOptions;

    // Time dropdown functionality
    const timeSection = document.getElementById('time-section');
    const timeDropdown = document.getElementById('time-dropdown');
    const timerSection = document.getElementById('timer-section');
    const timerDropdown = document.getElementById('timer-dropdown');
    let isTimeDropdownOpen = false;
    let isTimerDropdownOpen = false;
    let isTimerMode = false;
    let selectedTimerSeconds = 60;
    let timerInterval = null;
    let remainingSeconds = 0;

    function generateTimeOptions() {
        if (!window.chart || !window.chart.candleData || window.chart.candleData.length === 0) return;

        const currentCandle = window.chart.candleData[window.chart.currentCandleIndex];
        if (!currentCandle) return;

        let baseTime;
        if (window.chart.currentCandleElapsed >= 30) {
            baseTime = new Date(currentCandle.timestamp + 60000);
        } else {
            baseTime = new Date(currentCandle.timestamp + window.chart.currentCandleElapsed * 1000);
        }

        const timeOptions = [0, 1, 2, 3, 4, 5, 10, 15, 30, 45, 60, 120, 180, 240];

        timeDropdown.innerHTML = '';

        for (let i = 0; i < timeOptions.length; i += 3) {
            const row = document.createElement('div');
            row.className = 'time-dropdown-row';

            for (let j = i; j < Math.min(i + 3, timeOptions.length); j++) {
                const minutesOffset = timeOptions[j];
                const futureTime = new Date(baseTime.getTime() + minutesOffset * 60000);
                const timeString = futureTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false });

                const item = document.createElement('div');
                item.className = 'time-dropdown-item';
                item.setAttribute('data-minutes', minutesOffset);
                item.textContent = timeString;

                item.addEventListener('click', function (e) {
                    e.stopPropagation();

                    const selectedTime = this.textContent;
                    document.querySelector('.time-value').textContent = selectedTime;

                    minutes = minutesOffset;

                    if (minutesOffset === 0) {
                        window.isManualTimeSet = false;
                        window.manualTimeOffset = undefined;
                    } else {
                        window.isManualTimeSet = true;
                        window.manualTimeOffset = minutesOffset;
                    }

                    document.querySelectorAll('.time-dropdown-item').forEach(i => i.classList.remove('active'));
                    this.classList.add('active');

                    timeDropdown.classList.remove('show');
                    timeSection.classList.remove('dropdown-open');
                    isTimeDropdownOpen = false;
                });

                row.appendChild(item);
            }

            timeDropdown.appendChild(row);
        }
    }

    timeSection.addEventListener('click', function (e) {
        if (e.target.classList.contains('time-control') || e.target.classList.contains('time-switch')) return;

        e.stopPropagation();

        if (!isTimeDropdownOpen) {
            generateTimeOptions();
            timeDropdown.classList.add('show');
            timeSection.classList.add('dropdown-open');
            isTimeDropdownOpen = true;
        } else {
            timeDropdown.classList.remove('show');
            timeSection.classList.remove('dropdown-open');
            isTimeDropdownOpen = false;
        }
    });

    document.addEventListener('click', function (e) {
        if (!timeSection.contains(e.target)) {
            timeDropdown.classList.remove('show');
            timeSection.classList.remove('dropdown-open');
            isTimeDropdownOpen = false;
        }
        if (!timerSection.contains(e.target)) {
            timerDropdown.classList.remove('show');
            timerSection.classList.remove('dropdown-open');
            isTimerDropdownOpen = false;
        }
    });

    // Timer functionality
    function formatTimerDisplay(seconds) {
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        const secs = seconds % 60;
        return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    }

    function startTimer() {
        if (timerInterval) clearInterval(timerInterval);
        remainingSeconds = selectedTimerSeconds;

        timerInterval = setInterval(() => {
            remainingSeconds--;
            const timerValue = document.querySelector('.timer-value');
            if (timerValue) {
                timerValue.textContent = formatTimerDisplay(remainingSeconds);
            }

            if (remainingSeconds <= 0) {
                clearInterval(timerInterval);
                timerInterval = null;
                // Reset timer
                remainingSeconds = selectedTimerSeconds;
                if (timerValue) {
                    timerValue.textContent = formatTimerDisplay(remainingSeconds);
                }
            }
        }, 1000);
    }

    function updateTimerDisplay() {
        const timerValue = document.querySelector('.timer-value');
        if (timerValue) {
            timerValue.textContent = formatTimerDisplay(selectedTimerSeconds);
        }
    }

    // Timer +/- controls
    document.getElementById('timer-minus')?.addEventListener('click', function (e) {
        e.stopPropagation();
        if (selectedTimerSeconds > 5) {
            if (selectedTimerSeconds <= 60) {
                selectedTimerSeconds -= 5;
            } else if (selectedTimerSeconds <= 3600) {
                selectedTimerSeconds -= 60;
            } else {
                selectedTimerSeconds -= 3600;
            }
            updateTimerDisplay();

            // Update time section values but stay in timer mode
            const timerMinutes = Math.floor(selectedTimerSeconds / 60);
            minutes = timerMinutes;

            if (timerMinutes > 0) {
                isManualTimeSet = true;
                window.isManualTimeSet = true;
                window.manualTimeOffset = timerMinutes;
            } else {
                isManualTimeSet = false;
                window.isManualTimeSet = false;
                window.manualTimeOffset = undefined;
            }

            updateTimeDisplay();
            timeMinusBtn.classList.toggle('disabled', minutes <= 0);
        }
    });

    document.getElementById('timer-plus')?.addEventListener('click', function (e) {
        e.stopPropagation();
        if (selectedTimerSeconds < 14400) {
            if (selectedTimerSeconds < 60) {
                selectedTimerSeconds += 5;
            } else if (selectedTimerSeconds < 3600) {
                selectedTimerSeconds += 60;
            } else {
                selectedTimerSeconds += 3600;
            }
            updateTimerDisplay();

            // Update time section values but stay in timer mode
            const timerMinutes = Math.floor(selectedTimerSeconds / 60);
            minutes = timerMinutes;

            if (timerMinutes > 0) {
                isManualTimeSet = true;
                window.isManualTimeSet = true;
                window.manualTimeOffset = timerMinutes;
            } else {
                isManualTimeSet = false;
                window.isManualTimeSet = false;
                window.manualTimeOffset = undefined;
            }

            updateTimeDisplay();
            timeMinusBtn.classList.toggle('disabled', minutes <= 0);
        }
    });

    // Switch between time and timer modes
    document.getElementById('time-switch')?.addEventListener('click', function (e) {
        e.stopPropagation();
        isTimerMode = true;
        timeSection.style.display = 'none';
        timerSection.style.display = 'block';

        // Keep the heading as "Time" instead of changing to "Timer"
        const timerLegend = document.querySelector('.timer-legend');
        if (timerLegend) {
            timerLegend.textContent = 'Time';
        }

        updateTimerDisplay();
    });

    document.getElementById('timer-switch')?.addEventListener('click', function (e) {
        e.stopPropagation();
        isTimerMode = false;
        timerSection.style.display = 'none';
        timeSection.style.display = 'block';
        if (timerInterval) {
            clearInterval(timerInterval);
            timerInterval = null;
        }
    });

    // Timer dropdown functionality
    timerSection?.addEventListener('click', function (e) {
        if (e.target.classList.contains('timer-switch')) return;

        e.stopPropagation();

        if (!isTimerDropdownOpen) {
            timerDropdown.classList.add('show');
            timerSection.classList.add('dropdown-open');
            isTimerDropdownOpen = true;
        } else {
            timerDropdown.classList.remove('show');
            timerSection.classList.remove('dropdown-open');
            isTimerDropdownOpen = false;
        }
    });

    // Timer dropdown item selection
    document.querySelectorAll('.timer-dropdown-item').forEach(item => {
        item.addEventListener('click', function (e) {
            e.stopPropagation();

            const seconds = parseInt(this.getAttribute('data-seconds'));
            selectedTimerSeconds = seconds;
            remainingSeconds = seconds;

            // Update main timer display immediately
            updateTimerDisplay();

            // Update time section values but stay in timer mode
            const timerMinutes = Math.floor(seconds / 60);
            minutes = timerMinutes;

            if (timerMinutes > 0) {
                isManualTimeSet = true;
                window.isManualTimeSet = true;
                window.manualTimeOffset = timerMinutes;
            } else {
                isManualTimeSet = false;
                window.isManualTimeSet = false;
                window.manualTimeOffset = undefined;
            }

            updateTimeDisplay();
            timeMinusBtn.classList.toggle('disabled', minutes <= 0);

            timerDropdown.classList.remove('show');
            timerSection.classList.remove('dropdown-open');
            isTimerDropdownOpen = false;
        });
    });

    // Initialize timer display
    updateTimerDisplay();



    // Consolidation function to update time section when timer is selected
    function consolidateTimerWithTimeSection(timerSeconds) {
        // Convert timer seconds to minutes for time section
        const timerMinutes = Math.floor(timerSeconds / 60);

        // Update the time section variables
        minutes = timerMinutes;

        // Set manual time flags
        if (timerMinutes > 0) {
            isManualTimeSet = true;
            window.isManualTimeSet = true;
            window.manualTimeOffset = timerMinutes;
        } else {
            isManualTimeSet = false;
            window.isManualTimeSet = false;
            window.manualTimeOffset = undefined;
        }

        // Update time section display (but stay in timer mode)
        updateTimeDisplay();

        // Update time section controls state
        timeMinusBtn.classList.toggle('disabled', minutes <= 0);
    }



    // Investment controls
    const investmentInput = document.querySelector('.investment-value');
    const investMinusBtn = document.querySelector('.investment-control.minus');
    const investPlusBtn = document.querySelector('.investment-control.plus');
    let investmentAmount = 1;
    const MIN_INVESTMENT = 1;
    const MAX_INVESTMENT = 3000;

    if (investmentInput && investmentInput.value) {
        const currentValue = parseInt(investmentInput.value.replace(/[^0-9]/g, ''));
        if (!isNaN(currentValue) && currentValue >= MIN_INVESTMENT && currentValue <= MAX_INVESTMENT) {
            investmentAmount = currentValue;
        }
    }

    // Dynamic Payout System
    function getDynamicPayoutMultiplier() {
        const percentage = getDynamicPayoutPercentage();
        return percentage / 100;
    }

    function getDynamicPayoutPercentage() {
        const activeAssetCard = document.querySelector('.asset-card-tab.active') ||
            document.querySelector('.asset-card-tab:not([style*="display: none"])');
        if (activeAssetCard) {
            const payoutElement = activeAssetCard.querySelector('.asset-card-payout');
            const payoutText = payoutElement?.textContent;
            if (payoutText) {
                const percentage = parseFloat(payoutText.replace('%', ''));
                return percentage;
            }
        }
    }

    function calculateExactPayout(amount) {
        const percentage = getDynamicPayoutPercentage();
        const profit = amount * (percentage / 100);
        const totalPayout = amount + profit;
        return totalPayout;
    }

    function updateInvestmentDisplay() {
        investmentInput.value = `${investmentAmount} $`;
        const exactPayout = calculateExactPayout(investmentAmount);
        const formattedPayout = exactPayout.toFixed(2);

        // Update amount payout - only update text, never recreate elements
        const amountPayoutElement = document.querySelector('.amount-payout-info');
        if (amountPayoutElement) {
            const valueElement = amountPayoutElement.querySelector('.info-value');
            if (valueElement) {
                // Only update the text content, preserve HTML structure
                const boldTag = valueElement.querySelector('b');
                if (boldTag) {
                    boldTag.textContent = `${formattedPayout} $`;
                }
            }
        }

        investMinusBtn.classList.toggle('disabled', investmentAmount <= MIN_INVESTMENT);
        investPlusBtn.classList.toggle('disabled', investmentAmount >= MAX_INVESTMENT);
    }

    window.calculateExactPayout = calculateExactPayout;

    // Function to update trade when it completes/expires
    window.updateTradeResult = function (tradeId, result, payout = 0) {
        const tradeIndex = tradeHistory.findIndex(trade => trade.id === tradeId);
        if (tradeIndex !== -1) {
            tradeHistory[tradeIndex].result = result;
            if (payout > 0) {
                tradeHistory[tradeIndex].payout = payout;
            }
            localStorage.setItem('tradeHistory', JSON.stringify(tradeHistory));

            // Update running trades count
            const runningTradesCount = tradeHistory.filter(t => t.result === 'pending').length;
            tradeCount = runningTradesCount;
            localStorage.setItem('tradeCount', tradeCount);

            updateTradeHistoryDisplay();

            // Schedule deletion from ongoing-trade-information.json 5 seconds after trade ends
            if (window.tradePayoutStorage) {
                setTimeout(() => {
                    window.tradePayoutStorage.deleteTradeInfo(tradeId);
                }, 5000);
            }
        }
    };

    // Function to get current running trades count
    window.getRunningTradesCount = function () {
        return tradeHistory.filter(trade => trade.result === 'pending').length;
    };
    window.getDynamicPayoutMultiplier = getDynamicPayoutMultiplier;



    investmentInput?.addEventListener('focus', function () {
        if (isPercentageMode) {
            this.value = percentageAmount + ' %';
        } else {
            this.value = investmentAmount + ' $';
        }
        setTimeout(() => {
            const numLength = isPercentageMode ? percentageAmount.toString().length : investmentAmount.toString().length;
            this.setSelectionRange(numLength, numLength);
        }, 0);
    });

    investmentInput?.addEventListener('blur', function () {
        if (!isPercentageMode) {
            const value = parseInt(this.value.replace(/[^0-9]/g, '')) || MIN_INVESTMENT;
            investmentAmount = Math.max(MIN_INVESTMENT, Math.min(MAX_INVESTMENT, value));
            updateInvestmentDisplay();
        } else {
            const percentage = parseFloat(this.value.replace(/[^0-9.]/g, '')) || 1;
            percentageAmount = Math.max(1, Math.min(100, percentage));
            this.value = `${percentageAmount} %`;
            updatePercentagePayout(percentageAmount);
        }
    });

    investmentInput?.addEventListener('keypress', function (e) {
        if (e.key === 'Enter') {
            this.blur();
        }
    });

    // Click outside to blur investment input
    document.addEventListener('click', function (e) {
        if (investmentInput && !investmentInput.contains(e.target) && !e.target.closest('.investment-section')) {
            if (document.activeElement === investmentInput) {
                investmentInput.blur();
            }
        }
    });

    // Blinking effect when deleting the last digit
    investmentInput?.addEventListener('input', function () {
        const digits = this.value.replace(/[^0-9]/g, '');

        if (digits === '') {
            // Last digit deleted - hide input
            this.style.opacity = '0';

            setTimeout(() => {
                // Restore defaults after 0.5 seconds
                if (!isPercentageMode) {
                    investmentAmount = 1;
                    updateInvestmentDisplay();
                } else {
                    percentageAmount = 1;
                    this.value = '1 %';
                    updatePercentagePayout(1);
                }

                this.style.opacity = '1';

                // Restore formatting if focused (updateInvestmentDisplay removes focus formatting)
                if (document.activeElement === this) {
                    if (isPercentageMode) {
                        this.value = percentageAmount + ' %';
                    } else {
                        // Keep formatted with $ but cursor might jump. 
                        // updateInvestmentDisplay sets "$1" or "1 $" depending on implementation.
                        // Let's rely on updateInvestmentDisplay first.
                        // However, updateInvestmentDisplay uses "1 $" format. 
                        // Focus handler uses "1 $" format too.
                        // So it should be consistent.
                    }
                }
            }, 200);
        }
    });

    updateInvestmentDisplay();

    // Investment system: Direct amount OR Percentage of balance (1% to 100%)
    let isPercentageMode = false;
    let percentageAmount = 1; // Separate variable for percentage mode

    function getCurrentInvestmentAmount() {
        if (isPercentageMode) {
            return parseFloat(((demoBalance * percentageAmount) / 100).toFixed(2));
        }
        return investmentAmount;
    }

    function updatePercentagePayout(percentage) {
        const calculatedAmount = (demoBalance * percentage) / 100;

        // Update investment info - only update text, never recreate elements
        const investmentInfo = document.getElementById('investment-info');
        if (investmentInfo) {
            const valueElement = investmentInfo.querySelector('.info-value');
            if (valueElement) {
                // Only update the text content, preserve HTML structure
                const boldTag = valueElement.querySelector('b');
                if (boldTag) {
                    boldTag.textContent = `${calculatedAmount.toFixed(2)} $`;
                }
            }
        }

        // Calculate exact payout using the same algorithm as direct amount mode
        const exactPayout = calculateExactPayout(calculatedAmount);

        // Update percentage payout - only update text, never recreate elements
        const percentagePayoutElement = document.querySelector('.percentage-payout-info');
        if (percentagePayoutElement) {
            const valueElement = percentagePayoutElement.querySelector('.info-value');
            if (valueElement) {
                // Only update the text content, preserve HTML structure
                const boldTag = valueElement.querySelector('b');
                if (boldTag) {
                    boldTag.textContent = `${exactPayout.toFixed(2)} $`;
                    // Make only the payout amount white color
                    boldTag.style.color = '#ffffff';
                }
            }
        }

        // Update +/- button states
        investMinusBtn.classList.toggle('disabled', percentage <= 1);
        investPlusBtn.classList.toggle('disabled', percentage >= 100);
    }

    document.querySelector('.investment-switch')?.addEventListener('click', function () {
        isPercentageMode = !isPercentageMode;

        if (isPercentageMode) {
            // Show percentage elements, hide amount elements
            document.querySelector('.amount-payout-info').style.display = 'none';
            document.querySelector('.percentage-payout-info').style.display = 'flex';
            document.getElementById('investment-info').style.display = 'flex';

            investmentInput.value = `${percentageAmount} %`;
            updatePercentagePayout(percentageAmount);
        } else {
            // Show amount elements, hide percentage elements
            document.querySelector('.amount-payout-info').style.display = 'flex';
            document.querySelector('.percentage-payout-info').style.display = 'none';
            document.getElementById('investment-info').style.display = 'none';

            investmentInput.value = `${investmentAmount} $`;
            updateInvestmentDisplay();
        }
    });

    investmentInput?.addEventListener('input', function (e) {
        const cursorPos = this.selectionStart;
        const oldValue = this.value;

        if (isPercentageMode) {
            let numericValue = this.value.replace(/[^0-9.]/g, '');
            let percentage = parseFloat(numericValue) || 1;
            if (percentage > 100) {
                percentage = 100;
                numericValue = '100';
            }
            percentage = Math.max(1, Math.min(100, percentage));
            percentageAmount = percentage;
            this.value = numericValue + ' %';
            const newCursorPos = Math.min(cursorPos, numericValue.length);
            this.setSelectionRange(newCursorPos, newCursorPos);
            updatePercentagePayout(percentage);
        } else {
            let numericValue = this.value.replace(/[^0-9]/g, '');
            if (numericValue.length > 4) numericValue = numericValue.slice(0, 4);
            const amount = Math.max(MIN_INVESTMENT, Math.min(MAX_INVESTMENT, parseInt(numericValue) || MIN_INVESTMENT));
            investmentAmount = amount;
            this.value = numericValue + ' $';
            const newCursorPos = Math.min(cursorPos, numericValue.length);
            this.setSelectionRange(newCursorPos, newCursorPos);
            updateInvestmentDisplay();
        }
    });



    investMinusBtn?.addEventListener('click', function () {
        if (isPercentageMode) {
            if (percentageAmount > 1) {
                percentageAmount--;
                investmentInput.value = `${percentageAmount} %`;
                updatePercentagePayout(percentageAmount);
            }
        } else {
            if (investmentAmount > MIN_INVESTMENT) {
                investmentAmount--;
                updateInvestmentDisplay();
            }
        }
    });

    investPlusBtn?.addEventListener('click', function () {
        if (isPercentageMode) {
            if (percentageAmount < 100) {
                percentageAmount++;
                investmentInput.value = `${percentageAmount} %`;
                updatePercentagePayout(percentageAmount);
            }
        } else {
            if (investmentAmount < MAX_INVESTMENT) {
                investmentAmount++;
                updateInvestmentDisplay();
            }
        }
    });

    setTimeout(() => { updateInvestmentDisplay(); }, 100);

    // Trade placement
    // function placeTrade(type) {
    //     const tradeAmount = getCurrentInvestmentAmount();
    //     if (demoBalance < tradeAmount) { alert('Insufficient balance!'); return; }

    //     audioManager.playTradePlace();
    //     demoBalance -= tradeAmount;
    //     localStorage.setItem('demoBalance', demoBalance);
    //     updateBalanceDisplay();

    //     const tradeId = Date.now();

    //     // Get current price and asset name
    //     const currentPrice = window.chart?.currentPrice || 0;
    //     const assetName = document.querySelector('.asset-name')?.textContent || 'USD/BDT (OTC)';

    //     // 🔧 DEVELOPMENT CODE (ACTIVE)
    //     const config = getCurrentConfig();
    //     if (DEV_MODE) {

    //     }
    //     showTradeOpenedAlert(currentPrice.toFixed(3), assetName, config.TRADE_OPENED_DURATION);

    //     if (window.chart) window.chart[`place${type.charAt(0).toUpperCase() + type.slice(1)}Trade`](tradeAmount, null, type, tradeId);

    //     // Update tab display after placing trade
    //     setTimeout(() => updateTabDisplay(), 100);
    // }

    // Trade placement with 500ms delay system
    let pendingTrades = new Map();
    let tradeDelayTimeout = null;
    const TRADE_DELAY_MS = 500; // 0.5 seconds

    // Trade placement with delay
    function placeTrade(type) {
        const tradeAmount = getCurrentInvestmentAmount();

        // Validate trade amount is within bounds
        if (tradeAmount < MIN_INVESTMENT || tradeAmount > MAX_INVESTMENT) {
            alert(`Trade amount must be between $${MIN_INVESTMENT} and $${MAX_INVESTMENT}`);
            return;
        }

        if (demoBalance < tradeAmount) { alert('Insufficient balance!'); return; }
        if (pendingTrades.size > 0) { alert('Please wait for the current trade to be placed.'); return; }

        const tradeId = Date.now();
        const currentPrice = window.chart?.currentPrice || 0;
        const assetName = document.querySelector('.asset-name')?.textContent || 'USD/BDT (OTC)';

        pendingTrades.set(tradeId, { id: tradeId, type, amount: tradeAmount, price: currentPrice, assetName });

        disableTradeButtons();

        tradeDelayTimeout = setTimeout(() => {
            executePendingTrade(tradeId);
        }, TRADE_DELAY_MS);
    }

    function executePendingTrade(tradeId) {
        const pendingTrade = pendingTrades.get(tradeId);
        if (!pendingTrade) return;

        pendingTrades.delete(tradeId);

        audioManager.playTradePlace();
        demoBalance -= pendingTrade.amount;
        localStorage.setItem('demoBalance', demoBalance);
        updateBalanceDisplay();

        const config = getCurrentConfig();
        showTradeOpenedAlert(pendingTrade.price.toFixed(3), pendingTrade.assetName, config.TRADE_OPENED_DURATION);

        // Save trade payout info to database
        const payoutPercentage = getDynamicPayoutPercentage();
        const tradeDuration = getActualTradeDuration();
        const expiryTime = Date.now() + (tradeDuration * 1000);
        if (window.tradePayoutStorage && payoutPercentage) {
            window.tradePayoutStorage.saveTradeInfo(tradeId, pendingTrade.assetName, payoutPercentage, expiryTime);
            // Schedule deletion 5 seconds after trade expires
            window.tradePayoutStorage.scheduleCleanup(tradeId, expiryTime);
        }

        if (window.chart) window.chart[`place${pendingTrade.type.charAt(0).toUpperCase() + pendingTrade.type.slice(1)}Trade`](pendingTrade.amount, null, pendingTrade.type, pendingTrade.id);

        enableTradeButtons();
        setTimeout(() => updateTabDisplay(), 100);
    }



    function disableTradeButtons() {
        const buttons = [document.querySelector('.upside-btn'), document.querySelector('.downside-btn')];
        buttons.forEach(btn => {
            if (btn) {
                btn.disabled = true;
                // Removed opacity and cursor changes - buttons remain visually normal during delay
            }
        });
    }

    function enableTradeButtons() {
        const buttons = [document.querySelector('.upside-btn'), document.querySelector('.downside-btn')];
        buttons.forEach(btn => {
            if (btn) {
                btn.disabled = false;
                // Removed opacity and cursor changes - buttons remain visually normal
            }
        });
    }


    // New overlay system for trade buttons
    let overlayUpdateInterval = null;
    window.currentOverlayType = null;

    function setupChartOverlay() {
        const upsideBtn = document.querySelector('.upside-btn');
        const downsideBtn = document.querySelector('.downside-btn');
        const overlay = document.getElementById('chart-hover-overlay');

        // Note: Update logic moved to SmoothTradingChart.drawCurrentPriceLine for 60fps sync

        if (upsideBtn && overlay) {
            upsideBtn.addEventListener('mouseenter', () => {
                window.currentOverlayType = 'up';
                // Only set class, position is updated in draw loop
                overlay.className = 'chart-hover-overlay up-overlay';
            });

            upsideBtn.addEventListener('click', () => {
                window.currentOverlayType = null;
                overlay.className = 'chart-hover-overlay';
            });

            upsideBtn.addEventListener('mouseleave', () => {
                window.currentOverlayType = null;
                overlay.className = 'chart-hover-overlay';
            });
        }

        if (downsideBtn && overlay) {
            downsideBtn.addEventListener('mouseenter', () => {
                window.currentOverlayType = 'down';
                overlay.className = 'chart-hover-overlay down-overlay';
            });

            downsideBtn.addEventListener('click', () => {
                window.currentOverlayType = null;
                overlay.className = 'chart-hover-overlay';
            });

            downsideBtn.addEventListener('mouseleave', () => {
                window.currentOverlayType = null;
                overlay.className = 'chart-hover-overlay';
            });
        }
    }

    setupChartOverlay();
    setTimeout(setupChartOverlay, 1000);

    document.querySelector('.upside-btn')?.addEventListener('click', () => placeTrade('up'));
    document.querySelector('.downside-btn')?.addEventListener('click', () => placeTrade('down'));

    setInterval(updateTradeHistoryDisplay, 100);

    window.updateDemoBalance = amount => {
        demoBalance += amount;
        localStorage.setItem('demoBalance', demoBalance);
        updateBalanceDisplay();

        // Update percentage payout if in percentage mode
        if (typeof isPercentageMode !== 'undefined' && isPercentageMode && investmentInput) {
            updatePercentagePayout(percentageAmount);
        }
    };

    // Enhanced chart data storage for Time Jump Controller with user-specific paths
    window.storeChartDatasetPath = function (datasetPath, assetName) {
        if (window.chart) {
            window.chart.currentDatasetPath = datasetPath;

        }

        // Also store in multi-chart manager if available
        if (window.multiChartManager && assetName) {
            const chart = window.multiChartManager.getChart(assetName);
            if (chart) {
                chart.currentDatasetPath = datasetPath;

            }
        }
    };

    // User-specific dataset path detection for chart controls
    window.getUserSpecificDatasetPath = async function (assetName) {
        if (!assetName) return null;

        // Convert asset name to folder format
        let folderName = assetName.toLowerCase().replace(/[^a-z]/g, '');
        // Only add 'otc' suffix if asset name contains '(OTC)'
        if (assetName.includes('(OTC)') && !folderName.endsWith('otc')) {
            folderName += 'otc';
        }

        try {
            // Use PHP endpoint which handles user-specific data paths
            const response = await fetch(`./php/list_datasets.php?asset=${encodeURIComponent(folderName)}`);
            const datasets = await response.json();

            if (datasets && datasets.length > 0) {
                // Use the first dataset (newest due to sorting)
                const latestDataset = datasets[0];

                // Get current user's session info to build correct path
                const sessionResponse = await fetch('./php/session_manager.php', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ action: 'getCurrentUser' })
                });

                let username = 'unrealengine_developer'; // fallback
                try {
                    const sessionData = await sessionResponse.json();
                    if (sessionData.username) {
                        username = sessionData.username;
                    }
                } catch (e) {
                    console.warn('Could not get session info, using fallback username');
                }

                // Build user-specific path
                const path = `./data/${username}/${folderName}/${latestDataset}/candle_data.json`;
                return path;
            }
        } catch (error) {

        }

        return null;
    };

    // Enhanced loadDataset wrapper with user-specific path support
    const originalLoadDataset = window.chart?.loadDataset;
    if (window.chart && originalLoadDataset) {
        window.chart.loadDataset = function (data, sentimentData, datasetPath) {
            // Store raw data and dataset path for Time Jump Controller
            this.rawData = data;
            if (datasetPath) {
                this.currentDatasetPath = datasetPath;
                console.log('✅ Chart loadDataset stored user-specific path:', datasetPath);
            }

            // Call original loadDataset method
            return originalLoadDataset.call(this, data, sentimentData);
        };
    }

    window.addTradeToHistory = addTradeToHistory;

    // Clear chart cache but preserve trade history (user-specific)
    window.clearChartCache = function () {
        // Remove only chart-related localStorage keys
        localStorage.removeItem('tradingChart_state');
        localStorage.removeItem('multiChart_state');

        // Clear user-specific chart data if multi-chart manager exists
        if (window.multiChartManager) {
            window.multiChartManager.destroy();
            window.multiChartManager = new MultiChartManager();
            window.multiChartManager.init();
        }

        // Keep trade history and demo balance
        // localStorage.getItem('tradeHistory') - PRESERVED
        // localStorage.getItem('demoBalance') - PRESERVED
        // localStorage.getItem('tradeCount') - PRESERVED
    };
    // Trade result alert function
    function showTradeResultAlert(result, payout, amount, tradeEndCandleIndex, tradeEndPrice) {
        if (!window.chart) return;

        const chartContainer = document.getElementById('chartContainer');
        if (!chartContainer) return;

        // Calculate trade ending point position
        const a = window.chart.getChartArea();
        const twoCm = 100;
        const startX = a.left + window.chart.panOffset + twoCm;

        // Use trade ending candle index instead of current candle
        const endCandleIndex = tradeEndCandleIndex || window.chart.currentCandleIndex;
        const isOddCandle = (endCandleIndex % 2) === 0;
        const gridIndex = Math.floor(endCandleIndex / 2);
        const tradeEndX = isOddCandle ?
            startX + gridIndex * twoCm :
            startX + gridIndex * twoCm + twoCm / 2;

        // Position alert to the left of the trade ending circle with gap
        const alertWidth = 140;
        const pointerWidth = 8; // Triangle pointer extends 8px beyond alert
        let alertX = tradeEndX - alertWidth - pointerWidth + 12; // Move alert left of circle

        // Ensure alert respects 50px left clipping area
        const minLeftPosition = 50;
        if (alertX < minLeftPosition) {
            alertX = minLeftPosition;
        }

        const tradeEndPriceY = window.chart.priceToY(tradeEndPrice || window.chart.currentPrice);
        const alertY = tradeEndPriceY - 28; // Center alert with trade ending circle (2px up)

        const alertBox = document.createElement('div');
        alertBox.className = `trade-result-alert ${result}`;
        alertBox.style.userSelect = 'none';
        alertBox.style.webkitUserSelect = 'none';
        alertBox.style.left = `${Math.round(alertX)}px`;
        alertBox.style.top = `${Math.round(alertY)}px`;

        let payoutText;
        if (result === 'win' || result === 'refund') {
            payoutText = `+${parseFloat(payout || amount).toFixed(2)} $`;
        } else {
            payoutText = '0.00 $';
        }

        alertBox.innerHTML = `
            <div class="close-btn">×</div>
            <div class="result-title">Result (P/L)</div>
            <div class="payout-amount">${payoutText}</div>
        `;

        chartContainer.appendChild(alertBox);

        // 🔧 DEVELOPMENT CODE (ACTIVE)
        const config = getCurrentConfig();
        if (DEV_MODE) {

        }
        // Store alert reference for synchronized removal
        window.currentTradeResultAlert = alertBox;

        setTimeout(() => {
            if (alertBox.parentNode) {
                alertBox.remove();
            }
            window.currentTradeResultAlert = null;
        }, config.TRADE_RESULT_DURATION);

        // Close button functionality - remove both alert and trade end line
        alertBox.querySelector('.close-btn').addEventListener('click', () => {
            alertBox.remove();
            window.currentTradeResultAlert = null;
            // Remove corresponding trade end line immediately
            if (window.chart && window.chart.expirationEffects) {
                window.chart.expirationEffects = window.chart.expirationEffects.filter(effect =>
                    effect.alertRef !== alertBox
                );
            }
        });
    }

    // Trade opened alert function
    // 🔧 DEVELOPMENT CODE (ACTIVE)
    function showTradeOpenedAlert(price, assetName, duration = getCurrentConfig().TRADE_OPENED_DURATION) {
        const chartContainer = document.getElementById('chartContainer');
        if (!chartContainer) return;

        // Move existing alerts down with proper gap
        const existingAlerts = chartContainer.querySelectorAll('.trade-opened-alert');
        const alertHeight = 35;
        const gap = 10;
        existingAlerts.forEach(alert => {
            // Get current position relative to pair information box
            const pairInfoBox = document.querySelector('.pair-information');
            const pairInfoRect = pairInfoBox ? pairInfoBox.getBoundingClientRect() : null;
            const chartRect = chartContainer.getBoundingClientRect();

            let currentTop;
            if (pairInfoRect && chartRect) {
                const baseTop = (pairInfoRect.bottom - chartRect.top) + 14;
                currentTop = parseInt(alert.style.top) || baseTop;
            } else {
                currentTop = parseInt(alert.style.top) || 94;
            }
            alert.style.top = (currentTop + alertHeight + gap) + 'px';
        });

        const alertBox = document.createElement('div');
        alertBox.className = 'trade-opened-alert';
        alertBox.style.userSelect = 'none';
        alertBox.style.webkitUserSelect = 'none';
        alertBox.dataset.timestamp = Date.now(); // Add timestamp for chronological order
        alertBox.innerHTML = `
            <span>Trade opened with Price: <span class="trade-opened-alert-price-asset-info">${price} ${assetName}</span></span>
            <div class="close-btn"></div>
        `;

        // Get pair information box position and align with it
        const pairInfoBox = document.querySelector('.pair-information');
        const pairInfoRect = pairInfoBox ? pairInfoBox.getBoundingClientRect() : null;
        const chartRect = chartContainer.getBoundingClientRect();

        if (pairInfoRect && chartRect) {
            // Position 14px below pair information box, aligned to its left edge
            const topPosition = (pairInfoRect.bottom - chartRect.top) + 14;
            let leftPosition = pairInfoRect.left - chartRect.left;

            // Ensure alert respects 50px left clipping area
            const minLeftPosition = 50;
            if (leftPosition < minLeftPosition) {
                leftPosition = minLeftPosition;
            }

            alertBox.style.top = topPosition + 'px';
            alertBox.style.left = leftPosition + 'px';
        } else {
            // Fallback positioning - ensure it respects 50px clipping area
            alertBox.style.top = '94px';
            alertBox.style.left = '50px';
        }

        chartContainer.appendChild(alertBox);

        // Close button functionality
        alertBox.querySelector('.close-btn').addEventListener('click', () => {
            // Clear the auto-remove timeout when manually closed
            if (alertBox.timeoutId) {
                clearTimeout(alertBox.timeoutId);
            }

            // Apply slide left animation before removing
            alertBox.style.animation = 'tradeOpenedSlideLeft 0.3s ease-out forwards';
            setTimeout(() => {
                if (alertBox.parentNode) {
                    alertBox.remove();
                    // Reposition remaining alerts with proper gaps
                    const remainingAlerts = chartContainer.querySelectorAll('.trade-opened-alert');
                    const gap = 10;
                    // Reposition remaining alerts relative to pair information box
                    const pairInfoBox = document.querySelector('.pair-information');
                    const pairInfoRect = pairInfoBox ? pairInfoBox.getBoundingClientRect() : null;
                    const chartRect = chartContainer.getBoundingClientRect();

                    if (pairInfoRect && chartRect) {
                        const baseTop = (pairInfoRect.bottom - chartRect.top) + 14;
                        remainingAlerts.forEach((alert, index) => {
                            alert.style.top = (baseTop + index * (35 + gap)) + 'px';
                            // Ensure alert respects 50px left clipping area
                            const currentLeft = parseInt(alert.style.left) || 50;
                            if (currentLeft < 50) {
                                alert.style.left = '50px';
                            }
                        });
                    } else {
                        remainingAlerts.forEach((alert, index) => {
                            alert.style.top = (94 + index * (35 + gap)) + 'px';
                            // Ensure alert respects 50px left clipping area
                            const currentLeft = parseInt(alert.style.left) || 50;
                            if (currentLeft < 50) {
                                alert.style.left = '50px';
                            }
                        });
                    }
                }
            }, 300);
        });

        // Auto remove after specified duration (development mode aware)


        // Store the timeout ID on the alert element for proper cleanup
        const timeoutId = setTimeout(() => {
            if (alertBox && alertBox.parentNode) {
                // Apply slide left animation before removing
                alertBox.style.animation = 'tradeOpenedSlideLeft 0.3s ease-out forwards';
                setTimeout(() => {
                    if (alertBox.parentNode) {
                        alertBox.remove();
                        // Reposition remaining alerts with proper gaps
                        const remainingAlerts = chartContainer.querySelectorAll('.trade-opened-alert');
                        const alertHeight = 35;
                        const gap = 10;
                        // Reposition remaining alerts relative to pair information box
                        const pairInfoBox = document.querySelector('.pair-information');
                        const pairInfoRect = pairInfoBox ? pairInfoBox.getBoundingClientRect() : null;
                        const chartRect = chartContainer.getBoundingClientRect();

                        if (pairInfoRect && chartRect) {
                            const baseTop = (pairInfoRect.bottom - chartRect.top) + 14;
                            remainingAlerts.forEach((alert, index) => {
                                alert.style.top = (baseTop + index * (alertHeight + gap)) + 'px';
                                // Ensure alert respects 50px left clipping area
                                const currentLeft = parseInt(alert.style.left) || 50;
                                if (currentLeft < 50) {
                                    alert.style.left = '50px';
                                }
                            });
                        } else {
                            remainingAlerts.forEach((alert, index) => {
                                alert.style.top = (94 + index * (alertHeight + gap)) + 'px';
                                // Ensure alert respects 50px left clipping area
                                const currentLeft = parseInt(alert.style.left) || 50;
                                if (currentLeft < 50) {
                                    alert.style.left = '50px';
                                }
                            });
                        }
                    }
                }, 300);
            }
        }, duration);

        // Store timeout ID for cleanup if needed
        alertBox.timeoutId = timeoutId;
    }

    // Trade closed alert function
    function showTradeClosedAlert(assetName, duration, payout) {
        const chartContainer = document.getElementById('chartContainer');
        if (!chartContainer) return;

        displayTradeClosedAlert(assetName, duration, payout);
    }

    async function displayTradeClosedAlert(assetName, duration, payout) {
        const chartContainer = document.getElementById('chartContainer');
        if (!chartContainer) return;

        // Move existing alerts up
        const existingAlerts = chartContainer.querySelectorAll('.trade-closed-alert');
        const alertHeight = 70;
        const gap = 8;
        existingAlerts.forEach(alert => {
            const currentBottom = parseInt(alert.style.bottom) || 20;
            alert.style.bottom = (currentBottom + alertHeight + gap) + 'px';
        });

        const alertBox = document.createElement('div');
        alertBox.className = 'trade-closed-alert';

        // Generate flags for trade closed alert
        const flagsHtml = (await generateTradeFlags(assetName)).replace(/trade-history-flag/g, '');

        // Format duration as mm:ss or hh:mm:ss if over 1 hour
        const h = Math.floor(duration / 3600);
        const m = Math.floor((duration % 3600) / 60);
        const s = duration % 60;
        const timeDisplay = h > 0 ?
            `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}` :
            `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;

        // Format asset name using mapping from asset-name-mapping.json
        const formattedAssetName = window.getAlertName ? window.getAlertName(assetName) : (
            assetName.includes('(OTC)') ?
                assetName.replace('(OTC)', '(...') :
                assetName + ' (...'
        );

        // Determine result class based on payout amount
        const payoutAmount = parseFloat(payout);
        const resultClass = payoutAmount > 0 ? 'win' : 'loss';

        alertBox.innerHTML = `
            <div class="close-btn">×</div>
            <div class="first-line">
                <div class="asset-flags">${flagsHtml}</div>
                <span class="trade-alert-asset-name">${formattedAssetName}</span>
                <span class="circle-divider">•</span>
                <span class="duration">${timeDisplay}</span>
            </div>
            <div class="second-line ${resultClass}">${payoutAmount > 0 ? `+${payoutAmount.toFixed(2)}$` : '0.00 $'}</div>
        `;

        // Add close button functionality with animation
        alertBox.querySelector('.close-btn').addEventListener('click', () => {
            // Clear the auto-remove timeout when manually closed
            if (alertBox.autoRemoveTimeoutId) {
                clearTimeout(alertBox.autoRemoveTimeoutId);
            }
            closeTradeAlert(alertBox);
        });

        // Position at bottom left, respecting 50px clipping area
        alertBox.style.bottom = '20px';
        alertBox.style.left = '130px';

        // Ensure alert respects 50px left clipping area
        const minLeftPosition = 50;
        const currentLeft = parseInt(alertBox.style.left);
        if (currentLeft < minLeftPosition) {
            alertBox.style.left = minLeftPosition + 'px';
        }

        chartContainer.appendChild(alertBox);

        // 🔧 DEVELOPMENT CODE (ACTIVE)
        const config = getCurrentConfig();
        if (DEV_MODE) {

        }

        // Store timeout ID for proper cleanup
        const autoRemoveTimeoutId = setTimeout(() => {
            if (alertBox.parentNode) {
                // Add closing animation class
                alertBox.classList.add('closing');

                // Remove element after animation completes
                setTimeout(() => {
                    if (alertBox.parentNode) {
                        alertBox.remove();
                        // Reposition remaining alerts
                        const chartContainer = document.getElementById('chartContainer');
                        if (chartContainer) {
                            const remainingAlerts = chartContainer.querySelectorAll('.trade-closed-alert');
                            const alertHeight = 70;
                            const gap = 8;
                            remainingAlerts.forEach((alert, index) => {
                                alert.style.bottom = (20 + index * (alertHeight + gap)) + 'px';
                                // Ensure alert respects 50px left clipping area
                                const currentLeft = parseInt(alert.style.left) || 50;
                                if (currentLeft < 50) {
                                    alert.style.left = '50px';
                                }
                            });
                        }
                    }
                }, 300); // Match animation duration
            }
        }, config.TRADE_CLOSED_DURATION);

        // Store timeout ID on alert element for cleanup if needed
        alertBox.autoRemoveTimeoutId = autoRemoveTimeoutId;
    }

    // Restore trade closed alerts on page load
    function restoreTradeClosedAlerts() {
        const savedAlerts = JSON.parse(localStorage.getItem('tradeClosedAlerts')) || [];
        savedAlerts.forEach(alert => {
            displayTradeClosedAlert(alert.assetName, alert.duration, alert.payout);
        });
    }

    // Clear old alerts (optional - call when needed)
    function clearTradeClosedAlerts() {
        localStorage.removeItem('tradeClosedAlerts');
    }

    // Helper function to close trade alert with animation
    window.closeTradeAlert = function (alertElement) {
        if (!alertElement || !alertElement.parentNode) return;

        // Add closing animation class
        alertElement.classList.add('closing');

        // Remove element after animation completes
        setTimeout(() => {
            if (alertElement.parentNode) {
                alertElement.remove();
                // Reposition remaining alerts
                const chartContainer = document.getElementById('chartContainer');
                if (chartContainer) {
                    const remainingAlerts = chartContainer.querySelectorAll('.trade-closed-alert');
                    const alertHeight = 70;
                    const gap = 8;
                    remainingAlerts.forEach((alert, index) => {
                        alert.style.bottom = (20 + index * (alertHeight + gap)) + 'px';
                        // Ensure alert respects 50px left clipping area
                        const currentLeft = parseInt(alert.style.left) || 50;
                        if (currentLeft < 50) {
                            alert.style.left = '50px';
                        }
                    });
                }
            }
        }, 300); // Match animation duration
    };

    window.showTradeClosedAlert = showTradeClosedAlert;
    window.showTradeOpenedAlert = showTradeOpenedAlert;
    window.showTradeResultAlert = showTradeResultAlert;
    window.updateTradeHistoryDisplay = updateTradeHistoryDisplay;
    window.updateTabDisplay = updateTabDisplay;
    window.updateAssetDisplay = updateAssetDisplay;
    window.tradeHistory = tradeHistory;

    // Test function to check if flags are in DOM
    window.checkFlags = function () {
        const sidebar = document.querySelector('.asset-header .flag-container');
        const card = document.querySelector('.asset-card-flags');
        console.log('Sidebar flags HTML:', sidebar ? sidebar.innerHTML : 'Not found');
        console.log('Card flags HTML:', card ? card.innerHTML : 'Not found');
    };

    // Panel controls
    document.getElementById('support-link')?.addEventListener('click', function (e) {
        e.stopPropagation();
        document.getElementById('support-panel').classList.toggle('active');
        document.getElementById('more-panel').classList.remove('active');
        document.getElementById('settings-panel').classList.remove('active');
        setTimeout(updatePanelState, 10);
    });

    document.getElementById('settings-link')?.addEventListener('click', function (e) {
        e.stopPropagation();
        document.getElementById('settings-panel').classList.toggle('active');
        document.getElementById('support-panel').classList.remove('active');
        document.getElementById('more-panel').classList.remove('active');
        setTimeout(updatePanelState, 10);
    });

    document.getElementById('more-link')?.addEventListener('click', function (e) {
        e.stopPropagation();
        document.getElementById('more-panel').classList.toggle('active');
        document.getElementById('support-panel').classList.remove('active');
        setTimeout(updatePanelState, 10);
    });

    document.getElementById('close-support')?.addEventListener('click', function () {
        document.getElementById('support-panel').classList.remove('active');
        setTimeout(updatePanelState, 10);
    });

    document.getElementById('close-settings')?.addEventListener('click', function () {
        document.getElementById('settings-panel').classList.remove('active');
        setTimeout(updatePanelState, 10);
    });

    // Verification system
    let currentSection = 0;
    let tapCount = 0;
    let currentOTP = null;
    let otpTimer = null;
    let verificationTimer = null;
    let inactivityTimer = null;
    let timeLeft = 30;
    let sessionTimer = null;
    let isSessionActive = false;
    let sessionTimeLeft = 1800;
    let sessionDisplayTimer = null;
    const SESSION_DURATION = 30 * 60 * 1000;
    const SESSION_KEY = 'signals_session';

    function checkExistingSession() {
        const sessionData = localStorage.getItem(SESSION_KEY);
        if (sessionData) {
            const session = JSON.parse(sessionData);
            const now = Date.now();
            const timeRemaining = session.expiryTime - now;

            if (timeRemaining > 0) {
                isSessionActive = true;
                sessionTimeLeft = Math.floor(timeRemaining / 1000);

                if (session.currentView === 'signals') {
                    navigateToSection(2);
                }

                startSessionDisplayTimer();

                sessionTimer = setTimeout(() => {
                    endAnalyticsSession();
                }, timeRemaining);

                return true;
            } else {
                localStorage.removeItem(SESSION_KEY);
            }
        }
        return false;
    }

    function saveSessionToStorage(currentView = 'signals') {
        const sessionData = {
            startTime: Date.now(),
            expiryTime: Date.now() + SESSION_DURATION,
            currentView: currentView
        };
        localStorage.setItem(SESSION_KEY, JSON.stringify(sessionData));
    }

    function startSessionDisplayTimer() {
        if (sessionDisplayTimer) clearInterval(sessionDisplayTimer);

        sessionDisplayTimer = setInterval(() => {
            sessionTimeLeft--;
            updateSessionTimerDisplay();

            if (sessionTimeLeft <= 0) {
                endAnalyticsSession();
            }
        }, 1000);
    }

    function startAnalyticsSession() {
        if (sessionTimer) clearTimeout(sessionTimer);
        if (sessionDisplayTimer) clearInterval(sessionDisplayTimer);

        isSessionActive = true;
        sessionTimeLeft = 1800;

        saveSessionToStorage('signals');
        startSessionDisplayTimer();

        sessionTimer = setTimeout(() => {
            endAnalyticsSession();
        }, SESSION_DURATION);

        updateSessionTimerDisplay();
    }

    function updateSessionTimerDisplay() {
        const timerElement = document.getElementById('session-timer-value');
        if (timerElement && sessionTimeLeft > 0) {
            const minutes = Math.floor(sessionTimeLeft / 60);
            const seconds = sessionTimeLeft % 60;
            timerElement.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
        }
    }

    function endAnalyticsSession() {
        isSessionActive = false;
        if (sessionTimer) {
            clearTimeout(sessionTimer);
            sessionTimer = null;
        }
        if (sessionDisplayTimer) {
            clearInterval(sessionDisplayTimer);
            sessionDisplayTimer = null;
        }

        localStorage.removeItem(SESSION_KEY);

        const panelContent = document.querySelector('.panel-content');
        panelContent.classList.remove('show-signals');
        panelContent.classList.remove('show-verification');
        navigateToSection(0);
    }

    function navigateToSection(section) {
        const panelContent = document.querySelector('.panel-content');
        currentSection = section;

        panelContent.classList.remove('show-verification', 'show-signals');

        if (section === 1) {
            panelContent.classList.add('show-verification');
            startInactivityTimer();
        } else if (section === 2) {
            panelContent.classList.add('show-signals');
            if (inactivityTimer) clearTimeout(inactivityTimer);
        } else {
            if (inactivityTimer) clearTimeout(inactivityTimer);
        }
    }

    function generateOTP() {
        return Math.floor(100000 + Math.random() * 900000).toString();
    }

    function startOTPTimer() {
        timeLeft = 30;
        const timerElement = document.getElementById('timer');

        otpTimer = setInterval(() => {
            timeLeft--;
            const minutes = Math.floor(timeLeft / 60);
            const seconds = timeLeft % 60;
            timerElement.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;

            if (timeLeft <= 15) {
                timerElement.classList.add('warning');
            }

            if (timeLeft <= 0) {
                clearInterval(otpTimer);
                resetVerification();
            }
        }, 1000);
    }

    function resetVerification() {
        tapCount = 0;
        currentOTP = null;
        if (otpTimer) clearInterval(otpTimer);
        if (verificationTimer) clearInterval(verificationTimer);
        if (inactivityTimer) clearTimeout(inactivityTimer);
        document.getElementById('otp-section').classList.remove('show');
        document.querySelector('.verification-content').classList.remove('slide-up');
        document.querySelectorAll('.otp-input').forEach(input => input.value = '');

        const timerElement = document.getElementById('timer');
        if (timerElement) timerElement.classList.remove('warning');

        const verificationText = document.querySelector('.verification-text');
        verificationText.classList.add('token-mode');

        setTimeout(() => {
            verificationText.textContent = 'Verification Needed';
        }, 400);

        setTimeout(() => {
            verificationText.classList.remove('token-mode');
        }, 800);

        const targetIcon = document.getElementById('target-icon');
        const iconElement = targetIcon.querySelector('i');

        targetIcon.classList.add('password-mode');

        setTimeout(() => {
            iconElement.className = 'fas fa-fingerprint';
        }, 300);

        setTimeout(() => {
            targetIcon.classList.remove('password-mode');
        }, 800);
    }

    function startVerificationTimer() {
        // Auto-revert functionality removed
    }

    function showOTPInputs() {
        if (verificationTimer) clearInterval(verificationTimer);

        const targetIcon = document.getElementById('target-icon');
        const iconElement = targetIcon.querySelector('i');

        targetIcon.classList.add('password-mode');

        setTimeout(() => {
            iconElement.className = 'fas fa-key';
        }, 300);

        const verificationText = document.querySelector('.verification-text');
        verificationText.classList.add('token-mode');

        setTimeout(() => {
            verificationText.textContent = 'Verify the Session Token';
        }, 400);

        setTimeout(() => {
            verificationText.classList.remove('token-mode');
        }, 800);

        document.querySelector('.verification-content').classList.add('slide-up');

        setTimeout(() => {
            document.getElementById('otp-section').classList.add('show');
            document.getElementById('otp1').focus();
            startOTPTimer();
        }, 200);
    }

    function generateOTP() {
        return Math.floor(100000 + Math.random() * 900000).toString();
    }

    function showCustomPopup(message, callback) {
        const existingPopup = document.getElementById('custom-popup');
        if (existingPopup) existingPopup.remove();

        const popup = document.createElement('div');
        popup.id = 'custom-popup';
        popup.innerHTML = `
            <div class="popup-overlay">
                <div class="popup-content">
                    <p>${message}</p>
                    <button class="popup-ok-btn">OK</button>
                </div>
            </div>
        `;

        popup.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 10000;
        `;

        const style = document.createElement('style');
        style.textContent = `
            .popup-overlay {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.5);
                display: flex;
                justify-content: center;
                align-items: center;
            }
            .popup-content {
                background: white;
                padding: 20px;
                border-radius: 8px;
                box-shadow: 0 4px 20px rgba(0,0,0,0.3);
                text-align: center;
                min-width: 300px;
            }
            .popup-content p {
                margin: 0 0 15px 0;
                font-size: 16px;
                color: #333;
            }
            .popup-ok-btn {
                background: #007bff;
                color: white;
                border: none;
                padding: 10px 20px;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
            }
            .popup-ok-btn:hover {
                background: #0056b3;
            }
        `;

        document.head.appendChild(style);
        document.body.appendChild(popup);

        popup.querySelector('.popup-ok-btn').addEventListener('click', () => {
            popup.remove();
            if (callback) callback();
        });
    }

    // Target icon 7-tap functionality
    const targetIcon = document.getElementById('target-icon');

    if (targetIcon) {
        targetIcon.addEventListener('click', function () {
            tapCount++;

            resetInactivityTimer();

            if (window.tapResetTimeout) {
                clearTimeout(window.tapResetTimeout);
            }

            this.style.transform = 'scale(0.95)';
            setTimeout(() => {
                this.style.transform = 'scale(1)';
            }, 100);

            if (tapCount === 7) {
                try {
                    currentOTP = generateOTP();

                    showCustomPopup(`Token Generated: ${currentOTP}`, () => {
                        showOTPInputs();
                    });

                } catch (error) {
                    showCustomPopup('Error generating token!');
                }

                tapCount = 0;
            } else {
                window.tapResetTimeout = setTimeout(() => {
                    if (tapCount < 7 && tapCount > 0) {
                        tapCount = 0;
                    }
                }, 3000);
            }
        });
    }

    // OTP input handling
    document.querySelectorAll('.otp-input').forEach((input, index) => {
        input.addEventListener('input', function () {
            resetInactivityTimer();

            if (this.value.length === 1 && index < 5) {
                document.getElementById(`otp${index + 2}`).focus();
            }

            const allInputs = document.querySelectorAll('.otp-input');
            const enteredOTP = Array.from(allInputs).map(input => input.value).join('');

            if (enteredOTP.length === 6) {
                if (enteredOTP === currentOTP) {
                    allInputs.forEach(input => input.classList.add('success'));

                    setTimeout(() => {
                        clearInterval(otpTimer);
                        const panelContent = document.querySelector('.panel-content');
                        panelContent.classList.remove('show-verification');
                        panelContent.classList.add('show-signals');
                        resetVerification();

                        startAnalyticsSession();
                    }, 500);
                } else {
                    allInputs.forEach(input => {
                        input.value = '';
                        input.style.borderColor = '#ff6b6b';
                    });
                    document.getElementById('otp1').focus();

                    setTimeout(() => {
                        allInputs.forEach(input => {
                            input.style.borderColor = 'rgba(255, 255, 255, 0.3)';
                        });
                    }, 1000);
                }
            }
        });

        input.addEventListener('keydown', function (e) {
            resetInactivityTimer();

            if (e.key === 'Backspace' && this.value === '' && index > 0) {
                document.getElementById(`otp${index}`).focus();
            }
        });

        input.addEventListener('focus', function () {
            resetInactivityTimer();
        });
    });

    document.getElementById('analytics-link')?.addEventListener('click', function (e) {
        e.stopPropagation();
    });

    function startInactivityTimer() {
        // Inactivity timer functionality removed
    }

    function resetInactivityTimer() {
        if (currentSection === 1) {
            startInactivityTimer();
        }
    }

    document.getElementById('signals-link')?.addEventListener('click', function (e) {
        e.stopPropagation();

        if (isSessionActive) {
            navigateToSection(2);
        } else {
            navigateToSection(1);
        }
    });

    document.getElementById('signals-logout')?.addEventListener('click', function () {
        endAnalyticsSession();
        alert('Logged out successfully.');
    });

    const verificationContent = document.querySelector('.verification-content');
    if (verificationContent) {
        verificationContent.addEventListener('mousemove', resetInactivityTimer);
        verificationContent.addEventListener('click', resetInactivityTimer);
    }

    document.getElementById('close-more')?.addEventListener('click', function () {
        resetVerification();
        navigateToSection(0);
        document.getElementById('more-panel').classList.remove('active');
        updatePanelState();
    });

    checkExistingSession();

    // Accordion functionality
    function updateAccordionHeight(accordion) {
        if (accordion && accordion.classList.contains('active')) {
            accordion.style.maxHeight = accordion.scrollHeight + 'px';
        }
    }

    function setupAccordionObserver() {
        const accordions = document.querySelectorAll('.accordion-content');

        accordions.forEach(accordion => {
            const resizeObserver = new ResizeObserver(() => {
                updateAccordionHeight(accordion);
            });

            const mutationObserver = new MutationObserver(() => {
                updateAccordionHeight(accordion);
            });

            resizeObserver.observe(accordion);
            mutationObserver.observe(accordion, {
                childList: true,
                subtree: true,
                attributes: true,
                attributeOldValue: true
            });
        });
    }

    document.querySelectorAll('.accordion-header').forEach(header => {
        header.addEventListener('click', function () {
            const target = this.getAttribute('data-target');
            const content = document.getElementById(target);
            const isActive = content.classList.contains('active');

            document.querySelectorAll('.accordion-header').forEach(otherHeader => {
                if (otherHeader !== this) {
                    const otherTarget = otherHeader.getAttribute('data-target');
                    const otherContent = document.getElementById(otherTarget);
                    otherHeader.classList.remove('active');
                    otherContent.classList.remove('active');
                    otherContent.style.maxHeight = '0';
                }
            });

            if (isActive) {
                this.classList.remove('active');
                content.classList.remove('active');
                content.style.maxHeight = '0';
            } else {
                this.classList.add('active');
                content.classList.add('active');
                if (document.querySelector('.panel-content.show-signals')) {
                    content.style.maxHeight = 'none';
                } else {
                    updateAccordionHeight(content);
                }
            }
        });
    });

    setupAccordionObserver();

    // File Upload Manager
    class FileUploadManager {
        constructor() { }

        async uploadFiles(asset, candleFile, sentimentFile, datasetFolder) {
            try {
                const formData = new FormData();
                formData.append('asset', asset);
                formData.append('candle_data', candleFile);
                formData.append('sentiment_data', sentimentFile);
                formData.append('dataset_folder', datasetFolder);

                const response = await fetch('./php/upload_handler.php', {
                    method: 'POST',
                    body: formData
                });

                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }

                const responseText = await response.text();

                if (responseText.trim().startsWith('{')) {
                    try {
                        return JSON.parse(responseText);
                    } catch (parseError) {
                        return { success: false, message: 'Invalid JSON response from server' };
                    }
                } else {
                    return {
                        success: false,
                        message: `Server returned HTML/text instead of JSON: ${responseText.substring(0, 200)}`
                    };
                }
            } catch (error) {
                return { success: false, message: error.message };
            }
        }

        showMessage(message, type) {
            showCustomPopup(message);
        }
    }

    const uploadManager = new FileUploadManager();

    document.getElementById('upload-data-btn')?.addEventListener('click', async function () {
        const asset = document.getElementById('selected-upload-asset').value;
        const candleFile = document.getElementById('market-data-upload').files[0];
        const sentimentFile = document.getElementById('sentiment-data-upload').files[0];

        if (!asset || !candleFile || !sentimentFile) {
            const statusAlert = document.getElementById('upload-status-alert');
            const statusIcon = document.getElementById('status-icon');
            const statusMessage = document.getElementById('status-message');

            statusAlert.style.display = 'flex';
            statusAlert.className = 'alert alert-error';
            statusIcon.className = 'fas fa-exclamation-circle alert-icon';
            statusMessage.textContent = 'Please select asset and both files';

            setTimeout(() => {
                statusAlert.style.display = 'none';
            }, 3000);
            return;
        }

        if (!candleFile.name.endsWith('.json') || !sentimentFile.name.endsWith('.json')) {
            const statusAlert = document.getElementById('upload-status-alert');
            const statusIcon = document.getElementById('status-icon');
            const statusMessage = document.getElementById('status-message');

            statusAlert.style.display = 'flex';
            statusAlert.className = 'alert alert-error';
            statusIcon.className = 'fas fa-exclamation-circle alert-icon';
            statusMessage.textContent = 'Only JSON files are allowed';

            setTimeout(() => {
                statusAlert.style.display = 'none';
            }, 3000);
            return;
        }

        await processUpload(asset, candleFile, sentimentFile);
    });

    function generateTimestamp() {
        const now = new Date();

        const day = now.getDate().toString().padStart(2, '0');
        const month = (now.getMonth() + 1).toString().padStart(2, '0');
        const year = now.getFullYear().toString().slice(-2);
        const hours = now.getHours().toString().padStart(2, '0');
        const minutes = now.getMinutes().toString().padStart(2, '0');
        const seconds = now.getSeconds().toString().padStart(2, '0');

        return `dataset_${day}-${month}-${year}_${hours}-${minutes}-${seconds}`;
    }

    async function processUpload(asset, candleFile, sentimentFile) {
        const statusAlert = document.getElementById('upload-status-alert');
        const statusIcon = document.getElementById('status-icon');
        const statusMessage = document.getElementById('status-message');
        const timestamp = generateTimestamp();
        const datasetFolder = timestamp;

        statusAlert.style.display = 'flex';
        statusAlert.className = 'alert alert-success';

        statusIcon.className = 'fas fa-search alert-icon';
        statusMessage.textContent = 'Locating data directory...';
        await new Promise(resolve => setTimeout(resolve, 1200));

        statusIcon.className = 'fas fa-check-circle alert-icon';
        statusMessage.textContent = 'Data directory located successfully!';
        await new Promise(resolve => setTimeout(resolve, 1000));

        statusIcon.className = 'fas fa-search alert-icon';
        statusMessage.textContent = `Checking ${asset} asset folder...`;
        await new Promise(resolve => setTimeout(resolve, 1200));

        statusIcon.className = 'fas fa-folder alert-icon';
        statusMessage.textContent = `${asset} asset folder verified!`;
        await new Promise(resolve => setTimeout(resolve, 1000));

        statusIcon.className = 'fas fa-calendar-plus alert-icon';
        statusMessage.textContent = `Creating dataset folder: ${datasetFolder}`;
        await new Promise(resolve => setTimeout(resolve, 1500));

        statusIcon.className = 'fas fa-check-circle alert-icon';
        statusMessage.textContent = 'Timestamped dataset folder created!';
        await new Promise(resolve => setTimeout(resolve, 1000));

        statusIcon.className = 'fas fa-chart-line alert-icon';
        statusMessage.textContent = 'Processing candle data file...';
        await new Promise(resolve => setTimeout(resolve, 1300));

        statusIcon.className = 'fas fa-brain alert-icon';
        statusMessage.textContent = 'Processing sentiment data file...';
        await new Promise(resolve => setTimeout(resolve, 1300));

        statusIcon.className = 'fas fa-cloud-upload-alt alert-icon';
        statusMessage.textContent = 'Finalizing upload to dataset folder...';
        await new Promise(resolve => setTimeout(resolve, 1500));

        try {
            const result = await uploadManager.uploadFiles(asset, candleFile, sentimentFile, datasetFolder);

            if (result.success) {
                statusIcon.className = 'fas fa-check-circle alert-icon';
                statusMessage.textContent = `Upload completed! Dataset: ${datasetFolder}`;

                // Auto-clear disabled - chart progress preserved
                // window.clearChartCache();

                document.getElementById('market-data-upload').value = '';
                document.getElementById('sentiment-data-upload').value = '';
                document.getElementById('market-file-name').textContent = 'No file selected';
                document.getElementById('sentiment-file-name').textContent = 'No file selected';

                setTimeout(() => {
                    statusAlert.style.display = 'none';
                }, 4000);
            } else {
                throw new Error(result.message);
            }
        } catch (error) {
            statusAlert.className = 'alert alert-error';
            statusIcon.className = 'fas fa-exclamation-circle alert-icon';
            statusMessage.textContent = `Upload failed: ${error.message}`;

            setTimeout(() => {
                statusAlert.style.display = 'none';
            }, 5000);
        }
    }

    function setupScrollableContent() {
        const style = document.createElement('style');
        style.textContent = `
            .panel-content.show-signals {
                display: flex;
                flex-direction: column;
                height: calc(100vh - 60px);
                overflow: hidden;
            }
            .signals-main-content {
                flex: 1;
                overflow-y: auto;
                overflow-x: hidden;
                padding: 20px;
                padding-bottom: 10px;
            }
            .signals-footer {
                position: fixed !important;
                bottom: 0 !important;
                // left: 80px !important;
                width: 240px !important;
                background: #2B3040 !important;
                z-index: 1 !important;
                border-top: 1px solid rgba(255, 255, 255, 0.1) !important;
                padding: 15px 20px !important;
                box-sizing: border-box !important;
                margin: 0 !important;
                // position: absolute;
                // bottom: 0;
                // background: #1C1F2D;
                // z-index: 100;
                // border-top: 1px solid rgba(255,255,255,0.1);
                // padding: 15px 20px;
                // margin-top: auto;
            }
            .signals-main-content::-webkit-scrollbar {
                width: 0px;
                background: transparent;
            }
            .signals-main-content {
                scrollbar-width: none;
                -ms-overflow-style: none;
            }
            .accordion-content.active {
                max-height: none !important;
                height: auto;
            }
        `;
        document.head.appendChild(style);

        const signalsSection = document.querySelector('.signals-section');
        if (signalsSection && !signalsSection.querySelector('.signals-main-content')) {
            const content = signalsSection.innerHTML;
            signalsSection.innerHTML = `
                <div class="signals-main-content">
                    ${content}
                </div>
                <div class="signals-footer">
                    <button id="signals-logout" class="logout-btn">Logout</button>
                </div>
            `;
        }
    }

    setupScrollableContent();

    document.getElementById('market-data-upload')?.addEventListener('change', function (e) {
        const fileName = e.target.files[0]?.name || 'No file selected';
        document.getElementById('market-file-name').textContent = fileName;
    });

    document.getElementById('sentiment-data-upload')?.addEventListener('change', function (e) {
        const fileName = e.target.files[0]?.name || 'No file selected';
        document.getElementById('sentiment-file-name').textContent = fileName;
    });

    const firstAccordion = document.getElementById('data-upload');
    if (firstAccordion && firstAccordion.classList.contains('active')) {
        firstAccordion.style.maxHeight = firstAccordion.scrollHeight + 'px';
    }

    setTimeout(() => {
        if (window.calculateExactPayout && window.getDynamicPayoutMultiplier) {
            const payoutElement = document.querySelector('.payout-info');
            if (payoutElement) {
                const exactPayout = window.calculateExactPayout(1);
                payoutElement.textContent = `Your payout: ${exactPayout} $`;
            }
        }
    }, 500);

    // Asset availability check with user-specific dataset validation
    async function handleAssetClick(assetName) {
        const chartContainer = document.getElementById('chartContainer');
        const notAvailableContent = document.getElementById('notAvailableContent');
        const assetNamePlaceholder = document.getElementById('assetNamePlaceholder');

        // Check if asset has active dataset using user-specific paths
        const hasActiveDataset = await checkAssetDataset(assetName);

        if (hasActiveDataset) {
            // Hide not available content and show chart
            if (notAvailableContent) {
                notAvailableContent.style.display = 'none';
            }

            let canvas = chartContainer.querySelector('#chartCanvas');
            if (!canvas) {
                const existingContent = chartContainer.innerHTML;
                chartContainer.innerHTML = existingContent.replace(/<canvas[^>]*><\/canvas>/, '') + '<canvas id="chartCanvas"></canvas>';
                canvas = document.getElementById('chartCanvas');
            }

            if (window.chart) {
                window.chart.canvas = canvas;
                window.chart.ctx = canvas.getContext('2d');
                window.chart.setupCanvas();
            }
        } else {
            // Hide any existing loader and show not available content immediately
            const loader = chartContainer.querySelector('.chart-loader');
            if (loader) {
                loader.remove();
            }

            if (assetNamePlaceholder) {
                assetNamePlaceholder.textContent = assetName;
            }
            if (notAvailableContent) {
                notAvailableContent.style.display = 'flex';
            }
        }
    }

    // Check if asset has active dataset using user-specific paths
    async function checkAssetDataset(assetName) {
        try {
            const datasetPath = await window.getUserSpecificDatasetPath(assetName);
            return datasetPath !== null;
        } catch (error) {
            console.error('Error checking asset dataset:', error);
            return false;
        }
    }

    // Asset management
    let assetsToRemove = [];
    const ASSETS_STORAGE_KEY = 'trading_assets';

    function loadAssets() {
        const savedAssets = sessionStorage.getItem(ASSETS_STORAGE_KEY);
        if (savedAssets) {
            const assets = JSON.parse(savedAssets);
            const select = document.getElementById('asset-select');
            while (select.options.length > 1) {
                select.removeChild(select.lastChild);
            }
            assets.forEach(asset => {
                const option = document.createElement('option');
                option.value = asset.value;
                option.textContent = asset.text;
                select.appendChild(option);
            });
        }
    }

    function saveAssets() {
        const select = document.getElementById('asset-select');
        const assets = [];
        for (let i = 1; i < select.options.length; i++) {
            const option = select.options[i];
            assets.push({
                value: option.value,
                text: option.textContent
            });
        }
        sessionStorage.setItem(ASSETS_STORAGE_KEY, JSON.stringify(assets));
    }

    document.getElementById('add-asset-radio')?.addEventListener('click', function () {
        if (this.checked && this.dataset.wasChecked === 'true') {
            this.checked = false;
            this.dataset.wasChecked = 'false';
            document.getElementById('add-asset-section').style.display = 'none';
        } else {
            this.dataset.wasChecked = 'true';
            document.getElementById('remove-asset-radio').checked = false;
            document.getElementById('remove-asset-radio').dataset.wasChecked = 'false';
            document.getElementById('add-asset-section').style.display = 'block';
            document.getElementById('remove-asset-section').style.display = 'none';
        }
        updateAccordionHeight();
    });

    document.getElementById('remove-asset-radio')?.addEventListener('click', function () {
        if (this.checked && this.dataset.wasChecked === 'true') {
            this.checked = false;
            this.dataset.wasChecked = 'false';
            document.getElementById('remove-asset-section').style.display = 'none';
        } else {
            this.dataset.wasChecked = 'true';
            document.getElementById('add-asset-radio').checked = false;
            document.getElementById('add-asset-radio').dataset.wasChecked = 'false';
            document.getElementById('add-asset-section').style.display = 'none';
            document.getElementById('remove-asset-section').style.display = 'block';
            populateRemoveAssetList();
        }
        updateAccordionHeight();
    });

    window.updateAccordionHeight = function (accordionId) {
        const accordion = accordionId ? document.getElementById(accordionId) : document.getElementById('data-upload');
        if (accordion && accordion.classList.contains('active')) {
            accordion.style.maxHeight = accordion.scrollHeight + 'px';
        }
    };

    function populateRemoveAssetList() {
        const select = document.getElementById('asset-select');
        const list = document.getElementById('remove-dropdown-list');
        list.innerHTML = '';
        assetsToRemove = [];

        for (let i = 1; i < select.options.length; i++) {
            const option = select.options[i];
            const assetItem = document.createElement('div');
            assetItem.className = 'asset-item';
            assetItem.innerHTML = `
                <span>${option.textContent}</span>
                <span class="remove-asset-cross" data-value="${option.value}">×</span>
            `;
            list.appendChild(assetItem);
        }

        list.querySelectorAll('.remove-asset-cross').forEach(cross => {
            cross.addEventListener('click', function () {
                const assetValue = this.getAttribute('data-value');
                const assetItem = this.parentElement;

                if (assetsToRemove.includes(assetValue)) {
                    assetsToRemove = assetsToRemove.filter(v => v !== assetValue);
                    assetItem.classList.remove('marked-for-removal');
                } else {
                    assetsToRemove.push(assetValue);
                    assetItem.classList.add('marked-for-removal');
                }
            });
        });
    }

    document.getElementById('remove-dropdown-header')?.addEventListener('click', function () {
        const dropdownList = document.getElementById('remove-dropdown-list');
        const arrow = this.querySelector('.dropdown-arrow');

        if (dropdownList.style.display === 'none') {
            dropdownList.style.display = 'block';
            arrow.classList.add('rotated');
        } else {
            dropdownList.style.display = 'none';
            arrow.classList.remove('rotated');
        }
        updateAccordionHeight();
    });

    document.getElementById('add-asset-btn')?.addEventListener('click', function () {
        const input = document.getElementById('asset-name-input');
        const select = document.getElementById('asset-select');
        const assetName = input.value.trim();

        if (assetName) {
            const option = document.createElement('option');
            option.value = assetName.toLowerCase().replace(/[^a-z0-9]/g, '');
            option.textContent = assetName;
            select.appendChild(option);

            saveAssets();

            input.value = '';
            document.getElementById('add-asset-radio').checked = false;
            document.getElementById('add-asset-section').style.display = 'none';
            updateAccordionHeight();
        }
    });

    document.getElementById('update-asset-btn')?.addEventListener('click', function () {
        const select = document.getElementById('asset-select');

        assetsToRemove.forEach(assetValue => {
            const option = select.querySelector(`option[value="${assetValue}"]`);
            if (option) {
                option.remove();
            }
        });

        saveAssets();

        assetsToRemove = [];
        document.getElementById('remove-asset-radio').checked = false;
        document.getElementById('remove-asset-section').style.display = 'none';
        document.getElementById('remove-dropdown-list').style.display = 'none';
        document.querySelector('.dropdown-arrow').classList.remove('rotated');
        updateAccordionHeight();
    });

    document.getElementById('asset-name-input')?.addEventListener('keypress', function (e) {
        if (e.key === 'Enter') {
            document.getElementById('add-asset-btn').click();
        }
    });

    // Function to add caret icon to asset card labels
    function addCaretIconToAssetCards() {
        const assetCards = document.querySelectorAll('.asset-card-tab');
        assetCards.forEach(card => {
            const label = card.querySelector('.asset-card-label');
            if (label && !label.querySelector('.icon-caret')) {
                // Create caret icon
                const caretIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                caretIcon.setAttribute('class', 'icon-caret');
                caretIcon.setAttribute('width', '9');
                caretIcon.setAttribute('height', '6');

                const useElement = document.createElementNS('http://www.w3.org/2000/svg', 'use');
                useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', './svg/spritemap.svg#icon-caret');
                caretIcon.appendChild(useElement);

                // Add caret icon to the label
                label.appendChild(caretIcon);
            }
        });
    }

    // Function to update active asset card with caret icon
    function updateActiveAssetCard(activeAssetName) {
        const assetCards = document.querySelectorAll('.asset-card-tab');
        assetCards.forEach(card => {
            const label = card.querySelector('.asset-card-label');
            if (label) {
                const assetName = label.textContent.trim();
                if (assetName === activeAssetName) {
                    card.classList.add('active');
                } else {
                    card.classList.remove('active');
                }
            }
        });
    }

    // Observer to watch for new asset cards being added
    const assetCardObserver = new MutationObserver(function (mutations) {
        mutations.forEach(function (mutation) {
            if (mutation.type === 'childList') {
                mutation.addedNodes.forEach(function (node) {
                    if (node.nodeType === Node.ELEMENT_NODE) {
                        if (node.classList && node.classList.contains('asset-card-tab')) {
                            // New asset card added, add caret icon
                            setTimeout(() => addCaretIconToAssetCards(), 100);
                        } else if (node.querySelector && node.querySelector('.asset-card-tab')) {
                            // Container with asset cards added
                            setTimeout(() => addCaretIconToAssetCards(), 100);
                        }
                    }
                });
            }
        });
    });

    // Start observing the asset card container
    const assetCardContainer = document.querySelector('.asset-card-items');
    if (assetCardContainer) {
        assetCardObserver.observe(assetCardContainer, {
            childList: true,
            subtree: true
        });
    }

    // Also observe the main trading chart assets container
    const tradingChartAssets = document.querySelector('.trading-chart__assets');
    if (tradingChartAssets) {
        assetCardObserver.observe(tradingChartAssets, {
            childList: true,
            subtree: true
        });
    }

    // Initial check for existing asset cards
    setTimeout(() => addCaretIconToAssetCards(), 1000);

    // Add click listeners to asset cards - integrated with multi-chart manager
    document.addEventListener('click', function (e) {
        const assetCard = e.target.closest('.asset-card-tab');
        if (assetCard) {
            const assetName = assetCard.querySelector('.asset-card-label')?.textContent;
            if (assetName) {


                // Update active asset card
                updateActiveAssetCard(assetName);

                // Set transition state for time display controller
                if (window.timeDisplayController) {
                    window.timeDisplayController.setTransition(1500);
                }

                isAssetSwitching = true;
                setTimeout(() => {
                    isAssetSwitching = false;
                }, 1000);

                // Multi-chart manager handles everything in multi-chart mode
                if (window.multiChartManager && window.multiChartManager.isInitialized) {
                    // Let multi-chart manager handle asset switching and display updates
                    return;
                }

                // Fallback for single-chart mode only
                updateAssetDisplay(assetName);
                checkAssetDataset(assetName).then(hasActiveDataset => {
                    if (hasActiveDataset && window.chart) {
                        window.chart.showLoader();

                        if (window.chartPersistenceManager) {
                            window.chartPersistenceManager.clearManualStop();
                        }
                    }

                    handleAssetClick(assetName);
                });
            }
        }
    });

    loadAssets();

    // Account dropdown
    const accountBtn = document.getElementById('account-btn');
    const accountDropdown = document.getElementById('account-dropdown');
    const accountArrow = accountBtn?.querySelector('.account-arrow');

    accountBtn?.addEventListener('click', function (e) {
        e.stopPropagation();
        accountDropdown.classList.toggle('active');
        accountArrow.classList.toggle('flipped');
        document.getElementById('notification-modal').classList.remove('active');
    });

    // Prevent dropdown from closing when clicking inside it
    accountDropdown?.addEventListener('click', function (e) {
        e.stopPropagation();
    });

    const editButton = document.querySelector('.select-balance-edit');
    const confirmButton = document.querySelector('.select-balance-edit-button');
    const balanceInput = document.querySelector('.input-control__input');
    const refreshButton = document.querySelector('.select-refresh');

    editButton?.addEventListener('click', function (e) {
        e.stopPropagation();
        balanceInput?.focus();
    });

    confirmButton?.addEventListener('click', function (e) {
        e.stopPropagation();
        const newBalance = parseFloat(balanceInput?.value) || 10000;
        demoBalance = newBalance;
        localStorage.setItem('demoBalance', demoBalance);
        updateBalanceDisplay();

        const selectBalance = document.querySelector('.select-balance');
        if (selectBalance) {
            const formattedBalance = newBalance.toFixed(2);
            selectBalance.textContent = `$${formattedBalance}`;
        }
    });

    refreshButton?.addEventListener('click', function (e) {
        e.stopPropagation();
        demoBalance = 10000;
        localStorage.setItem('demoBalance', demoBalance);
        updateBalanceDisplay();

        const selectBalance = document.querySelector('.select-balance');
        if (selectBalance) {
            selectBalance.textContent = '$10000.00';
        }

        if (balanceInput) {
            balanceInput.value = '10000';
        }
    });

    const liveAccountRadio = document.getElementById('live-account');
    const demoAccountRadio = document.getElementById('demo-account');

    liveAccountRadio?.addEventListener('change', function () {
        if (this.checked) {
            document.querySelector('.account-select-item-radio.active')?.classList.remove('active');
            this.closest('.account-select-item-radio').classList.add('active');
        }
    });

    demoAccountRadio?.addEventListener('change', function () {
        if (this.checked) {
            document.querySelector('.account-select-item-radio.active')?.classList.remove('active');
            this.closest('.account-select-item-radio').classList.add('active');
        }
    });

    document.addEventListener('click', function (e) {
        if (!accountBtn?.contains(e.target) && !accountDropdown?.contains(e.target)) {
            accountDropdown?.classList.remove('active');
            accountArrow?.classList.remove('flipped');
        }
    });

    document.getElementById('notification-btn')?.addEventListener('click', function (e) {
        e.stopPropagation();
        document.getElementById('notification-modal').classList.toggle('active');
        accountDropdown?.classList.remove('active');
        accountArrow?.classList.remove('flipped');
    });

    function updatePanelState() {
        const appContainer = document.querySelector('.app-container');
        const hasActivePanel = document.querySelector('.side-panel.active') || document.querySelector('.setting-panel.active');
        const mainContent = document.querySelector('.main-content');

        if (hasActivePanel) {
            appContainer.classList.add('panel-active');
            if (mainContent) {
                mainContent.style.transition = 'transform 0.3s ease';
                mainContent.style.transform = 'translateX(300px)';
            }
        } else {
            appContainer.classList.remove('panel-active');
            if (mainContent) {
                mainContent.style.transform = 'translateX(0)';
            }
        }

        // Adjust chart container width and resize
        const chartContainer = document.getElementById('chartContainer');
        if (chartContainer) {
            if (hasActivePanel) {
                chartContainer.style.width = 'calc(100vw - 650px)';
            } else {
                chartContainer.style.width = '';
                chartContainer.style.removeProperty('width');
            }
        }

        // Resize chart when panel state changes
        if (window.chart) {
            setTimeout(() => {
                window.chart.setupCanvas();
            }, 350);
        }
    }

    initializeTabs();

    // Make functions globally available for other scripts
    window.addCaretIconToAssetCards = addCaretIconToAssetCards;
    window.updateActiveAssetCard = updateActiveAssetCard;

    // Watch for panel state changes
    const observer = new MutationObserver(() => {
        updatePanelState();
    });

    const supportPanel = document.getElementById('support-panel');
    const morePanel = document.getElementById('more-panel');
    const settingsPanel = document.getElementById('settings-panel');

    if (supportPanel) observer.observe(supportPanel, { attributes: true, attributeFilter: ['class'] });
    if (morePanel) observer.observe(morePanel, { attributes: true, attributeFilter: ['class'] });
    if (settingsPanel) observer.observe(settingsPanel, { attributes: true, attributeFilter: ['class'] });

    // Add tournament alert badge
    const tournamentLink = document.querySelector('a[href="#tournament"]');
    if (tournamentLink && !tournamentLink.querySelector('.tournament-alert')) {
        const alertBadge = document.createElement('div');
        alertBadge.className = 'tournament-alert';
        alertBadge.textContent = '4';
        tournamentLink.style.position = 'relative';
        tournamentLink.appendChild(alertBadge);
    }



    // Account level icon management
    function updateAccountLevelIcon() {
        const accountBalanceElement = document.getElementById('account-balance');
        const accountLevelIcon = document.getElementById('account-level-icon');
        const accountType = document.querySelector('.account-type');

        if (!accountBalanceElement || !accountLevelIcon || !accountType) return;

        // Only update for live accounts
        if (accountType.textContent.includes('LIVE')) {
            const balanceText = accountBalanceElement.textContent;
            const balance = parseFloat(balanceText.replace(/[$,]/g, ''));

            let iconHref;
            if (balance >= 10000) {
                iconHref = './svg/spritemap.svg#icon-profile-level-vip';
            } else if (balance >= 5000) {
                iconHref = './svg/spritemap.svg#icon-profile-level-pro';
            } else {
                iconHref = './svg/spritemap.svg#icon-profile-level-standart';
            }

            accountLevelIcon.querySelector('use').setAttribute('xlink:href', iconHref);
        }
    }

    // Initialize on page load
    document.addEventListener('DOMContentLoaded', updateAccountLevelIcon);

    // Update every second
    setInterval(updateAccountLevelIcon, 1000);

    // Timeframe popover functionality
    const timeframeButton = document.querySelector('.timeframe-button');
    const timeframePopover = document.querySelector('.popover-select__settings-timeframe');
    let isTimeframePopoverOpen = false;

    timeframeButton?.addEventListener('click', function (e) {
        e.stopPropagation();

        if (isTimeframePopoverOpen) {
            timeframePopover.classList.remove('show');
            isTimeframePopoverOpen = false;
        } else {
            timeframePopover.classList.add('show');
            isTimeframePopoverOpen = true;
        }
    });

    document.querySelectorAll('.timeframe-item').forEach(item => {
        item.addEventListener('click', function (e) {
            e.stopPropagation();

            const timeframe = this.getAttribute('data-value');

            document.querySelectorAll('.timeframe-item').forEach(i => i.classList.remove('active'));
            this.classList.add('active');

            timeframeButton.childNodes[0].textContent = timeframe;

            if (window.chart) {
                window.chart.setTimeframe(timeframe);
            }

            timeframePopover.classList.remove('show');
            isTimeframePopoverOpen = false;
        });
    });

    document.addEventListener('click', function (e) {
        if (!timeframeButton.contains(e.target) && !timeframePopover.contains(e.target)) {
            timeframePopover.classList.remove('show');
            isTimeframePopoverOpen = false;
        }
    });

    // Shutter control
    document.getElementById('shutter-control')?.addEventListener('click', function () {
        const tabsContainer = document.querySelector('.tabs-container');
        const shutterIcon = document.getElementById('shutter-icon');

        tabsContainer.classList.toggle('collapsed');
        shutterIcon.classList.toggle('collapsed');
    });

    // Chart control buttons functionality with user-specific data paths
    document.getElementById('chart-play-btn')?.addEventListener('click', function () {

        if (window.multiChartManager && window.multiChartManager.isInitialized && window.multiChartManager.activeAsset) {

            window.multiChartManager.startChart(window.multiChartManager.activeAsset);
        } else if (window.chart) {

            window.chart.startAnimation();
            if (window.chartPersistenceManager) {
                window.chartPersistenceManager.startChart();
            }
        } else {

        }

        // Update time jump controller after chart starts
        setTimeout(() => {

            if (window.timeJumpController) {
                window.timeJumpController.updateTimeRange();
            }
        }, 2000);
    });

    document.getElementById('chart-pause-btn')?.addEventListener('click', function () {

        if (window.multiChartManager && window.multiChartManager.isInitialized && window.multiChartManager.activeAsset) {

            window.multiChartManager.stopChart(window.multiChartManager.activeAsset);
        } else if (window.chart) {

            window.chart.stopAnimation();
            if (window.chartPersistenceManager) {
                window.chartPersistenceManager.stopChart();
            }
        } else {

        }
    });

    document.getElementById('chart-reset-btn')?.addEventListener('click', async function () {

        if (window.multiChartManager && window.multiChartManager.isInitialized && window.multiChartManager.activeAsset) {

            await window.multiChartManager.resetChart(window.multiChartManager.activeAsset);
        } else if (window.chart) {

            window.chart.restart();
            if (window.chartPersistenceManager) {
                window.chartPersistenceManager.clearManualStop();
            }
        } else {

        }

        // Update time jump controller after reset
        setTimeout(() => {

            if (window.timeJumpController) {
                window.timeJumpController.updateTimeRange();
            }
        }, 2000);
    });

    document.getElementById('chart-build-all-btn')?.addEventListener('click', async function () {

        if (window.multiChartManager && window.multiChartManager.isInitialized && window.multiChartManager.activeAsset) {

            await window.multiChartManager.buildAllChart(window.multiChartManager.activeAsset);
        } else if (window.chart) {

            window.chart.buildAllCandles();
            if (window.chartPersistenceManager) {
                window.chartPersistenceManager.markManualStop();
            }
        } else {

        }

        // Update time jump controller after build all
        setTimeout(() => {

            if (window.timeJumpController) {
                window.timeJumpController.updateTimeRange();
            }
        }, 1000);
    });

    // Data reset button functionality
    document.getElementById('data-reset-btn')?.addEventListener('click', async function () {


        const resetAlert = document.getElementById('data-reset-alert');
        const resetIcon = document.getElementById('reset-status-icon');
        const resetMessage = document.getElementById('reset-status-message');

        // Show processing alert
        resetAlert.style.display = 'flex';
        resetAlert.className = 'alert alert-success';
        resetIcon.className = 'fas fa-spinner fa-spin alert-icon';
        resetMessage.textContent = 'Deleting data folder...';

        try {
            const response = await fetch('./php/delete_data_handler.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                }
            });

            const result = await response.json();

            if (result.success) {
                resetIcon.className = 'fas fa-check-circle alert-icon';
                resetMessage.textContent = 'Data folder deleted successfully!';

                // Clear chart cache but preserve trade history
                window.clearChartCache();

                setTimeout(() => {
                    resetAlert.style.display = 'none';
                }, 3000);
            } else {
                resetAlert.className = 'alert alert-error';
                resetIcon.className = 'fas fa-exclamation-circle alert-icon';
                resetMessage.textContent = `Error: ${result.message}`;

                setTimeout(() => {
                    resetAlert.style.display = 'none';
                }, 5000);
            }
        } catch (error) {
            resetAlert.className = 'alert alert-error';
            resetIcon.className = 'fas fa-exclamation-circle alert-icon';
            resetMessage.textContent = `Network error: ${error.message}`;

            setTimeout(() => {
                resetAlert.style.display = 'none';
            }, 5000);
        }
    });

    // Fullscreen toggle
    document.querySelector('.icon-settings-full-screen')?.parentElement.addEventListener('click', function () {
        if (!document.fullscreenElement) {
            document.documentElement.requestFullscreen();
        } else {
            document.exitFullscreen();
        }
    });
});

// Chart JavaScript 
class SmoothTradingChart {
    constructor(canvasId) {
        this.canvas = document.getElementById(canvasId);
        this.ctx = this.canvas.getContext('2d');
        this.setupCanvas();

        this.config = {
            candleWidth: 48,
            candleGap: 41,
            visibleCandles: 12,
            // Candle base Colors
            colors: {
                up: '#0FA054',
                down: '#E75B4D',
                grid: '#3a4553',
                crosshair: '#FFFFFF',
                currentPriceLine: 'rgba(255,255,255,0.6)',
                bg: '#1C1F2D',
                text: '#e0e0e0'
            },
            crosshairWidth: 1,
            padding: { top: 0, right: 55, bottom: 30, left: 0 },
            animation: {
                duration: 1000,
                easing: t => (t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2)
            }
        };

        this.rawData = [];
        this.candleData = [];
        this.currentCandleIndex = 0;
        this.currentSecondIndex = 0;

        // Market reversal detection
        this.reversalBoxes = [];
        this.lastReversalCheck = -1;

        // Dynamic high/low detection - updates on every frame for instant response
        // Removed setInterval - now called directly in draw() method for real-time updates

        // Market reversal detection
        this.reversalBoxes = [];
        this.pendingReversals = [];
        this.confirmationCandles = 3;
        this.currentPrice = 0;
        this.targetPrice = 0;
        this.animationStart = 0;
        this.isAnimating = false;
        this.isPlaying = false;
        this.animationInterval = null;
        this.currentTimeframe = '1m';
        this.timeframeIntervals = {
            '5s': 5, '10s': 10, '15s': 15, '30s': 30, '1m': 60, '2m': 120, '3m': 180, '5m': 300,
            '10m': 600, '15m': 900, '30m': 1800, '1h': 3600, '4h': 14400, '1d': 86400
        };
        this.candleStartTime = Date.now();
        this.currentCandleElapsed = 0;

        this.hoveredCandle = null;
        this.mouseX = 0;
        this.mouseY = 0;
        this.showCrosshair = false;
        this.isHoveringReversalBox = false;
        this.isDragging = false;
        this.panOffset = 0;
        this.zoom = 1;
        this.userDraggedAway = false;


        this.tradelines = [];

        // Initialize with default intervals - will be updated based on asset
        this.minInterval = 0.020;
        this.maxInterval = 0.050;
        this.currentInterval = 0.020;
        this.priceWindowBase = 110900;
        this.priceLineCount = 7;
        this.optimalMaxLines = 10;
        this.maxPriceLines = 10;
        this.slidingAnimation = { offset: 0, target: 0, speed: 0.15 };
        this.priceAxisLines = [];
        this.topMargin = 100;
        this.bottomMargin = 20;
        this.priceGridBase = null;
        this.animatedPriceLines = new Map();
        this.animatedVerticalLines = new Map();

        this.runningHigh = null;
        this.runningLow = null;
        this.currentCandleLines = {
            high: { current: 0, target: 0, visible: false },
            low: { current: 0, target: 0, visible: false },
            close: { current: 0, target: 0 }
        };

        this.isViewingHistorical = false;
        this.realStartTime = Date.now();
        this.lastUpdateTime = Date.now();
        this.storageKey = 'tradingChart_state';

        // Asset switching freeze state
        this.isFrozen = false;
        this.frozenCanvasData = null;

        // Page Visibility API - Tab switching fix
        this.backgroundPauseTime = null;
        this.setupVisibilityHandler();

        this.initializeData();
        this.setupEventListeners();
        this.setupTradeButtonListeners();
        this.startRenderLoop();
    }

    checkForReversals() {
        // Use dynamic high/low detection
        if (this.updateHighLowBoxes) {
            this.updateHighLowBoxes();
        }
    }

    formatPrice(price, tickSize = null) {
        // Get asset-specific configuration
        const assetConfig = this.getAssetConfig();
        if (assetConfig) {
            return parseFloat(price).toFixed(assetConfig.decimalPoints);
        }

        // Fallback to original logic
        if (!tickSize) {
            const range = this.getPriceRange();
            tickSize = range.tickSize;
        }

        const factor = Math.pow(10, 6);
        const scaledPrice = Math.round(price * factor);
        const scaledTick = Math.round(tickSize * factor);
        const rounded = Math.round(scaledPrice / scaledTick) * scaledTick;
        const result = rounded / factor;

        return result.toFixed(3);
    }

    setupCanvas() {
        const container = document.getElementById('chartContainer');
        this.canvas.width = container.clientWidth;
        this.canvas.height = container.clientHeight;
        this.canvas.style.width = container.clientWidth + 'px';
        this.canvas.style.height = container.clientHeight + 'px';
        this.ctx.setTransform(1, 0, 0, 1, 0, 0);
    }

    getAssetConfig() {
        // Get current asset name from UI or chart instance
        const assetName = this.assetName || document.querySelector('.asset-name')?.textContent;
        if (!assetName) return null;

        // Use global getAssetConfig function from price-interval.js
        if (typeof getAssetConfig === 'function') {
            const config = getAssetConfig(assetName);
            if (config) {

                return config;
            }
        }


        return null;
    }





    showLoader() {
        const container = document.getElementById('chartContainer');
        if (!container || container.querySelector('.chart-loader')) return;

        // Freeze chart before showing loader
        this.freezeChart();

        const loader = document.createElement('div');
        loader.className = 'chart-loader';
        loader.innerHTML = '<img src="./img/loading.gif" class="chart-loader-gif" alt="Loading...">';
        container.appendChild(loader);

        this.loaderStartTime = Date.now();
    }

    hideLoader() {
        const minDisplayTime = 3000;

        // Ensure chart loader completes EXACTLY at 8 seconds from page load (5s skeleton + 3s loader)
        const timeSincePageLoad = Date.now() - (window.pageLoadTime || Date.now());
        const remainingTo8Sec = Math.max(0, 8000 - timeSincePageLoad);

        const elapsed = Date.now() - (this.loaderStartTime || 0);
        const standardDelay = Math.max(0, minDisplayTime - elapsed);

        // Use the longer delay to strictly enforce the 8-second initial sequence
        const delay = Math.max(remainingTo8Sec, standardDelay);

        setTimeout(() => {
            const container = document.getElementById('chartContainer');
            const loader = container?.querySelector('.chart-loader');
            if (loader) loader.remove();

            // Unfreeze chart after loader is hidden
            this.unfreezeChart();
        }, delay);
    }

    async initializeData() {
        return this.hasValidData();
    }

    hasValidData() {
        return this.rawData && this.rawData.length > 0 &&
            this.rawData.every(item => item.time && item.price && !isNaN(item.price));
    }

    loadDataset(candleData, sentimentData) {
        this.showLoader();

        // 🚀 ANIMATION FIX: Force algorithm to snap instantly to the new market price 
        // instead of sliding from 0 or the previous asset's price.
        // It perfectly preserves all smooth breathing micro-animations for live market movements!
        if (this.visibleZone) {
            this.visibleZone.isInitialized = false;
        }
        this.priceGridBase = null;

        this.rawData = candleData.map(item => ({
            time: parseInt(item.time),
            price: parseFloat(item.price)
        })).filter(item => !isNaN(item.price) && item.price > 0);

        if (!this.hasValidData()) {
            this.hideLoader();
            return false;
        }

        // Update intervals based on asset configuration
        this.updateAssetIntervals();

        // Force re-initialization of price window with new intervals
        this.forceUpdatePriceRange();

        this.processCandleData();

        // 🚀 LIVE EDGE TARGETING: Skip historical replay and jump instantly to the active market edge
        this.currentCandleIndex = Math.max(0, this.candleData.length - 1);
        this.currentCandleElapsed = 0;

        // Mark all past candles as permanently completed history so they can be dragged back into view
        this.candleData.forEach((candle, index) => {
            candle.isComplete = (index < this.currentCandleIndex);
        });

        // Initialize current price using the newest live tick, not the oldest historical tick
        const newestTick = this.rawData[this.rawData.length - 1] || this.rawData[0];
        this.currentPrice = newestTick ? newestTick.price : 0;
        this.targetPrice = newestTick ? newestTick.price : 0;

        // Flag the camera to natively calculate its center on the first valid CSS paint frame
        // This solves cross-axis initialization glitches where 0-width breaks Y-axis scaling
        this.needsInitialPan = true;
        this.initializePriceWindow();
        this._initRunningExtremes();
        this.updateDisplays();
        this.updateCurrentCandleLines(true);

        this.startAnimation();
        this.hideLoader();
    }

    updateAssetIntervals() {
        const assetConfig = this.getAssetConfig();
        if (assetConfig) {
            this.currentInterval = assetConfig.baseInterval;
            this.minInterval = assetConfig.baseInterval;
            this.maxInterval = assetConfig.priceInterval[assetConfig.priceInterval.length - 1];

            // Force update the price grid base and line count
            this.priceLineCount = 7;
            this.optimalMaxLines = 10;
            this.maxPriceLines = 10;


        } else {

        }
    }

    loadJSONData(event) {
        const file = event.target.files[0];
        if (!file) return;
        const reader = new FileReader();
        reader.onload = e => {
            try {
                const jsonData = JSON.parse(e.target.result);
                this.rawData = jsonData
                    .map(item => ({ time: parseInt(item.time), price: parseFloat(item.price) }))
                    .filter(item => !isNaN(item.price) && item.price > 0);
                this.processCandleData();
                this.restart();
                const indicator = document.getElementById('statusIndicator');
                indicator.classList.add('visible');
                setTimeout(() => indicator.classList.remove('visible'), 3000);
            } catch (error) {
                alert('Error loading JSON file. Please check the format.');
            }
        };
        reader.readAsText(file);
    }

    processCandleData() {
        if (!this.hasValidData()) return false;

        this.candleData = [];
        for (let i = 0; i < this.rawData.length; i += 60) {
            const candlePoints = this.rawData.slice(i, i + 60);
            if (candlePoints.length === 0) continue;
            const open = candlePoints[0].price;
            const close = candlePoints[candlePoints.length - 1].price;
            const high = Math.max(...candlePoints.map(d => d.price));
            const low = Math.min(...candlePoints.map(d => d.price));
            const timestamp = candlePoints[0].time * 1000;
            this.candleData.push({
                timestamp,
                time: new Date(timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }),
                open, high, low, close,
                secondData: candlePoints,
                isComplete: false
            });
        }

        this.createAllCandlesForTesting();
        this.analyzeCompleteDataset();
    }

    createAllCandlesForTesting() {
        this.candleData.forEach(candle => candle.isComplete = false);

        this.currentCandleIndex = 0;
        this.currentCandleElapsed = 0;
        this.realStartTime = Date.now();
        this.currentSecondIndex = 0;

        this.currentPrice = this.candleData[0]?.open || this.rawData[0]?.price;
        this.targetPrice = this.candleData[0]?.secondData[0]?.price || this.currentPrice;
    }

    setupEventListeners() {
        this.canvas.addEventListener('mousedown', e => this.onMouseDown(e));
        this.canvas.addEventListener('mousemove', e => this.onMouseMove(e));
        this.canvas.addEventListener('mouseup', () => this.onMouseUp());
        this.canvas.addEventListener('mouseleave', () => {
            this.showCrosshair = false;
            this.hoveredCandle = null;
            this.hideCandleOHLC();
            // Remove any crosshair icons when mouse leaves canvas
            const chartContainer = document.getElementById('chartContainer');
            if (chartContainer) {
                const existingIcons = chartContainer.querySelectorAll('img[src="./svg/svgbellicon.svg"]');
                existingIcons.forEach(icon => icon.remove());
            }
        });
        window.addEventListener('resize', () => this.setupCanvas());
    }

    setupVisibilityHandler() {
        document.addEventListener('visibilitychange', () => {
            if (document.hidden) {
                this.pauseForBackground();
            } else {
                this.resumeFromBackground();
            }
        });
    }

    pauseForBackground() {
        if (this.isPlaying) {
            this.backgroundPauseTime = Date.now();
        }
    }

    resumeFromBackground() {
        if (this.backgroundPauseTime && this.isPlaying) {
            const pauseDuration = Date.now() - this.backgroundPauseTime;
            this.realStartTime += pauseDuration;
            this.backgroundPauseTime = null;
        }
    }

    setupTradeButtonListeners() {
        // Trade button listeners are now handled in the main app.js file
    }

    onMouseDown(e) {
        // Only respond to left clicks (button 0)
        if (e.button !== 0) return;

        // Check if clicking on circle
        if (this.circlePosition) {
            const rect = this.canvas.getBoundingClientRect();
            const mouseX = e.clientX - rect.left;
            const mouseY = e.clientY - rect.top;
            const distance = Math.sqrt(Math.pow(mouseX - this.circlePosition.x, 2) + Math.pow(mouseY - this.circlePosition.y, 2));

            if (distance <= this.circlePosition.radius) {
                // Start smooth slide animation to maximum left position
                const boundaries = this.getAdaptiveBoundaries();
                this.startPanAnimation(boundaries.left);
                return;
            }
        }

        this.isDragging = true;
        this.lastMouseX = e.clientX;
        this.canvas.style.cursor = 'default';
        e.preventDefault();
    }

    onMouseMove(e) {
        const rect = this.canvas.getBoundingClientRect();
        this.mouseX = e.clientX - rect.left;
        this.mouseY = e.clientY - rect.top;
        this.showCrosshair = true;

        if (this.isDragging) {
            const deltaX = e.clientX - this.lastMouseX;

            if (Math.abs(deltaX) > 1) {
                const newOffset = this.panOffset + deltaX;
                const boundaries = this.getAdaptiveBoundaries();

                const leftBoundaryWithBuffer = boundaries.left - 10;
                const deadband = 3;

                if (newOffset > boundaries.right + deadband) {
                    this.panOffset = boundaries.right;
                } else if (newOffset < leftBoundaryWithBuffer - deadband) {
                    this.panOffset = leftBoundaryWithBuffer;
                } else if (newOffset <= boundaries.right && newOffset >= leftBoundaryWithBuffer) {
                    this.panOffset = newOffset;
                }

                this.lastMouseX = e.clientX;

                // Update high/low boxes when panning
                if (this.updateHighLowBoxes) {
                    this.updateHighLowBoxes();
                }
            }

            this.userDraggedAway = !this.isRunningCandleVisible();
            this.isViewingHistorical = this.userDraggedAway;
        } else {
            this.checkCandleHover();
        }
    }

    analyzeCompleteDataset() {
        if (!this.candleData.length) return;

        const allPrices = [];
        this.candleData.forEach(candle => allPrices.push(candle.open, candle.high, candle.low, candle.close));

        const minPrice = Math.min(...allPrices), maxPrice = Math.max(...allPrices);
        const totalRange = maxPrice - minPrice;

        const marketCondition = this.analyzeMarketCondition(allPrices);
        this.currentInterval = marketCondition.interval;
        this.priceLineCount = 6;

        this.minInterval = this.maxInterval = this.currentInterval;
        this.priceWindowBase = minPrice - (this.currentInterval * 2);

        this.currentPrice = this.rawData[0].price;
        this.targetPrice = this.rawData[0].price;

        this.forceUpdatePriceRange();
    }

    analyzeMarketCondition(prices) {
        // Get asset-specific configuration first
        const assetConfig = this.getAssetConfig();
        if (assetConfig) {
            return {
                condition: 'ASSET_CONFIGURED',
                interval: assetConfig.baseInterval,
                volatilityCoeff: 0,
                avgMovement: 0
            };
        }

        // Fallback to original logic
        const movements = [];
        for (let i = 1; i < prices.length; i++) {
            movements.push(Math.abs(prices[i] - prices[i - 1]));
        }

        const avgMovement = movements.reduce((sum, mov) => sum + mov, 0) / movements.length;
        const variance = movements.reduce((sum, mov) => sum + Math.pow(mov - avgMovement, 2), 0) / movements.length;
        const stdDev = Math.sqrt(variance);

        const volatilityCoeff = stdDev / avgMovement;

        let condition, interval;

        if (volatilityCoeff < 0.8 || avgMovement < 0.005) {
            condition = 'CALM';
            interval = 0.010;
        } else if (volatilityCoeff < 1.2 || avgMovement < 0.008) {
            condition = 'STABLE';
            interval = 0.010;
        } else if (volatilityCoeff > 2.0 || avgMovement > 0.015) {
            condition = 'VOLATILE';
            interval = 0.050;
        } else {
            condition = 'NORMAL';
            interval = 0.020;
        }

        return { condition, interval, volatilityCoeff, avgMovement };
    }

    initializePriceWindow() {
        // Initialize the price grid base when data is first loaded
        if (this.candleData && this.candleData.length > 0) {
            const firstCandle = this.candleData[0];
            this.priceGridBase = Math.round(firstCandle.open / this.currentInterval) * this.currentInterval;
        }
    }

    forceUpdatePriceRange() {
        if (!this.candleData.length) return;

        const allPrices = [];
        this.candleData.forEach(candle => allPrices.push(candle.open, candle.high, candle.low, candle.close));

        const min = Math.min(...allPrices), max = Math.max(...allPrices), range = max - min;
        const centerPrice = (min + max) / 2;

        // Initialize price grid base to center of price range
        this.priceGridBase = Math.round(centerPrice / this.currentInterval) * this.currentInterval;
        this.priceLineCount = 7; // Always start with 7 lines
    }

    checkCandleHover() {
        if (!this.candleData || !this.candleData.length || this.currentCandleIndex < 0) {
            return;
        }

        const a = this.getChartArea();
        const twoCm = 100;
        const startX = a.left + this.panOffset + twoCm;
        let hoveredIndex = -1;

        for (let i = 0; i <= this.currentCandleIndex; i++) {
            const isOddCandle = (i % 2) === 0;
            const gridIndex = Math.floor(i / 2);
            const x = isOddCandle ?
                startX + gridIndex * twoCm - this.config.candleWidth / 2 :
                startX + gridIndex * twoCm + twoCm / 2 - this.config.candleWidth / 2;
            const candleEndX = x + this.config.candleWidth;
            if (this.mouseX >= x && this.mouseX <= candleEndX) { hoveredIndex = i; break; }
        }

        if (hoveredIndex !== -1 && hoveredIndex !== this.currentCandleIndex) {
            this.hoveredCandle = this.candleData[hoveredIndex];
            this.showCandleOHLC(this.hoveredCandle);
        } else if (hoveredIndex === this.currentCandleIndex) {
            const currentCandle = this.candleData[this.currentCandleIndex];
            this.hoveredCandle = {
                ...currentCandle,
                time: currentCandle.time,
                high: this.runningHigh ?? currentCandle.open,
                low: this.runningLow ?? currentCandle.open,
                close: this.currentPrice
            };
            this.showCandleOHLC(this.hoveredCandle);
        } else {
            this.hoveredCandle = null; this.hideCandleOHLC();
        }
    }

    showCandleOHLC(candle) {
        let candleInfo = document.getElementById('candleInfo');
        if (candleInfo) {
            candleInfo.querySelector('#candleOpen').textContent = this.formatPrice(candle.open);
            candleInfo.querySelector('#candleClose').textContent = this.formatPrice(candle.close);
            candleInfo.querySelector('#candleHigh').textContent = this.formatPrice(candle.high);
            candleInfo.querySelector('#candleLow').textContent = this.formatPrice(candle.low);
            candleInfo.classList.add('visible');
        }
    }

    hideCandleOHLC() {
        const candleInfo = document.getElementById('candleInfo');
        if (candleInfo) candleInfo.classList.remove('visible');
    }

    onMouseUp() {
        this.isDragging = false;
        this.canvas.style.cursor = 'default';
    }

    toggleAnimation() {
        if (this.isPlaying) { this.stopAnimation(); }
        else { this.startAnimation(); }
    }

    setTimeframe(timeframe) {
        this.showLoader();

        const oldSecondsPerCandle = this.timeframeIntervals[this.currentTimeframe] || 60;
        const totalElapsedSeconds = (this.currentCandleIndex * oldSecondsPerCandle) + this.currentCandleElapsed;

        this.currentTimeframe = timeframe;
        this.stopAnimation();

        this.processCandleDataForTimeframe(timeframe);

        const newSecondsPerCandle = this.timeframeIntervals[timeframe] || 60;
        const newCandleIndex = Math.floor(totalElapsedSeconds / newSecondsPerCandle);
        const newCandleElapsed = totalElapsedSeconds % newSecondsPerCandle;

        this.currentCandleIndex = Math.min(newCandleIndex, this.candleData.length - 1);

        const currentCandle = this.candleData[this.currentCandleIndex];
        if (currentCandle && currentCandle.secondData) {
            this.currentCandleElapsed = Math.min(newCandleElapsed, currentCandle.secondData.length - 1);

            if (currentCandle.secondData[this.currentCandleElapsed]) {
                this.currentPrice = currentCandle.secondData[this.currentCandleElapsed].price;
                this.targetPrice = this.currentPrice;
            } else {
                this.currentPrice = currentCandle.open;
                this.targetPrice = this.currentPrice;
                this.currentCandleElapsed = 0;
            }
        } else {
            this.currentCandleElapsed = 0;
            this.currentPrice = this.candleData[0]?.open || this.rawData[0]?.price;
            this.targetPrice = this.currentPrice;
        }

        this.candleData.forEach((candle, index) => {
            candle.isComplete = index < this.currentCandleIndex;
        });

        this._initRunningExtremes();
        this.updateDisplays();
        this.updateCurrentCandleLines(true);

        this.startAnimation();
        this.hideLoader();
    }

    processCandleDataForTimeframe(timeframe) {
        const secondsPerCandle = this.timeframeIntervals[timeframe] || 60;

        this.candleData = [];
        for (let i = 0; i < this.rawData.length; i += secondsPerCandle) {
            const candlePoints = this.rawData.slice(i, i + secondsPerCandle);
            if (candlePoints.length === 0) continue;

            const open = candlePoints[0].price;
            const close = candlePoints[candlePoints.length - 1].price;
            const high = Math.max(...candlePoints.map(d => d.price));
            const low = Math.min(...candlePoints.map(d => d.price));
            const timestamp = candlePoints[0].time * 1000;

            this.candleData.push({
                timestamp,
                time: new Date(timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', hour12: false }),
                open, high, low, close,
                secondData: candlePoints,
                isComplete: false
            });
        }
    }

    startAnimation() {
        if (this.isPlaying) return;
        this.isPlaying = true;

        const secondsPerCandle = this.timeframeIntervals[this.currentTimeframe] || 60;
        this.candleStartTime = Date.now();
        this.lastUpdateTime = Date.now();

        this.animationInterval = setInterval(() => {
            const now = Date.now();
            const realElapsed = Math.floor((now - this.realStartTime) / 1000);
            const expectedCandleIndex = Math.floor(realElapsed / secondsPerCandle);
            const expectedElapsed = realElapsed % secondsPerCandle;

            if (expectedCandleIndex > this.currentCandleIndex) {
                const missedCandles = expectedCandleIndex - this.currentCandleIndex;

                for (let i = 0; i < missedCandles; i++) {
                    if (this.currentCandleIndex < this.candleData.length - 1) {
                        const c = this.candleData[this.currentCandleIndex];
                        c.high = c.high;
                        c.low = c.low;
                        c.close = c.close;
                        c.isComplete = true;

                        this.currentCandleIndex++;
                        if (this.currentCandleIndex < this.candleData.length) {
                            this.currentPrice = this.candleData[this.currentCandleIndex].open;
                        }
                    }
                }

                this.currentCandleElapsed = expectedElapsed;
                this._initRunningExtremes();
                this.updateDisplays();
                this.updateCurrentCandleLines(true);
            } else {
                this.currentCandleElapsed++;
            }

            if (this.currentCandleElapsed < secondsPerCandle) {
                const candleData = this.candleData[this.currentCandleIndex];
                if (candleData && candleData.secondData[this.currentCandleElapsed]) {
                    this.targetPrice = candleData.secondData[this.currentCandleElapsed].price;
                    this.animationStart = performance.now();
                    this.isAnimating = true;
                    this.checkAndAdjustPriceInterval();
                    this.updateDisplays();
                }
            } else if (this.currentCandleIndex < this.candleData.length - 1) {
                const c = this.candleData[this.currentCandleIndex];
                c.high = Math.max(c.high, this.runningHigh ?? c.open);
                c.low = Math.min(c.low, this.runningLow ?? c.open);
                c.close = this.currentPrice;
                c.isComplete = true;

                this.currentCandleIndex++;
                this.currentCandleElapsed = 0;
                this.candleStartTime = Date.now();

                this.currentPrice = this.candleData[this.currentCandleIndex].open;
                this.targetPrice = this.candleData[this.currentCandleIndex].secondData[0].price;
                this._initRunningExtremes();
                this.updateDisplays();
                this.updateCurrentCandleLines(true);

                if (this.userDraggedAway && this.panOffset < 0) {
                    this.returnToRunningCandle();
                }
                this.isViewingHistorical = false;
            } else {
                const lastCandle = this.candleData[this.currentCandleIndex];
                if (lastCandle) {
                    lastCandle.high = Math.max(lastCandle.high, this.runningHigh ?? lastCandle.open);
                    lastCandle.low = Math.min(lastCandle.low, this.runningLow ?? lastCandle.open);
                    lastCandle.close = this.currentPrice;
                    lastCandle.isComplete = true;
                }

                this.currentCandleIndex = 0;
                this.currentCandleElapsed = 0;
                this.candleData.forEach(candle => candle.isComplete = false);

                this.currentPrice = this.candleData[0].open;
                this.targetPrice = this.candleData[0].secondData[0].price;
                this._initRunningExtremes();
                this.updateDisplays();
                this.updateCurrentCandleLines(true);


            }

            this.lastUpdateTime = now;
        }, 1000);

        setInterval(() => {
            if (this.isPlaying) {
                this.saveChartState();
            }
        }, 5000);
    }

    saveChartState() {
        const state = {
            currentCandleIndex: this.currentCandleIndex,
            currentCandleElapsed: this.currentCandleElapsed,
            realStartTime: this.realStartTime,
            timestamp: Date.now()
        };
        localStorage.setItem(this.storageKey, JSON.stringify(state));
    }

    loadChartState() {
        try {
            const saved = localStorage.getItem(this.storageKey);
            if (saved) {
                const state = JSON.parse(saved);
                const timeSinceLastSave = Math.floor((Date.now() - state.timestamp) / 1000);
                const totalElapsed = (state.currentCandleIndex * 60) + state.currentCandleElapsed + timeSinceLastSave;

                return {
                    currentCandleIndex: Math.floor(totalElapsed / 60),
                    currentCandleElapsed: totalElapsed % 60,
                    realStartTime: state.realStartTime
                };
            }
        } catch (error) { }
        return null;
    }

    stopAnimation() {
        this.isPlaying = false;
        if (this.animationInterval) {
            clearInterval(this.animationInterval);
            this.animationInterval = null;
        }
    }

    restart() {
        this.stopAnimation();
        this.currentCandleIndex = 0;
        this.currentSecondIndex = 0;
        this.currentPrice = this.rawData[0].price;
        this.targetPrice = this.rawData[0].price;
        this.isAnimating = false;
        this.candleData.forEach(c => (c.isComplete = false));
        this._initRunningExtremes();
        this.updateDisplays();
        this.updateCurrentCandleLines(true);
    }

    buildAllCandles() {
        this.stopAnimation();

        this.candleData.forEach((candle, index) => {
            if (candle.secondData && candle.secondData.length > 0) {
                const prices = candle.secondData.map(d => d.price);
                candle.high = Math.max(...prices);
                candle.low = Math.min(...prices);
                candle.close = candle.secondData[candle.secondData.length - 1].price;
            }
            candle.isComplete = true;
        });

        this.currentCandleIndex = this.candleData.length - 1;
        this.currentCandleElapsed = 59;
        this.isPlaying = false;

        if (this.candleData[this.currentCandleIndex]) {
            this.currentPrice = this.candleData[this.currentCandleIndex].close;
            this.targetPrice = this.currentPrice;
            this.runningHigh = this.candleData[this.currentCandleIndex].high;
            this.runningLow = this.candleData[this.currentCandleIndex].low;
        }

        this.updateDisplays();
        this.updateCurrentCandleLines(true);
    }

    freezeChart() {
        if (!this.isFrozen) {
            const container = document.getElementById('chartContainer');
            this.frozenCanvasData = this.ctx.getImageData(0, 0, container.clientWidth, container.clientHeight);
            this.isFrozen = true;
        }
    }

    unfreezeChart() {
        this.isFrozen = false;
        this.frozenCanvasData = null;
    }

    _initRunningExtremes() {
        const currentCandle = this.candleData[this.currentCandleIndex];
        if (!currentCandle) return;
        this.runningHigh = currentCandle.open;
        this.runningLow = currentCandle.open;
        const y = this.priceToY(this.currentPrice);
        this.currentCandleLines.high.current = y; this.currentCandleLines.high.target = y;
        this.currentCandleLines.low.current = y; this.currentCandleLines.low.target = y;
        this.currentCandleLines.close.current = y; this.currentCandleLines.close.target = y;

        this.updateTimeSection();
    }

    updateDisplays() {
        this.updateTimeSection();
    }

    updateTimeSection() {
        // Skip individual chart time updates - handled by centralized controller
        // This prevents conflicts with the master time display controller
        return;
    }



    updateCurrentCandleLines(force = false) {
        const c = this.candleData[this.currentCandleIndex];
        if (!c) return;
        const priceRange = this.getPriceRange();
        const chartArea = this.getChartArea();
        const hi = this.runningHigh ?? c.open;
        const lo = this.runningLow ?? c.open;
        const priceToY = p => chartArea.top + ((priceRange.max - p) / (priceRange.max - priceRange.min)) * chartArea.height;
        const hiY = priceToY(hi);
        const loY = priceToY(lo);
        const closeY = priceToY(this.currentPrice);
        if (force) {
            this.currentCandleLines.high.current = hiY; this.currentCandleLines.low.current = loY; this.currentCandleLines.close.current = closeY;
        }
        this.currentCandleLines.high.target = hiY;
        this.currentCandleLines.low.target = loY;
        this.currentCandleLines.close.target = closeY;

        const last = this.candleData[this.currentCandleIndex - 1];
        if (last) {
            this.currentCandleLines.high.visible = hi > last.high;
            this.currentCandleLines.low.visible = lo < last.low;
        } else {
            this.currentCandleLines.high.visible = true;
            this.currentCandleLines.low.visible = true;
        }
    }

    startRenderLoop() {
        let lastFrameTime = 0;
        const targetFPS = 60;
        const frameInterval = 1000 / targetFPS;

        const render = (timestamp) => {
            if (timestamp - lastFrameTime >= frameInterval) {
                this.animate(timestamp);
                this.draw();
                lastFrameTime = timestamp;
            }
            requestAnimationFrame(render);
        };
        render();
    }

    animate(timestamp) {
        if (this.isAnimating) {
            const elapsed = timestamp - this.animationStart;
            const progress = Math.min(elapsed / this.config.animation.duration, 1);
            const eased = this.config.animation.easing(progress);
            const startPrice = this.currentPrice;
            this.currentPrice = startPrice + (this.targetPrice - startPrice) * eased;

            if (progress >= 1) { this.isAnimating = false; this.currentPrice = this.targetPrice; }
            this.checkAndAdjustPriceInterval();
            this.updateCurrentCandleLines();
        }

        // Update running high/low on every frame for instant reversal box updates
        this.runningHigh = Math.max(this.runningHigh ?? this.currentPrice, this.currentPrice);
        this.runningLow = Math.min(this.runningLow ?? this.currentPrice, this.currentPrice);

        const smooth = 0.15;
        this.currentCandleLines.high.current += (this.currentCandleLines.high.target - this.currentCandleLines.high.current) * smooth;
        this.currentCandleLines.low.current += (this.currentCandleLines.low.target - this.currentCandleLines.low.current) * smooth;
        this.currentCandleLines.close.current += (this.currentCandleLines.close.target - this.currentCandleLines.close.current) * smooth;

        this.slidingAnimation.offset += (this.slidingAnimation.target - this.slidingAnimation.offset) * this.slidingAnimation.speed;

        if (Math.abs(this.slidingAnimation.target - this.slidingAnimation.offset) < 0.001) {
            this.slidingAnimation.offset = 0;
            this.slidingAnimation.target = 0;
        }
    }

    draw() {
        const container = document.getElementById('chartContainer');

        // If frozen, draw the frozen canvas data and return
        if (this.isFrozen && this.frozenCanvasData) {
            this.ctx.putImageData(this.frozenCanvasData, 0, 0);
            return;
        }

        // Reset cursor to default at start of frame
        if (this.canvas) {
            this.canvas.style.cursor = 'default';
        }

        this.ctx.fillStyle = this.config.colors.bg;
        this.ctx.fillRect(0, 0, container.clientWidth, container.clientHeight);
        this.drawGrid();
        this.drawCompletedCandles();
        this.drawBuildingCandle();
        this.drawCurrentCandleVerticalLine();
        // Draw dashed price line first (below trade info boxes)
        this.drawCurrentPriceDashedLine();

        // Draw reversal boxes (Lower Z-index: Behind trade lines)
        // Update reversal detection on every frame for instant response
        if (this.candleData && this.candleData.length > 2) {
            this.checkForReversals();
        }
        if (this.drawReversalBoxes) {
            this.drawReversalBoxes();
        }



        this.drawTradeLines();

        this.drawTradeExpirationEffects();
        this.drawRightSideCircle();
        this.drawPriceScale();
        this.drawTimeScale();
        if (this.showCrosshair) this.drawCrosshair();
        // Draw current price line last to ensure it's always on top
        this.drawCurrentPriceLine();
    }

    getChartArea() {
        const container = document.getElementById('chartContainer');
        return {
            left: 50,
            top: this.config.padding.top,
            width: container.clientWidth - 50 - this.config.padding.right,
            height: container.clientHeight - this.config.padding.top - this.config.padding.bottom
        };
    }

    getPriceRange() {
        if (this.candleData.length === 0) {
            return { min: 0, max: 0, interval: 0.020, tickSize: 0.001 };
        }

        const visibleCandles = this.getVisibleCandles();
        const allPrices = [];

        visibleCandles.forEach(candle => {
            if (candle.isComplete) {
                allPrices.push(candle.high, candle.low);
            } else {
                allPrices.push(candle.open, this.runningHigh || candle.open, this.runningLow || candle.open);
            }
        });

        allPrices.push(this.currentPrice);

        if (allPrices.length === 0) {
            return { min: 0, max: 0, interval: 0.020, tickSize: 0.001 };
        }

        const minPrice = Math.min(...allPrices);
        const maxPrice = Math.max(...allPrices);
        const priceRange = maxPrice - minPrice;
        const centerPrice = (minPrice + maxPrice) / 2;

        let optimalInterval;
        if (priceRange <= 0.050) optimalInterval = 0.010;
        else if (priceRange <= 0.120) optimalInterval = 0.020;
        else optimalInterval = 0.050;

        // Use asset-specific interval if available, otherwise use calculated optimal
        const assetConfig = this.getAssetConfig();
        if (assetConfig) {
            this.currentInterval = assetConfig.baseInterval;
        } else {
            this.currentInterval = optimalInterval;
        }

        const isHistorical = this.isViewingHistorical || this.userDraggedAway;

        // Always use 7 lines, only expand in extreme cases
        let targetLines = 7;

        // Only expand if price range is extremely large
        const extremeRangeThreshold = this.currentInterval * 8;
        if (priceRange > extremeRangeThreshold) {
            targetLines = Math.min(10, Math.ceil(priceRange / this.currentInterval) + 1);
        }

        // Ensure all visible candles fit within the price range
        const dynamicRange = this.calculateDynamicPriceRange(centerPrice, this.currentInterval, targetLines);

        // Expand range if visible candles don't fit (now handled in calculateDynamicPriceRange)
        if (minPrice < dynamicRange.min || maxPrice > dynamicRange.max) {
            const requiredMin = Math.min(dynamicRange.min, minPrice - this.currentInterval);
            const requiredMax = Math.max(dynamicRange.max, maxPrice + this.currentInterval);
            const requiredLineCount = Math.ceil((requiredMax - requiredMin) / this.currentInterval) + 1;

            // Only expand if absolutely necessary and within limits
            if (requiredLineCount <= this.maxPriceLines) {
                return {
                    min: requiredMin,
                    max: requiredMax,
                    interval: this.currentInterval,
                    tickSize: 0.001,
                    centerPrice: (requiredMin + requiredMax) / 2,
                    lineCount: requiredLineCount
                };
            }
        }

        return dynamicRange;
    }

    checkAndAdjustPriceInterval() { }

    calculateOptimalInterval(priceRange) {
        // Use asset-specific intervals if available
        const assetConfig = this.getAssetConfig();
        if (assetConfig && assetConfig.priceInterval) {
            // Select appropriate interval based on price range
            const intervals = assetConfig.priceInterval;
            console.log(`📊 Calculating optimal interval for range ${priceRange}, available intervals:`, intervals);

            if (intervals.length >= 3) {
                if (priceRange <= intervals[0] * 3) return intervals[0];
                if (priceRange <= intervals[1] * 3) return intervals[1];
                return intervals[2];
            } else if (intervals.length >= 2) {
                if (priceRange <= intervals[0] * 3) return intervals[0];
                return intervals[1];
            } else {
                return intervals[0];
            }
        }

        // Fallback to original logic
        if (priceRange <= 0.030) return 0.010;
        if (priceRange <= 0.100) return 0.020;
        return 0.050;
    }

    getVisibleCandles() {
        const a = this.getChartArea();
        const twoCm = 100;
        const startX = a.left + this.panOffset + twoCm;
        const visibleCandles = [];

        for (let i = 0; i < this.candleData.length; i++) {
            const isOddCandle = (i % 2) === 0;
            const gridIndex = Math.floor(i / 2);
            const x = isOddCandle ?
                startX + gridIndex * twoCm - this.config.candleWidth / 2 :
                startX + gridIndex * twoCm + twoCm / 2 - this.config.candleWidth / 2;

            if (x + this.config.candleWidth >= 50 && x <= a.left + a.width) {
                visibleCandles.push(this.candleData[i]);
            }
        }

        return visibleCandles.length > 0 ? visibleCandles : [this.candleData[this.currentCandleIndex]].filter(Boolean);
    }

    priceToY(price) {
        const a = this.getChartArea();
        const r = this.getPriceRange();
        const chartTopWithMargin = a.top + this.topMargin;
        const availableHeight = a.height - this.topMargin - this.bottomMargin;
        return chartTopWithMargin + ((r.max - price) / (r.max - r.min)) * availableHeight;
    }
    yToPrice(y) {
        const a = this.getChartArea();
        const r = this.getPriceRange();
        const chartTopWithMargin = a.top + this.topMargin;
        const availableHeight = a.height - this.topMargin - this.bottomMargin;
        return r.max - ((y - chartTopWithMargin) / availableHeight) * (r.max - r.min);
    }

    calculateDynamicPriceRange(centerPrice, interval, targetLines = 6) {
        // Force exactly 7 lines
        targetLines = 7;
        // Get all visible candle prices to ensure they fit
        const visibleCandles = this.getVisibleCandles();
        const visiblePrices = [];

        visibleCandles.forEach(candle => {
            if (candle.isComplete) {
                visiblePrices.push(candle.high, candle.low);
            } else {
                visiblePrices.push(candle.open, this.runningHigh || candle.open, this.runningLow || candle.open);
            }
        });

        // Always include current price for universal expansion
        visiblePrices.push(this.currentPrice);

        if (visiblePrices.length > 0) {
            const visibleMin = Math.min(...visiblePrices);
            const visibleMax = Math.max(...visiblePrices);

            // Initialize or adjust grid base to accommodate visible candles
            if (!this.priceGridBase) {
                this.priceGridBase = Math.round(centerPrice / interval) * interval;
            }

            const linesAbove = Math.ceil(targetLines / 2);
            const linesBelow = Math.floor(targetLines / 2);

            // Try to fit within optimal range first
            let adjustedBase = this.priceGridBase;
            let currentMin = adjustedBase - (linesBelow * interval);
            let currentMax = adjustedBase + (linesAbove * interval);
            let expansionCount = 0;
            const maxExpansions = Math.min(2, (this.maxPriceLines - targetLines) / 2); // Limit expansions more strictly

            // 🚀 CONSERVATIVE DYNAMIC EXPANSION - Only expand when absolutely necessary
            const proximityThreshold = interval * 0.9; // More conservative threshold (90% instead of 70%)

            // Check if current price needs expansion at top
            if (this.currentPrice >= (currentMax - proximityThreshold)) {
                while (this.currentPrice >= (currentMax - proximityThreshold) && expansionCount < maxExpansions) {
                    adjustedBase += interval;
                    currentMin = adjustedBase - (linesBelow * interval);
                    currentMax = adjustedBase + (linesAbove * interval);
                    expansionCount++;
                }
            }

            // Check if current price needs expansion at bottom
            if (this.currentPrice <= (currentMin + proximityThreshold)) {
                while (this.currentPrice <= (currentMin + proximityThreshold) && expansionCount < maxExpansions) {
                    adjustedBase -= interval;
                    currentMin = adjustedBase - (linesBelow * interval);
                    currentMax = adjustedBase + (linesAbove * interval);
                    expansionCount++;
                }
            }

            // Expand grid if visible candles don't fit, but limit expansions
            while (visibleMin < currentMin && expansionCount < maxExpansions) {
                adjustedBase -= interval;
                currentMin = adjustedBase - (linesBelow * interval);
                currentMax = adjustedBase + (linesAbove * interval);
                expansionCount++;
            }

            while (visibleMax > currentMax && expansionCount < maxExpansions) {
                adjustedBase += interval;
                currentMin = adjustedBase - (linesBelow * interval);
                currentMax = adjustedBase + (linesAbove * interval);
                expansionCount++;
            }

            this.priceGridBase = adjustedBase;

            // Always use exactly 7 lines
            const actualLineCount = 7;

            return {
                min: currentMin,
                max: currentMax,
                interval: interval,
                tickSize: 0.001,
                centerPrice: adjustedBase,
                lineCount: actualLineCount
            };
        }

        // Fallback if no visible candles
        if (!this.priceGridBase) {
            this.priceGridBase = Math.round(centerPrice / interval) * interval;
        }

        const linesAbove = Math.ceil(targetLines / 2);
        const linesBelow = Math.floor(targetLines / 2);
        const min = this.priceGridBase - (linesBelow * interval);
        const max = this.priceGridBase + (linesAbove * interval);

        return {
            min: min,
            max: max,
            interval: interval,
            tickSize: 0.001,
            centerPrice: this.priceGridBase,
            lineCount: 7
        };
    }


    drawGrid() {
        const a = this.getChartArea();

        // 🚀 CROSS-AXIS INITIALIZATION FIX: Wait dynamically for the exact millisecond 
        // the browser CSS paints the canvas width, then instantly lock the camera center.
        if (this.needsInitialPan && a.width > 200) {
            const twoCm = 100;
            const i = this.currentCandleIndex;
            const gridIndex = Math.floor(i / 2);
            const targetCandleX = (i % 2 === 0) ? (gridIndex * twoCm) : (gridIndex * twoCm + twoCm / 2);
            this.panOffset = (a.width - 400) - targetCandleX - twoCm;
            this.needsInitialPan = false;
        }

        const r = this.getPriceRange();
        const chartTopWithMargin = a.top + this.topMargin;
        const availableHeight = a.height - this.topMargin - this.bottomMargin;

        let interval = r.interval;
        const tickSize = r.tickSize;

        let startPrice = Math.floor(r.min / interval) * interval;
        let endPrice = Math.ceil(r.max / interval) * interval;

        // EMERGENCY GLITCH PREVENTION:
        // If the configuration has not loaded or interval math fails, never allow >15 grid lines
        // This solves the 'excessive white grid lines' initialization bug permanently
        if (((endPrice - startPrice) / interval) > 15) {
            interval = (r.max - r.min) / 7;
            startPrice = r.min;
            endPrice = r.max;
        }

        // 1. UPDATE HORIZONTAL GRID
        const currentPrices = [];
        for (let price = startPrice; price <= endPrice; price += interval) {
            const normalizedPrice = Number(price.toFixed(8));
            currentPrices.push(normalizedPrice);
        }
        this.updateAnimatedPriceLines(currentPrices, chartTopWithMargin, availableHeight, r);

        // 2. UPDATE VERTICAL GRID (TIME)
        let currentVerticalLines = [];
        if (this.visibleZone && typeof this.visibleZone.getVerticalGrid === 'function') {
            currentVerticalLines = this.visibleZone.getVerticalGrid();
            this.updateAnimatedVerticalLines(currentVerticalLines);
        }

        // 3. DRAW HORIZONTAL GRID LINES (SLIDING)
        this.animatedPriceLines.forEach((lineData, price) => {
            const y = lineData.currentY;

            // Only draw lines that are physically within or near the visible area
            if (y >= a.top - 5 && y <= a.top + a.height + 5) {
                this.ctx.strokeStyle = '#ffffff';
                this.ctx.lineWidth = 0.2;
                this.ctx.globalAlpha = 0.5; // Always solid grid intensity

                this.ctx.beginPath();
                this.ctx.moveTo(50, y);
                this.ctx.lineTo(a.left + a.width + this.config.padding.right, y);
                this.ctx.stroke();

                this.ctx.globalAlpha = 1.0;
                this.ctx.fillStyle = '#DDDDDF';
                this.ctx.font = '500 12px Roboto,Arial,Helvetica,sans-serif';
                this.ctx.textAlign = 'right';

                const priceText = this.formatPrice(price, tickSize);
                this.ctx.fillText(priceText, a.left + a.width + this.config.padding.right - 8, y - 5);
            }
        });

        // 4. DRAW VERTICAL GRID LINES (SLIDING)
        this.ctx.save();
        this.ctx.setTransform(1, 0, 0, 1, 0, 0);
        this.ctx.strokeStyle = '#FFFFFF';
        this.ctx.lineWidth = 0.2;
        this.ctx.lineCap = 'butt';

        const container = document.getElementById('chartContainer');
        const fullWidth = container?.clientWidth || a.width;

        this.animatedVerticalLines.forEach((lineData) => {
            const x = a.left + lineData.currentX;

            if (x > a.left + 45 && x < fullWidth) {
                this.ctx.globalAlpha = 0.5;
                this.ctx.beginPath();
                this.ctx.moveTo(Math.floor(x) + 0.5, a.top);
                this.ctx.lineTo(Math.floor(x) + 0.5, a.top + a.height + 10);
                this.ctx.stroke();
            }
        });

        this.ctx.restore();
        this.ctx.globalAlpha = 1.0;
    }

    updateAnimatedPriceLines(currentPrices, chartTopWithMargin, availableHeight, priceRange) {
        // 1. Tag all existing lines
        this.animatedPriceLines.forEach(line => line.active = false);

        // 2. Refresh target positions and visibility
        currentPrices.forEach(price => {
            const targetY = chartTopWithMargin + ((priceRange.max - price) / (priceRange.max - priceRange.min)) * availableHeight;

            if (!this.animatedPriceLines.has(price)) {
                // NEW LINE: Lock instantly to price-coordinate
                this.animatedPriceLines.set(price, {
                    currentY: targetY,
                    targetY: targetY,
                    active: true
                });
            } else {
                // EXISTING LINE: Lock instantly to breathing price-coordinate
                const line = this.animatedPriceLines.get(price);
                line.targetY = targetY;
                line.currentY = targetY; // Instant lock to price range breathing
                line.active = true;
            }
        });

        // 3. Cleanup immediately
        this.animatedPriceLines.forEach((line, price) => {
            if (!line.active) {
                this.animatedPriceLines.delete(price);
            }
        });
    }

    updateAnimatedVerticalLines(currentLines) {
        this.animatedVerticalLines.forEach(line => line.active = false);

        // 2. Update
        currentLines.forEach(line => {
            const { id, offset } = line;
            if (!this.animatedVerticalLines.has(id)) {
                this.animatedVerticalLines.set(id, {
                    currentX: offset,
                    targetX: offset,
                    active: true
                });
            } else {
                const lineData = this.animatedVerticalLines.get(id);
                lineData.targetX = offset;
                lineData.currentX = offset; // INSTANT LOCK
                lineData.active = true;
            }
        });

        // 3. Animate (Vertical lines mostly follow candles instantly for zero-lag)
        this.animatedVerticalLines.forEach((line, id) => {
            if (!line.active) {
                this.animatedVerticalLines.delete(id);
            }
        });
    }



    drawCompletedCandles() {
        const a = this.getChartArea();
        const twoCm = 100;
        const startX = a.left + this.panOffset + twoCm;

        for (let i = 0; i < this.currentCandleIndex; i++) {
            const c = this.candleData[i];
            if (!c || !c.isComplete) continue;

            const isOddCandle = (i % 2) === 0;
            const gridIndex = Math.floor(i / 2);
            const x = isOddCandle ?
                startX + gridIndex * twoCm - this.config.candleWidth / 2 :
                startX + gridIndex * twoCm + twoCm / 2 - this.config.candleWidth / 2;

            // Check visibility with 50px clipping zone consideration
            const candleRight = x + this.config.candleWidth;
            if (candleRight > 50 && x < a.left + a.width + this.config.candleWidth) {
                this.drawCandle(x, c, c.open, c.high, c.low, c.close, false);
            }
        }
    }

    drawBuildingCandle() {
        const a = this.getChartArea();
        const c = this.candleData[this.currentCandleIndex];
        if (!c) return;

        const twoCm = 100;
        const startX = a.left + this.panOffset + twoCm;
        const i = this.currentCandleIndex;

        const isOddCandle = (i % 2) === 0;
        const gridIndex = Math.floor(i / 2);
        const x = isOddCandle ?
            startX + gridIndex * twoCm - this.config.candleWidth / 2 :
            startX + gridIndex * twoCm + twoCm / 2 - this.config.candleWidth / 2;

        const currentHigh = this.runningHigh ?? c.open;
        const currentLow = this.runningLow ?? c.open;
        this.drawCandle(x, c, c.open, currentHigh, currentLow, this.currentPrice, true);
    }

    drawCandle(x, candle, open, high, low, close, isCurrent = false) {
        const candleWidth = this.config.candleWidth * this.zoom;
        const isUp = close >= open;

        // ANIMATION: Fade in new building candle over 1s
        if (isCurrent && this.candleStartTime) {
            const elapsed = Date.now() - this.candleStartTime;
            const alpha = Math.min(elapsed / 1000, 1);
            this.ctx.globalAlpha = alpha;
        }

        const upColor = '#0FA054';
        const downColor = '#E75B4D';

        const centerX = x + candleWidth / 2;
        const highY = this.priceToY(high);
        const lowY = this.priceToY(low);
        const openY = this.priceToY(open);
        const closeY = this.priceToY(close);

        // Respect the 50px left clipping zone
        const clippingLeft = 50;
        const candleLeft = x + 1;
        const candleRight = x + candleWidth - 1;

        // Only draw if the candle is not completely in the clipping zone
        if (candleRight <= clippingLeft) {
            return; // Candle is completely in clipping zone, don't draw
        }

        // Calculate clipped dimensions
        const clippedLeft = Math.max(candleLeft, clippingLeft);
        const clippedWidth = candleRight - clippedLeft;
        const clippedCenterX = Math.max(centerX, clippingLeft);

        this.ctx.strokeStyle = isUp ? upColor : downColor;
        this.ctx.lineWidth = 1;
        this.ctx.imageSmoothingEnabled = false;
        this.ctx.lineCap = 'butt';

        // Pixel snap for sharp wicks
        const pixelWickX = Math.floor(clippedCenterX) + 0.5;

        // Draw wicks only if center is not in clipping zone
        if (centerX >= clippingLeft) {
            if (high > Math.max(open, close)) {
                this.ctx.beginPath();
                this.ctx.moveTo(pixelWickX, highY);
                this.ctx.lineTo(pixelWickX, Math.min(openY, closeY));
                this.ctx.stroke();
            }
            if (low < Math.min(open, close)) {
                this.ctx.beginPath();
                this.ctx.moveTo(pixelWickX, lowY);
                this.ctx.lineTo(pixelWickX, Math.max(openY, closeY));
                this.ctx.stroke();
            }
        }

        const bodyTop = Math.min(openY, closeY);
        const bodyBottom = Math.max(openY, closeY);
        const bodyHeight = Math.max(1, bodyBottom - bodyTop);
        // Candle's transparent color fill / candle color opacity
        this.ctx.fillStyle = isUp ? 'rgba(15, 175, 89, 0.9)' : 'rgba(255, 98, 81, 0.9)';

        // Draw body with clipping applied
        if (clippedWidth > 0) {
            this.ctx.fillRect(clippedLeft, bodyTop, clippedWidth, bodyHeight);
        }

        // Reset alpha
        this.ctx.globalAlpha = 1.0;
    }

    drawCurrentPriceDashedLine() {
        const a = this.getChartArea();
        const y = this.priceToY(this.currentPrice);

        // Draw dashed line at original Y position
        this.ctx.strokeStyle = '#ffffff'; this.ctx.lineWidth = 1; this.ctx.setLineDash([5, 3]);
        this.ctx.beginPath(); this.ctx.moveTo(a.left, y); this.ctx.lineTo(a.left + a.width, y); this.ctx.stroke(); this.ctx.setLineDash([]);
    }

    drawCurrentPriceLine() {
        const a = this.getChartArea();
        const exactY = this.priceToY(this.currentPrice); // Sub-pixel precision for jitter-free glide

        // Draw timer box first (lower z-index)
        const c = this.candleData[this.currentCandleIndex];
        if (c) {
            const twoCm = 100;
            const startX = a.left + this.panOffset + twoCm;
            const i = this.currentCandleIndex;
            const isOddCandle = (i % 2) === 0;
            const gridIndex = Math.floor(i / 2);
            const candleX = isOddCandle ?
                startX + gridIndex * twoCm - this.config.candleWidth / 2 :
                startX + gridIndex * twoCm + twoCm / 2 - this.config.candleWidth / 2;
            const candleRightEdge = candleX + this.config.candleWidth;
            const timerX = candleRightEdge + 50;

            const secondsPerCandle = this.timeframeIntervals[this.currentTimeframe] || 60;
            const countdown = secondsPerCandle - this.currentCandleElapsed;

            let timerText;
            if (countdown >= 3600) {
                const hours = Math.floor(countdown / 3600);
                const minutes = Math.floor((countdown % 3600) / 60);
                const seconds = countdown % 60;
                timerText = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
            } else if (countdown >= 60) {
                const minutes = Math.floor(countdown / 60);
                const seconds = countdown % 60;
                timerText = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
            } else {
                timerText = `00:${countdown.toString().padStart(2, '0')}`;
            }

            const boxWidth = 31;
            const boxHeight = 18;

            // Calculate dynamic X position
            let targetX = timerX;
            if (window.CountdownPositioning) {
                // Use exact time for smooth animation (sub-second precision)
                let exactElapsed = this.currentCandleElapsed;
                if (this.candleStartTime) {
                    exactElapsed = (Date.now() - this.candleStartTime) / 1000;
                    // Clamp for safety
                    if (exactElapsed < 0) exactElapsed = 0;
                    if (exactElapsed > secondsPerCandle) exactElapsed = secondsPerCandle;
                }

                targetX = window.CountdownPositioning.calculatePosition(candleRightEdge, exactElapsed, secondsPerCandle);
            }
            const fixedBoxX = targetX - boxWidth / 2;
            const fixedBoxY = exactY - boxHeight / 2 - 1;

            // Update DOM-based timer box (Z-index 16)
            let timerBox = document.querySelector('.candle-timer-box');
            if (!timerBox) {
                timerBox = document.createElement('div');
                timerBox.className = 'candle-timer-box';
                const chartContainer = document.getElementById('chartContainer');
                if (chartContainer) chartContainer.appendChild(timerBox);
            }

            if (timerBox) {
                timerBox.style.left = fixedBoxX + 'px';
                timerBox.style.top = fixedBoxY + 'px';
                timerBox.style.width = boxWidth + 'px';
                timerBox.style.height = boxHeight + 'px';
                timerBox.innerText = timerText;
                timerBox.style.display = 'flex';
            }
        } else {
            // Hide timer if no candle data
            const timerBox = document.querySelector('.candle-timer-box');
            if (timerBox) timerBox.style.display = 'none';
        }

        // Draw blue price box last (highest z-index)
        const padding = 8;
        const borderRadius = 9;
        const referenceWidth = 55;
        const boxHeight = 22;
        const fixedPriceBoxY = exactY - 12;

        const priceText = this.formatPrice(this.currentPrice);

        this.ctx.font = '600 11px Roboto,Arial,Helvetica,sans-serif';
        const textWidth = this.ctx.measureText(priceText).width;
        const boxWidth = Math.round(Math.max(referenceWidth, textWidth + padding * 2));

        const fixedRightEdge = Math.round(a.left + a.width - 8 + referenceWidth);
        const fixedPriceBoxX = fixedRightEdge - boxWidth;

        this.ctx.fillStyle = '#2B99FF';
        this.ctx.beginPath();
        this.ctx.roundRect(fixedPriceBoxX, fixedPriceBoxY, boxWidth, boxHeight, borderRadius);
        this.ctx.fill();

        this.ctx.fillStyle = '#D6EBFF';
        this.ctx.textAlign = 'center';
        this.ctx.fillText(priceText, Math.round(fixedPriceBoxX + boxWidth / 2), Math.round(fixedPriceBoxY + boxHeight / 2 + 4));

        // Sync Overlay Position (60fps)
        if (window.currentOverlayType) {
            const overlay = document.getElementById('chart-hover-overlay');
            if (overlay) {
                const chartContainer = document.getElementById('chartContainer');
                // Adjust for exact alignment with horizontal dashed price line
                const adjustedPriceLineY = exactY - 1;
                const priceLinePercent = chartContainer ? (adjustedPriceLineY / chartContainer.clientHeight) * 100 : 50;

                overlay.style.setProperty('--price-line-position', `${priceLinePercent}%`);

                // Ensure class matches state
                const expectedClass = `chart-hover-overlay ${window.currentOverlayType === 'up' ? 'up-overlay' : 'down-overlay'}`;
                if (overlay.className !== expectedClass) {
                    overlay.className = expectedClass;
                }
            }
        }
    }

    drawCurrentCandleVerticalLine() {
        const c = this.candleData[this.currentCandleIndex];
        if (!c) return;

        // Check if there's an active expiration effect that should replace the dashed line
        const hasActiveExpiration = this.expirationEffects && this.expirationEffects.some(effect => {
            const elapsed = Date.now() - effect.startTime;
            return elapsed < effect.duration;
        });

        const a = this.getChartArea();
        const twoCm = 100;
        const startX = a.left + this.panOffset + twoCm;
        const i = this.currentCandleIndex;

        const isOddCandle = (i % 2) === 0;
        const gridIndex = Math.floor(i / 2);
        const candleX = isOddCandle ?
            startX + gridIndex * twoCm - this.config.candleWidth / 2 :
            startX + gridIndex * twoCm + twoCm / 2 - this.config.candleWidth / 2;

        const centerX = candleX + this.config.candleWidth / 2;

        const currentHigh = this.runningHigh ?? c.open;
        const currentLow = this.runningLow ?? c.open;
        const highY = this.priceToY(currentHigh) - 10;
        const lowY = this.priceToY(currentLow) + 10;

        // Only draw dashed line if no active expiration effect
        if (!hasActiveExpiration) {
            this.ctx.strokeStyle = '#ffffff';
            this.ctx.lineWidth = 1;
            this.ctx.setLineDash([5, 3]);

            this.ctx.beginPath();
            this.ctx.moveTo(centerX, a.top);
            this.ctx.lineTo(centerX, highY);
            this.ctx.stroke();

            this.ctx.beginPath();
            this.ctx.moveTo(centerX, lowY);
            this.ctx.lineTo(centerX, a.top + a.height);
            this.ctx.stroke();

            this.ctx.setLineDash([]);
        }

        // Draw SVG icon and "beginning of trade" text
        const chevronX = centerX - 10; // 10 pixels to the left of the vertical line
        const chevronY = a.top + 61; // Moved up by 2 pixels

        // Create SVG icon element
        const chartContainer = document.getElementById('chartContainer');
        if (chartContainer) {
            const existingBeginIcon = chartContainer.querySelector('.beginning-trade-icon');
            if (existingBeginIcon) existingBeginIcon.remove();

            const svgIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            svgIcon.setAttribute('class', 'icon-arrow-triangle-small-up shutter-icon beginning-trade-icon');
            svgIcon.style.position = 'absolute';
            svgIcon.style.left = (chevronX - 6) + 'px';
            svgIcon.style.top = (chevronY - 6) + 'px';
            svgIcon.style.width = '12px';
            svgIcon.style.height = '12px';
            svgIcon.style.pointerEvents = 'none';
            svgIcon.style.zIndex = '10';
            svgIcon.style.fill = '#535661';
            svgIcon.style.transform = 'rotate(90deg)';

            const useElement = document.createElementNS('http://www.w3.org/2000/svg', 'use');
            useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', './svg/spritemap.svg#icon-arrow-triangle-small-up');
            svgIcon.appendChild(useElement);
            chartContainer.appendChild(svgIcon);
        }

        // Draw "beginning of trade" text below the icon
        this.ctx.fillStyle = '#535661';/*(HK chng)*/
        this.ctx.font = '600 12px Arial';/*(HK chng)*/
        this.ctx.textAlign = 'right';
        this.ctx.fillText('Beginning of trade', chevronX, chevronY + 18);

        // Draw "End of Trade" vertical line
        this.drawEndOfTradeVerticalLine();
    }

    drawEndOfTradeVerticalLine() {
        const c = this.candleData[this.currentCandleIndex];
        if (!c) return;

        const a = this.getChartArea();
        const twoCm = 100;
        const startX = a.left + this.panOffset + twoCm;
        const i = this.currentCandleIndex;

        const secondsPerCandle = this.timeframeIntervals[this.currentTimeframe] || 60;
        const hasManualTime = window.isManualTimeSet && window.manualTimeOffset !== undefined;

        let endCandleIndex;
        let totalDurationSeconds;

        if (hasManualTime) {
            // Use manual time - always synchronize with remaining candle time
            const manualTimeSeconds = window.manualTimeOffset * 60;
            const remainingInCurrentCandle = secondsPerCandle - this.currentCandleElapsed;
            totalDurationSeconds = remainingInCurrentCandle + manualTimeSeconds;

            const additionalCandlesNeeded = Math.ceil(manualTimeSeconds / secondsPerCandle);
            endCandleIndex = i + additionalCandlesNeeded + 1;
        } else {
            // Use 30-second sliding logic
            if (this.currentCandleElapsed >= 30) {
                // Add 1 minute and capture second next candle middle
                totalDurationSeconds = (secondsPerCandle - this.currentCandleElapsed) + 60;
                endCandleIndex = i + 2;
            } else {
                // Synchronize with remaining candle time
                totalDurationSeconds = secondsPerCandle - this.currentCandleElapsed;
                endCandleIndex = i + 1;
            }
        }

        const isOddCandle = (endCandleIndex % 2) === 0;
        const gridIndex = Math.floor(endCandleIndex / 2);
        const endCandleX = isOddCandle ?
            startX + gridIndex * twoCm :
            startX + gridIndex * twoCm + twoCm / 2;

        // Draw straight vertical line (with pixel snapping for sharpness)
        this.ctx.strokeStyle = '#bbb3b3ff';
        this.ctx.lineWidth = 0.5;
        this.ctx.setLineDash([]);
        this.ctx.imageSmoothingEnabled = false;

        const pixelX = Math.floor(endCandleX) + 0.5;
        this.ctx.beginPath();
        this.ctx.moveTo(pixelX, a.top);
        this.ctx.lineTo(pixelX, a.top + a.height);
        this.ctx.stroke();

        // Draw SVG icon and "End of trade" text
        const arrowX = endCandleX + 10;
        const arrowY = a.top + 61; // Moved up by 2 pixels

        // Create SVG icon element
        if (chartContainer) {
            const existingEndIcon = chartContainer.querySelector('.end-trade-icon');
            if (existingEndIcon) existingEndIcon.remove();

            const svgIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            svgIcon.setAttribute('class', 'icon-arrow-triangle-small-up shutter-icon end-trade-icon');
            svgIcon.style.position = 'absolute';
            svgIcon.style.left = (arrowX - 6) + 'px';
            svgIcon.style.top = (arrowY - 6) + 'px';
            svgIcon.style.width = '12px';
            svgIcon.style.height = '12px';
            svgIcon.style.pointerEvents = 'none';
            svgIcon.style.zIndex = '10';
            svgIcon.style.fill = '#535661';
            svgIcon.style.transform = 'rotate(-90deg)';

            const useElement = document.createElementNS('http://www.w3.org/2000/svg', 'use');
            useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', './svg/spritemap.svg#icon-arrow-triangle-small-up');
            svgIcon.appendChild(useElement);
            chartContainer.appendChild(svgIcon);
        }

        this.ctx.fillStyle = '#535661';
        this.ctx.font = '600 12px Roboto,Arial,Helvetica,sans-serif';
        this.ctx.textAlign = 'left';
        this.ctx.fillText('End of trade', arrowX, arrowY + 18);

        // Timer always shows remaining time synchronized with candle
        const totalCountdown = totalDurationSeconds;

        let timerText;
        if (totalCountdown >= 3600) {
            const hours = Math.floor(totalCountdown / 3600);
            const minutes = Math.floor((totalCountdown % 3600) / 60);
            const seconds = totalCountdown % 60;
            timerText = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
        } else if (totalCountdown >= 60) {
            const minutes = Math.floor(totalCountdown / 60);
            const seconds = totalCountdown % 60;
            timerText = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
        } else {
            timerText = `00:${Math.max(0, totalCountdown).toString().padStart(2, '0')}`;
        }

        this.ctx.fillStyle = '#535661';
        this.ctx.font = '600 13px Arial';
        this.ctx.textAlign = 'left';
        this.ctx.fillText(timerText, arrowX, arrowY + 32);
    }



    drawCrosshair() {
        const a = this.getChartArea();

        // Check for hover on zoom buttons to hide crosshair
        const centerX = a.left + a.width / 2;
        const bottomY = a.top + a.height;
        const isHoverMinus = this.mouseX >= centerX + 14 && this.mouseX <= centerX + 14 + 23 && this.mouseY >= bottomY - 14 && this.mouseY <= bottomY - 14 + 23;
        const isHoverPlus = this.mouseX >= centerX + 39 && this.mouseX <= centerX + 39 + 23 && this.mouseY >= bottomY - 14 && this.mouseY <= bottomY - 14 + 23;
        if (isHoverMinus || isHoverPlus) {
            return;
        }

        this.ctx.strokeStyle = '#bbb3b3ff';
        this.ctx.lineWidth = 0.5;
        this.ctx.setLineDash([]);
        this.ctx.imageSmoothingEnabled = false;

        // Draw vertical crosshair line and time point
        if (this.mouseX >= a.left && this.mouseX <= a.left + a.width + this.config.padding.right) {
            const pixelX = Math.floor(this.mouseX) + 0.5;
            this.ctx.beginPath();
            this.ctx.moveTo(pixelX, a.top);
            this.ctx.lineTo(pixelX, a.top + a.height);
            this.ctx.stroke();

            // Continuous second-by-second progression algorithm
            const twoCm = 100;
            const startX = a.left + this.panOffset + twoCm;
            const firstWickX = startX; // First candle wick position

            let timeText = '';
            if (this.candleData && this.candleData.length > 0) {
                const firstCandle = this.candleData[0];
                if (firstCandle && firstCandle.timestamp) {
                    // Only show time from first wick onwards
                    if (this.mouseX < firstWickX) {
                        timeText = '';
                    } else {
                        // Only calculate time when inside candle areas (ignore gaps)
                        let found = false;

                        for (let i = 0; i < this.candleData.length && !found; i++) {
                            const isOddCandle = (i % 2) === 0;
                            const gridIndex = Math.floor(i / 2);
                            const candleX = isOddCandle ?
                                startX + gridIndex * twoCm - this.config.candleWidth / 2 :
                                startX + gridIndex * twoCm + twoCm / 2 - this.config.candleWidth / 2;

                            const candleEndX = candleX + this.config.candleWidth;
                            const wickX = candleX + this.config.candleWidth / 2;

                            // Only process if mouse is inside this candle area
                            if (this.mouseX >= candleX && this.mouseX <= candleEndX) {
                                const positionInCandle = this.mouseX - candleX;
                                const wickPosition = this.config.candleWidth / 2;

                                let candleSeconds;
                                if (positionInCandle <= wickPosition) {
                                    if (i === 0) {
                                        // First candle left half: starts at 0
                                        candleSeconds = 0;
                                    } else {
                                        // Other candles left half: 31s to 60s (next minute)
                                        const progress = positionInCandle / wickPosition;
                                        candleSeconds = Math.min(60, 31 + Math.floor(progress * 30)); // 31s to 60s (overflow protected)
                                    }
                                } else {
                                    // Right half: wick (0s) to 30s
                                    const progress = (positionInCandle - wickPosition) / wickPosition;
                                    candleSeconds = Math.floor(progress * 30);
                                }

                                let totalSeconds;
                                if (i === 0) {
                                    totalSeconds = candleSeconds;
                                } else if (positionInCandle <= wickPosition) {
                                    // Left half of non-first candles: continue from previous candle's 30s
                                    totalSeconds = (i - 1) * 60 + candleSeconds;
                                } else {
                                    // Right half: normal calculation
                                    totalSeconds = i * 60 + candleSeconds;
                                }
                                const displayTime = new Date(firstCandle.timestamp + totalSeconds * 1000);

                                // Check if at wick
                                const isAtWick = Math.abs(positionInCandle - wickPosition) < 3;

                                if (isAtWick) {
                                    const hours = displayTime.getHours();
                                    const minutes = displayTime.getMinutes();
                                    timeText = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
                                } else {
                                    timeText = displayTime.toLocaleTimeString([], {
                                        hour: '2-digit',
                                        minute: '2-digit',
                                        second: '2-digit',
                                        hour12: false
                                    });
                                }
                                found = true;
                            }
                        }

                        // If not inside any candle area, don't show time (ignore gaps)
                        if (!found) {
                            timeText = '';
                        }
                    }
                }
            }

            if (timeText && timeText !== '') {
                // Draw time box at bottom of chart
                this.ctx.font = '11px Roboto,Arial,Helvetica,sans-serif';
                const timeTextWidth = this.ctx.measureText(timeText).width;
                const timePadding = 8;
                const timeBorderRadius = 2;

                const timeBoxX = this.mouseX - timeTextWidth / 2 - timePadding;
                const timeBoxY = a.top + a.height + 5;
                const timeBoxWidth = timeTextWidth + timePadding * 2;
                const timeBoxHeight = 22;

                this.ctx.fillStyle = '#ffffff';
                this.ctx.beginPath();
                this.ctx.roundRect(timeBoxX, timeBoxY, timeBoxWidth, timeBoxHeight, timeBorderRadius);
                this.ctx.fill();

                this.ctx.fillStyle = '#353131ff';
                this.ctx.font = '11px Roboto,Arial,Helvetica,sans-serif';
                this.ctx.textAlign = 'center';
                this.ctx.fillText(timeText, this.mouseX, timeBoxY + 15);
            }
        }

        // Draw horizontal crosshair line and price point
        if (this.mouseY >= a.top && this.mouseY <= a.top + a.height) {
            const padding = 8;
            const borderRadius = 2;
            const referenceWidth = 55;
            const priceBoxHeight = 21;
            const priceBoxY = this.mouseY - 12;

            // Draw horizontal line at original mouse Y position
            const pixelY = Math.floor(this.mouseY) + 0.5;
            this.ctx.beginPath();
            this.ctx.moveTo(a.left, pixelY);
            this.ctx.lineTo(a.left + a.width, pixelY);
            this.ctx.stroke();

            // Crosshair pricebox
            // Calculate price directly from mouseY with fine-tuning
            const price = this.yToPrice(this.mouseY);
            const priceText = this.formatPrice(price);

            this.ctx.font = '11px Roboto,Arial,Helvetica,sans-serif';
            const textWidth = this.ctx.measureText(priceText).width;
            const calculatedWidth = textWidth + padding * 2;
            const originalLeftEdge = a.left + a.width - 8;
            const fixedRightEdge = originalLeftEdge + referenceWidth;
            const minWidth = referenceWidth;
            const priceBoxWidth = Math.max(minWidth, calculatedWidth);
            const priceBoxX = fixedRightEdge - priceBoxWidth;

            this.ctx.fillStyle = '#ffffff';
            this.ctx.beginPath();
            this.ctx.roundRect(priceBoxX, priceBoxY, priceBoxWidth, priceBoxHeight, borderRadius);
            this.ctx.fill();

            this.ctx.fillStyle = '#535353ff';
            this.ctx.font = '11px Roboto,Arial,Helvetica,sans-serif';
            this.ctx.textAlign = 'center';
            this.ctx.fillText(priceText, priceBoxX + priceBoxWidth / 2, priceBoxY + priceBoxHeight / 2 + 4);

            // Draw icon box to the left of the price point box
            const iconBoxSize = 21;
            const iconBoxX = priceBoxX - iconBoxSize - 1;
            const iconBoxY = priceBoxY; // Adjust Y position to center with price box

            // Draw square icon box with black outline
            this.ctx.fillStyle = '#ffffff';
            this.ctx.beginPath();
            this.ctx.roundRect(iconBoxX, iconBoxY, iconBoxSize, iconBoxSize, 2);
            this.ctx.fill();
            this.ctx.stroke();

            // Check for hover on bell icon box
            // Since the box follows the mouse Y-axis, we only need to check if mouse X is within the vertical column
            if (this.mouseX >= iconBoxX && this.mouseX <= iconBoxX + iconBoxSize) {
                if (this.canvas) this.canvas.style.cursor = 'pointer';
            }

            // Create IMG element for the svgbellicon.svg icon
            const imgElement = document.createElement('img');
            imgElement.src = './svg/svgbellicon.svg';
            imgElement.style.position = 'absolute';
            imgElement.style.left = (iconBoxX + (iconBoxSize - 17) / 2) + 'px';
            imgElement.style.top = (iconBoxY + (iconBoxSize - 20) / 2 + 0) + 'px';
            imgElement.style.width = '17px';
            imgElement.style.height = '20px';
            imgElement.style.pointerEvents = 'none';
            imgElement.style.zIndex = '50';
            imgElement.style.filter = 'drop-shadow(0 0 0 5px black)';

            // Add IMG to the chart container
            const chartContainer = document.getElementById('chartContainer');
            if (chartContainer) {
                // Remove any existing crosshair icons
                const existingIcons = chartContainer.querySelectorAll('img[src="./svg/svgbellicon.svg"]');
                existingIcons.forEach(icon => icon.remove());

                chartContainer.appendChild(imgElement);

                // Remove the IMG after a short delay to prevent accumulation
                setTimeout(() => {
                    if (imgElement.parentNode) {
                        imgElement.remove();
                    }
                }, 100);
            }
        }
    }

    drawPriceScale() {
        const a = this.getChartArea();
        // Draw transparent background for price area
        this.ctx.fillStyle = 'rgba(28, 31, 45, 0)';
        this.ctx.fillRect(a.left + a.width, 0, this.config.padding.right, a.top + a.height);
    }

    drawTimeScale() {
        const a = this.getChartArea();
        this.ctx.fillStyle = 'rgba(28, 31, 45, 0)'; this.ctx.fillRect(a.left, a.top + a.height + 10, a.width, this.config.padding.bottom - 10);
        this.ctx.fillStyle = this.config.colors.text; this.ctx.font = 'bold 12px Arial'; this.ctx.textAlign = 'center';

        const gridSpacing = 100;
        const startX = a.left + this.panOffset + gridSpacing;

        const container = document.getElementById('chartContainer');
        const fullWidth = container.clientWidth;

        for (let i = 0; i * gridSpacing < a.width + Math.abs(this.panOffset) + gridSpacing; i++) {
            const x = startX + i * gridSpacing;
            if (x >= a.left && x <= fullWidth) {
                const candleIndex = i * 2;
                if (candleIndex < this.candleData.length) {
                    const candle = this.candleData[candleIndex];

                    this.ctx.fillText(candle.time, x, a.top + a.height + 25);
                }
            }
        }

        // Draw + and - boxes (Zoom in and Zoom out) in the middle of the bottom line
        const centerX = a.left + a.width / 2;
        const bottomY = a.top + a.height;

        // Draw - box (left)
        this.ctx.fillStyle = 'rgba(66, 68, 77, 0.4)';
        this.ctx.fillRect(centerX + 14, bottomY - 14, 23, 23);
        this.ctx.fillStyle = '#8D8F96';
        this.ctx.fillRect(centerX + 21.5, bottomY - 4.5, 8, 1.5);

        // Draw + box (right)
        this.ctx.fillStyle = 'rgba(66, 68, 77, 0.4)';
        this.ctx.fillRect(centerX + 39, bottomY - 14, 23, 23);
        this.ctx.fillStyle = '#8D8F96';
        this.ctx.fillRect(centerX + 46.5, bottomY - 3.25, 8, 1.5);
        this.ctx.fillRect(centerX + 49.75, bottomY - 6.5, 1.5, 8);

        // Check for hover on - and + boxes
        if (this.canvas) {
            const isHoverMinus = this.mouseX >= centerX + 14 && this.mouseX <= centerX + 14 + 23 && this.mouseY >= bottomY - 14 && this.mouseY <= bottomY - 14 + 23;
            const isHoverPlus = this.mouseX >= centerX + 39 && this.mouseX <= centerX + 39 + 23 && this.mouseY >= bottomY - 14 && this.mouseY <= bottomY - 14 + 23;
            if (isHoverMinus || isHoverPlus) {
                this.canvas.style.cursor = 'pointer';
            }
        }
    }

    getAdaptiveBoundaries() {
        const totalCandles = this.candleData.length;
        if (!totalCandles) return { left: -200, right: 200 };
        if (totalCandles <= 3) return { left: -300, right: 200 };

        const a = this.getChartArea();
        const twoCm = 100;

        const firstCandleMaxX = twoCm - this.config.candleWidth / 2;
        const leftBoundary = -firstCandleMaxX + 20;

        const chartCenter = a.width - 400;
        const i = this.currentCandleIndex;
        const isOddCandle = (i % 2) === 0;
        const gridIndex = Math.floor(i / 2);
        const currentCandleTargetX = isOddCandle ?
            gridIndex * twoCm :
            gridIndex * twoCm + twoCm / 2;

        const maxRightOffset = chartCenter - currentCandleTargetX - twoCm;

        return {
            left: Math.min(leftBoundary, maxRightOffset - 100),
            right: Math.max(maxRightOffset + 100, 200)
        };
    }

    getMaxRightPan() {
        return this.getAdaptiveBoundaries().right;
    }

    isRunningCandleVisible() {
        const a = this.getChartArea();
        const twoCm = 100;
        const i = this.currentCandleIndex;
        const isOddCandle = (i % 2) === 0;
        const gridIndex = Math.floor(i / 2);
        const candleX = isOddCandle ?
            a.left + this.panOffset + twoCm + gridIndex * twoCm - this.config.candleWidth / 2 :
            a.left + this.panOffset + twoCm + gridIndex * twoCm + twoCm / 2 - this.config.candleWidth / 2;
        return candleX >= a.left && candleX <= a.left + a.width - this.config.candleWidth;
    }

    returnToRunningCandle() {
        const a = this.getChartArea();
        const twoCm = 100;
        const i = this.currentCandleIndex;
        const isOddCandle = (i % 2) === 0;
        const gridIndex = Math.floor(i / 2);
        const targetCandleX = isOddCandle ?
            gridIndex * twoCm :
            gridIndex * twoCm + twoCm / 2;
        const chartCenter = a.width - 400;
        const targetOffset = chartCenter - targetCandleX - twoCm;

        this.startPanAnimation(targetOffset);
        this.userDraggedAway = false;
    }

    startPanAnimation(targetOffset) {
        if (this.panAnimationId) cancelAnimationFrame(this.panAnimationId);

        const startOffset = this.panOffset;
        const distance = targetOffset - startOffset;
        const duration = 800; // 800ms animation
        const startTime = performance.now();

        const animate = (currentTime) => {
            const elapsed = currentTime - startTime;
            const progress = Math.min(elapsed / duration, 1);
            const eased = 1 - Math.pow(1 - progress, 3); // Ease out cubic

            this.panOffset = startOffset + (distance * eased);

            if (progress < 1) {
                this.panAnimationId = requestAnimationFrame(animate);
            } else {
                this.panAnimationId = null;
            }
        };

        this.panAnimationId = requestAnimationFrame(animate);
    }


}

const chart = new SmoothTradingChart('chartCanvas');
window.chart = chart;

// Initialize reversal detection
setTimeout(() => {
    if (window.chart) {
        // Integrate new reversal detection algorithm
        window.chart.reversalBoxes = window.chart.reversalBoxes || [];

        // Synchronize detection with 60fps draw loop (zero-lag movement)
        window.chart.updateHighLowBoxes = window.chart.detectMarketReversals;

        // Hook into draw loop (Monkey-patching)
        // Hook into draw loop (Monkey-patching REMOVED - integrated into main class)
        // Cursor reset is now handled in main draw loop or implicit default

        console.log('✅ Reversal detection algorithm integrated');

        console.log('✅ Reversal detection algorithm integrated');
    }
}, 2000);
// Trade placement methods
chart.placeTrade = function (type, amount, payout, tradeId) {
    let durationMinutes = window.getTimeOffsetMinutes?.() || 1;

    if (window.isManualTimeSet && window.manualTimeOffset !== undefined) {
        durationMinutes = window.manualTimeOffset;
    }

    let tradeDuration;
    // Original algorithm restored
    if (window.isManualTimeSet && durationMinutes > 0) {
        tradeDuration = durationMinutes * 60;
    } else {
        if (this.currentCandleElapsed >= 30) {
            tradeDuration = (60 - this.currentCandleElapsed) + 60;
        } else {
            tradeDuration = 60 - this.currentCandleElapsed;
        }
    }

    /*
    // 🔧 DEVELOPMENT CODE (COMMENTED OUT)
    if (DEV_MODE) {
        const config = getCurrentConfig();
        tradeDuration = config.TRADE_DURATION_SECONDS;
        console.log('🚨 DEV MODE: Using', tradeDuration, 'second trade duration');
    } else {
        // Production Mode: Use normal timing logic
        if (window.isManualTimeSet && durationMinutes > 0) {
            tradeDuration = durationMinutes * 60;
        } else {
            if (this.currentCandleElapsed >= 30) {
                tradeDuration = (60 - this.currentCandleElapsed) + 60;
            } else {
                tradeDuration = 60 - this.currentCandleElapsed;
            }
        }
    }
    */

    const calculatedPayout = window.calculateExactPayout ? window.calculateExactPayout(amount) : amount * 0.93;

    // Get current asset info from sidebar
    const sidebarAssetName = document.querySelector('.asset-name');
    const currentAssetName = (sidebarAssetName && sidebarAssetName.textContent) ? sidebarAssetName.textContent : 'USD/BDT (OTC)';
    const assetConfig = getAssetConfig(currentAssetName);
    const roundedPrice = parseFloat(this.currentPrice.toFixed(assetConfig.decimalPoints));

    const tradeLine = {
        type, startCandleIndex: this.currentCandleIndex, endCandleIndex: this.currentCandleIndex + Math.ceil(tradeDuration / 60),
        startCandleElapsed: this.currentCandleElapsed, price: roundedPrice, color: type === 'up' ? '#0FA054' : '#E75B4D',
        amount, payout: calculatedPayout, countdown: tradeDuration, totalDuration: tradeDuration, resolved: false, tradeId
    };

    this.tradelines.push(tradeLine);

    // Immediately show progress bar
    this.updateAssetCardTradeStatus(tradeLine);
    const sidebarAssetReturn = document.querySelector('.asset-return');
    const currentPayoutPercentage = (sidebarAssetReturn && sidebarAssetReturn.textContent) ? sidebarAssetReturn.textContent : '80%';

    const tradeData = {
        id: tradeId,
        type,
        amount,
        payout: 0,
        startTime: Date.now(),
        duration: tradeDuration,
        startPrice: this.currentPrice,
        result: 'pending',
        assetName: currentAssetName,
        payoutPercentage: currentPayoutPercentage
    };

    window.tradeHistory.unshift(tradeData);
    if (window.tradeHistory.length > 50) window.tradeHistory.pop();
    localStorage.setItem('tradeHistory', JSON.stringify(window.tradeHistory));
    window.updateTradeHistoryDisplay();
};

chart.placeUpTrade = function (amount, payout, direction, tradeId) { this.placeTrade('up', amount, payout, tradeId); };
chart.placeDownTrade = function (amount, payout, direction, tradeId) { this.placeTrade('down', amount, payout, tradeId); };

chart.drawTradeLines = function () {
    this.tradelines = this.tradelines.filter(line => {
        const candlesPassed = this.currentCandleIndex - line.startCandleIndex;
        const secondsInCurrentCandle = this.currentCandleElapsed;
        const elapsed = (candlesPassed * 60) + secondsInCurrentCandle - line.startCandleElapsed;

        line.countdown = Math.max(0, line.totalDuration - elapsed);

        if (elapsed >= line.totalDuration) {
            if (!line.delayStarted && !line.resolved) {
                line.delayStarted = true;
                line.countdown = 0;

                // Capture current state for accurate resolution after delay
                let finalPrice = this.currentPrice;
                const endCandle = this.candleData[line.endCandleIndex];
                if (endCandle && endCandle.isComplete) {
                    finalPrice = endCandle.close;
                }
                const resolutionPrice = finalPrice;
                const resolutionCandleIndex = this.currentCandleIndex;

                setTimeout(() => {
                    const won = (line.type === 'up' && resolutionPrice > line.price) ||
                        (line.type === 'down' && resolutionPrice < line.price);

                    const tradeIndex = window.tradeHistory.findIndex(t => t.id === line.tradeId);
                    if (tradeIndex !== -1) {
                        const tradeAsset = window.tradeHistory[tradeIndex].assetName || this.asset;
                        const assetConfig = getAssetConfig(tradeAsset);

                        const pipMultiplier = 1 / assetConfig.pipValue;
                        const startPips = Math.round(line.price * pipMultiplier);
                        const endPips = Math.round(resolutionPrice * pipMultiplier);
                        const pipDifference = Math.abs(endPips - startPips);
                        const isDraw = pipDifference === 0;

                        let result, payout;
                        if (isDraw) {
                            result = 'refund';
                            payout = line.amount;
                            window.tradeHistory[tradeIndex].result = 'refund';
                            window.tradeHistory[tradeIndex].payout = line.amount;
                            window.updateDemoBalance(line.amount);
                        } else {
                            result = won ? 'win' : 'loss';
                            payout = won ? line.payout : 0;
                            window.tradeHistory[tradeIndex].result = won ? 'win' : 'loss';
                            window.tradeHistory[tradeIndex].payout = won ? line.payout : 0;
                        }

                        if (window.showTradeResultAlert) {
                            const candlesSpanned = Math.ceil(line.totalDuration / 60);
                            const tradeEndCandleIndex = line.startCandleIndex + candlesSpanned;
                            window.showTradeResultAlert(result, payout, line.amount, tradeEndCandleIndex, resolutionPrice);
                        }

                        this.addTradeExpirationEffect(line, result, resolutionPrice);
                        this.removeAssetCardTradeStatus();

                        localStorage.setItem('tradeHistory', JSON.stringify(window.tradeHistory));
                        window.updateTradeHistoryDisplay();

                        if (window.showTradeClosedAlert) {
                            const tradeData = window.tradeHistory[tradeIndex];
                            const assetName = tradeData.assetName || 'USD/BDT (OTC)';
                            setTimeout(() => {
                                window.showTradeClosedAlert(assetName, line.totalDuration, payout);
                            }, 500);
                        }

                        if (typeof updateTabDisplay === 'function') {
                            updateTabDisplay();
                        }
                    }

                    if (won) {
                        window.updateDemoBalance(line.payout);
                        window.audioManager.playTradeWin();
                    } else {
                        window.audioManager.playTradeLoss();
                    }

                    line.resolved = true;
                    // Trade Result Delay
                }, 1000);
            }

            return !line.resolved;
        }

        return elapsed < line.totalDuration;
    });

    // Remove trade status box if no active trades
    if (this.tradelines.length === 0) {
        this.removeAssetCardTradeStatus();
    }

    const a = this.getChartArea();
    const twoCm = 100;
    const startX = a.left + this.panOffset + twoCm;

    this.tradelines.forEach(line => {
        const isStartOdd = (line.startCandleIndex % 2) === 0;
        const startGridIndex = Math.floor(line.startCandleIndex / 2);
        const startCenterX = isStartOdd ?
            startX + startGridIndex * twoCm :
            startX + startGridIndex * twoCm + twoCm / 2;

        const candlesSpanned = Math.ceil(line.totalDuration / 60);
        const actualEndCandleIndex = line.startCandleIndex + candlesSpanned;

        const isEndOdd = (actualEndCandleIndex % 2) === 0;
        const endGridIndex = Math.floor(actualEndCandleIndex / 2);
        let endCenterX = isEndOdd ?
            startX + endGridIndex * twoCm :
            startX + endGridIndex * twoCm + twoCm / 2;

        if (Math.abs(endCenterX - startCenterX) < 50) {
            endCenterX = startCenterX + 50;
        }

        const priceY = this.priceToY(line.price);

        this.ctx.strokeStyle = line.color;
        this.ctx.lineWidth = 2;
        this.ctx.setLineDash([]);

        this.ctx.beginPath();
        this.ctx.moveTo(startCenterX, priceY);
        this.ctx.lineTo(endCenterX, priceY);
        this.ctx.stroke();

        const radius = 4;

        this.ctx.fillStyle = '#ffffff';
        this.ctx.beginPath();
        this.ctx.arc(startCenterX, priceY, radius, 0, 2 * Math.PI);
        this.ctx.fill();
        this.ctx.strokeStyle = line.color;
        this.ctx.lineWidth = 2;
        this.ctx.stroke();

        this.ctx.fillStyle = '#ffffff';
        this.ctx.beginPath();
        this.ctx.arc(endCenterX, priceY, radius, 0, 2 * Math.PI);
        this.ctx.fill();
        this.ctx.strokeStyle = line.color;
        this.ctx.lineWidth = 2;
        this.ctx.stroke();

        // Draw horizontal line from trade info box right edge to chart right edge
        const amountText = `${line.amount} \u0024`;
        const timerText = `${Math.floor(line.countdown / 60).toString().padStart(2, '0')}:${(line.countdown % 60).toString().padStart(2, '0')}`;
        const boxWidth = line.delayStarted ? 
            20 + this.ctx.measureText(amountText).width + 12 :
            20 + this.ctx.measureText(amountText).width + 2 + this.ctx.measureText(timerText).width + 12;
        const boxX = startCenterX - boxWidth - 5;

        // Draw shadow first
        this.ctx.globalAlpha = 0.2;
        this.ctx.strokeStyle = line.color;
        this.ctx.lineWidth = 1;
        this.ctx.setLineDash([]);

        this.ctx.beginPath();
        this.ctx.moveTo(boxX + boxWidth, priceY + 1);
        this.ctx.lineTo(a.left + a.width, priceY + 1);
        this.ctx.stroke();

        // Draw main line
        this.ctx.globalAlpha = 0.4;
        this.ctx.strokeStyle = line.type === 'up' ? '#0FA054' : '#E75B4D';

        this.ctx.beginPath();
        this.ctx.moveTo(boxX + boxWidth, priceY);
        this.ctx.lineTo(a.left + a.width, priceY);
        this.ctx.stroke();
        this.ctx.globalAlpha = 1;

    });

    // Draw trade info boxes with overlap prevention
    const boxPositions = [];
    this.tradelines.forEach(line => {
        const isStartOdd = (line.startCandleIndex % 2) === 0;
        const startGridIndex = Math.floor(line.startCandleIndex / 2);
        const startCenterX = isStartOdd ?
            startX + startGridIndex * twoCm :
            startX + startGridIndex * twoCm + twoCm / 2;
        const priceY = this.priceToY(line.price);

        this.drawTradeInfoBox(line, startCenterX, priceY, boxPositions);

        // Update asset card trade status box
        this.updateAssetCardTradeStatus(line);
    });
};

//Trade Information Box with Overlap Prevention
chart.drawTradeInfoBox = function (line, startX, y, boxPositions) {
    const timerText = line.delayStarted ? "" : `${Math.floor(line.countdown / 60).toString().padStart(2, '0')}:${(line.countdown % 60).toString().padStart(2, '0')}`;

    this.ctx.font = '14px Arial';
    const amountText = `${line.amount} \u0024`;
    const boxWidth = line.delayStarted ? 
        20 + this.ctx.measureText(amountText).width + 12 :
        20 + this.ctx.measureText(amountText).width + 2 + this.ctx.measureText(timerText).width + 12;
    const boxHeight = 20;

    let boxX = startX - boxWidth - 5;
    const boxY = y - boxHeight / 2;

    // Check for overlaps and adjust position
    const checkOverlap = (x, y, w, h) => {
        return boxPositions.some(pos =>
            x < pos.x + pos.width && x + w > pos.x && y < pos.y + pos.height && y + h > pos.y
        );
    };

    while (checkOverlap(boxX, boxY, boxWidth, boxHeight) && boxX > 10) {
        boxX -= boxWidth + 5;
    }

    boxPositions.push({ x: boxX, y: boxY, width: boxWidth, height: boxHeight });

    this.ctx.globalAlpha = 0.95;
    this.ctx.fillStyle = line.color;
    this.ctx.beginPath();
    this.ctx.roundRect(boxX, boxY, boxWidth, boxHeight, 8);
    this.ctx.fill();
    this.ctx.globalAlpha = 1;

    const iconX = boxX + 12, iconY = boxY + boxHeight / 2;

    this.ctx.fillStyle = 'rgba(255, 255, 255, 0.4)';
    this.ctx.beginPath();
    this.ctx.arc(iconX, iconY, 7, 0, 2 * Math.PI);
    this.ctx.fill();

    this.ctx.fillStyle = '#ffffff';
    this.ctx.font = '8px FontAwesome';
    this.ctx.textAlign = 'center';
    this.ctx.fillText(line.type === 'up' ? '↑' : '↓', iconX, iconY + 3);

    const amountNumber = `${line.amount}`;
    const dollarSign = ' \u0024';

    // Set transparency for text elements
    this.ctx.globalAlpha = 0.8;

    // Draw amount number
    this.ctx.fillStyle = '#FBE6E4';
    this.ctx.font = '200 14px Arial';
    this.ctx.textAlign = 'left';
    this.ctx.fillText(amountNumber, iconX + 12, boxY + boxHeight / 2 + 4);

    // Draw dollar sign (bold)
    this.ctx.font = 'bold 14px Arial';
    this.ctx.fillText(dollarSign, iconX + 12 + this.ctx.measureText(amountNumber).width, boxY + boxHeight / 2 + 4);

    // Dynamic gap based on amount digits
    const amountDigits = amountNumber.length;
    const timerGap = (amountDigits <= 2) ? 10 : 15;

    this.ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';
    this.ctx.font = 'bold 11px Arial';
    this.ctx.fillText(timerText, iconX + 12 + this.ctx.measureText(amountNumber).width + this.ctx.measureText(dollarSign).width + timerGap, boxY + boxHeight / 2 + 3);

    // Reset alpha
    this.ctx.globalAlpha = 1;

    // Check for hover (Box OR Popup)
    const popupWidth = 150;
    const popupHeight = 79;
    const popupX = boxX + (boxWidth / 2) - (popupWidth / 2);
    const popupY = boxY - 10 - popupHeight;

    const isHoveredBox = this.mouseX >= boxX && this.mouseX <= boxX + boxWidth &&
        this.mouseY >= boxY && this.mouseY <= boxY + boxHeight;

    const isHoveredPopup = this.mouseX >= popupX && this.mouseX <= popupX + popupWidth &&
        this.mouseY >= popupY && this.mouseY <= boxY;

    // Logic: Trigger on Box, Sustain on Popup
    if (isHoveredBox) {
        this.activePopupTrade = line;
    } else if (this.activePopupTrade === line && !isHoveredPopup && !isHoveredBox) {
        this.activePopupTrade = null;
    }

    // Only draw if this line is the active one and we are in the zone
    if (this.activePopupTrade === line && (isHoveredBox || isHoveredPopup)) {
        // Draw popup on top
        this.drawTradeHoverPopup(line, boxX, boxY, boxWidth);
    }
};

// Trade Hover Popup
chart.drawTradeHoverPopup = function (line, refX, refY, refWidth) {
    const popupWidth = 150;
    const popupHeight = 79;

    // Center popup relative to the trade info box
    const popupX = refX + (refWidth / 2) - (popupWidth / 2);
    // Position 10px above the trade info box
    const popupY = refY - 10 - popupHeight;

    this.ctx.save();

    // Background (no shadow)
    this.ctx.fillStyle = '#383D4F';
    this.ctx.beginPath();
    this.ctx.roundRect(popupX, popupY, popupWidth, popupHeight, 3);
    this.ctx.fill();

    // Header Text: "Sell the trade"
    this.ctx.fillStyle = '#d3d3d3ff';
    this.ctx.font = 'bold 14px Arial';
    this.ctx.textAlign = 'center';
    this.ctx.fillText('Sell the trade', popupX + (popupWidth / 2), popupY + 23);

    // Calculate Sell Amount
    // Countdown from 30% to 0% (decrease 1% per second over 30 seconds)
    const candlesPassed = this.currentCandleIndex - line.startCandleIndex;
    const elapsed = (candlesPassed * 60) + this.currentCandleElapsed - line.startCandleElapsed;
    const remainingTime = line.totalDuration - elapsed;
    const sellPercentage = Math.max(0, 30 - elapsed);
    let sellNowAmount = (line.amount * (sellPercentage / 100)).toFixed(2);

    // Show hyphen if countdown finished (30s), trade resolved, or trade has ≤20 seconds remaining
    if (elapsed >= 30 || line.resolved || remainingTime <= 20) {
        sellNowAmount = '-';
    }

    // Sell Button Box (127x30)
    const buttonWidth = 127;
    const buttonHeight = 30;
    const buttonX = popupX + (popupWidth - buttonWidth) / 2;
    const buttonY = popupY + 37; // Positioned below text

    this.ctx.fillStyle = '#606472';
    this.ctx.beginPath();
    this.ctx.roundRect(buttonX, buttonY, buttonWidth, buttonHeight, 3);
    this.ctx.fill();

    // Sell Amount Text inside button
    this.ctx.fillStyle = '#FFFFFF'; // White text on dark button
    this.ctx.font = 'bold 14px Arial';
    this.ctx.textAlign = 'center';

    // Format text: show hyphen alone, or amount with dollar sign
    const displayText = sellNowAmount === '-' ? '-' : `${sellNowAmount} \u0024`;
    this.ctx.fillText(displayText, buttonX + (buttonWidth / 2), buttonY + 20);

    // Check for hover on button specifically to set cursor
    if (this.mouseX >= buttonX && this.mouseX <= buttonX + buttonWidth &&
        this.mouseY >= buttonY && this.mouseY <= buttonY + buttonHeight) {
        if (this.canvas) this.canvas.style.cursor = 'pointer';
    }

    this.ctx.restore();
};
chart.addTradeExpirationEffect = function (line, result, finalPrice) {
    // Determine line color based on result
    let lineColor;
    if (result === 'win' || result === 'refund') {
        lineColor = '#0FA054'; // Green
    } else {
        lineColor = '#E75B4D'; // Red
    }

    // Create expiration effect object with candle index (not fixed coordinates)
    const expirationEffect = {
        candleIndex: this.currentCandleIndex, // Store candle index instead of x coordinate
        price: finalPrice, // Store price instead of y coordinate
        color: lineColor,
        startTime: Date.now(),
        duration: 5000 // 5 seconds (original algorithm)
    };

    // Initialize expiration effects array if not exists
    if (!this.expirationEffects) {
        this.expirationEffects = [];
    }

    // Add the effect
    this.expirationEffects.push(expirationEffect);

    // Store effect reference for synchronized removal
    expirationEffect.alertRef = window.currentTradeResultAlert;

    // Clean up expired effects synchronized with alert
    const config = window.getCurrentConfig ? window.getCurrentConfig() : { TRADE_RESULT_DURATION: 4000 };
    setTimeout(() => {
        this.expirationEffects = this.expirationEffects.filter(effect => effect !== expirationEffect);
        // Remove alert simultaneously if it exists
        if (window.currentTradeResultAlert && window.currentTradeResultAlert.parentNode) {
            window.currentTradeResultAlert.remove();
            window.currentTradeResultAlert = null;
        }
    }, config.TRADE_RESULT_DURATION);

    /*
    // 🔧 DEVELOPMENT CODE (COMMENTED OUT)
    const config = window.getCurrentConfig ? window.getCurrentConfig() : { TRADE_RESULT_DURATION: 4000 };
    const expirationEffect = {
        candleIndex: this.currentCandleIndex,
        price: finalPrice,
        color: lineColor,
        startTime: Date.now(),
        duration: config.TRADE_RESULT_DURATION
    };
    
    setTimeout(() => {
        this.expirationEffects = this.expirationEffects.filter(effect => effect !== expirationEffect);
    }, config.TRADE_RESULT_DURATION);
    */
};

// Update asset card payout box with progress bar
chart.updateAssetCardTradeStatus = function (line) {
    const currentPrice = this.currentPrice;
    const tradeLinePrice = line.price;

    // Determine if winning
    const isWinning = (line.type === 'up' && currentPrice > tradeLinePrice) || (line.type === 'down' && currentPrice < tradeLinePrice);

    // Show actual payout if winning, $0 if draw/loss
    const displayPayout = isWinning ? line.payout : 0;
    const boxColor = isWinning ? '#0FA054' : '#E75B4D';

    // Calculate progress percentage (remaining time)
    const progressPercentage = Math.max(0, Math.min(100, (line.countdown / line.totalDuration) * 100));
    const progressColor = isWinning ? '#0FA054' : '#E75B4D';

    const activeAssetCard = document.querySelector('.asset-card-tab.active') ||
        document.querySelector('.asset-card-tab:not([style*="display: none"])');

    if (activeAssetCard) {
        // Add loading bar
        activeAssetCard.classList.add('has-active-trade');
        activeAssetCard.style.position = 'relative';



        let progressBar = activeAssetCard.querySelector('.trade-progress-bar');
        if (!progressBar) {
            progressBar = document.createElement('div');
            progressBar.className = 'trade-progress-bar';
            progressBar.style.cssText = `
                position: absolute;
                left: 0;
                top: 0;
                width: 3px;
                height: 100%;
                background: #686F86;
                border-radius: 4px 0 0 4px;
                z-index: 1;
                overflow: hidden;
            `;

            const progressFill = document.createElement('div');
            progressFill.className = 'progress-fill';
            progressFill.style.cssText = `
                width: 100%;
                height: 0%;
                border-radius: 4px 0 0 4px;
                transition: height 0.3s ease;
                position: absolute;
                bottom: 0;
            `;

            progressBar.appendChild(progressFill);
            activeAssetCard.appendChild(progressBar);
        }

        const progressFill = progressBar.querySelector('.progress-fill');
        progressFill.style.height = `${100 - progressPercentage}%`;
        progressFill.style.background = '';
        progressFill.style.backgroundImage = 'none';
        progressFill.className = isWinning ? 'progress-fill' : 'progress-fill losing';

        // Add payout box
        let payoutBox = activeAssetCard.querySelector('.trade-payout-box');
        if (!payoutBox) {
            payoutBox = document.createElement('div');
            payoutBox.className = 'trade-payout-box';
            activeAssetCard.appendChild(payoutBox);
        }

        // Format payout display according to requirements
        let payoutText;
        if (displayPayout === 0) {
            payoutText = '0 $';
        } else {
            payoutText = `+${displayPayout.toFixed(2)} $`;
        }

        payoutBox.textContent = payoutText;
        payoutBox.style.backgroundColor = boxColor;
    }
};

// Remove progress bar and payout box when no active trades
chart.removeAssetCardTradeStatus = function () {
    const progressBars = document.querySelectorAll('.trade-progress-bar');
    progressBars.forEach(bar => bar.remove());

    const payoutBoxes = document.querySelectorAll('.trade-payout-box');
    payoutBoxes.forEach(box => box.remove());

    const activeAssetCards = document.querySelectorAll('.asset-card-tab.has-active-trade');
    activeAssetCards.forEach(card => card.classList.remove('has-active-trade'));
};

// Draw trade expiration effects/ circles
chart.drawTradeExpirationEffects = function () {
    if (!this.expirationEffects || this.expirationEffects.length === 0) return;

    const a = this.getChartArea();
    const twoCm = 100;
    const startX = a.left + this.panOffset + twoCm;
    const currentTime = Date.now();

    this.expirationEffects.forEach(effect => {
        const elapsed = currentTime - effect.startTime;
        if (elapsed >= effect.duration) return;

        // Calculate current position based on candle index and pan offset
        const isOdd = (effect.candleIndex % 2) === 0;
        const gridIndex = Math.floor(effect.candleIndex / 2);
        const centerX = isOdd ?
            startX + gridIndex * twoCm :
            startX + gridIndex * twoCm + twoCm / 2;

        const priceY = this.priceToY(effect.price);

        // Trade end line without opacity fade 
        const opacity = 1;

        // Draw white outer circle (6px radius) -> Reduced to 5px
        this.ctx.fillStyle = '#ffffff';
        this.ctx.globalAlpha = opacity;
        this.ctx.beginPath();
        this.ctx.arc(centerX, priceY, 4, 0, 2 * Math.PI);
        this.ctx.fill();

        // Draw colored inner circle (3px radius)
        this.ctx.fillStyle = effect.color;
        this.ctx.beginPath();
        this.ctx.arc(centerX, priceY, 2, 0, 2 * Math.PI);
        this.ctx.fill();

        // Draw vertical straight line through candles (over circles)
        this.ctx.strokeStyle = effect.color;
        this.ctx.lineWidth = 1;
        this.ctx.globalAlpha = opacity;
        this.ctx.setLineDash([]);

        this.ctx.beginPath();
        this.ctx.moveTo(centerX, a.top);
        this.ctx.lineTo(centerX, a.top + a.height);
        this.ctx.stroke();

        // Reset alpha
        this.ctx.globalAlpha = 1;
    });
};

// Draw 40x40 white circle with SVG icon on chart right side
chart.drawRightSideCircle = function () {
    const a = this.getChartArea();
    const circleX = a.left + a.width - 60;
    const circleY = a.top + a.height / 2;
    const radius = 20;

    this.ctx.fillStyle = '#ffffff';
    this.ctx.beginPath();
    this.ctx.arc(circleX, circleY, radius, 0, 2 * Math.PI);
    this.ctx.fill();

    // Check for hover
    const isHovered = Math.sqrt((this.mouseX - circleX) ** 2 + (this.mouseY - circleY) ** 2) <= radius;
    if (isHovered && this.canvas) {
        this.canvas.style.cursor = 'pointer';
    }

    this.ctx.strokeStyle = '#ddd';
    this.ctx.lineWidth = 1;
    this.ctx.stroke();

    const iconSize = 16;
    const chartContainer = this.canvas.parentElement;
    let existingIcon = chartContainer.querySelector('.chart-right-circle-icon');
    if (existingIcon) existingIcon.remove();

    const iconDiv = document.createElement('div');
    iconDiv.className = 'chart-right-circle-icon';
    iconDiv.style.cssText = `position: absolute; left: ${circleX - iconSize / 2}px; top: ${circleY - iconSize / 2}px; width: ${iconSize}px; height: ${iconSize}px; pointer-events: none;`;
    iconDiv.innerHTML = `<svg class="icon-arrow-right" width="${iconSize}" height="${iconSize}"><use xlink:href="./svg/spritemap.svg#icon-arrow-right"></use></svg>`;
    chartContainer.appendChild(iconDiv);
};

// Buyer-Seller Sentiment Indicator
class BuyerSellerIndicator {
    constructor() {
        this.buyerSection = document.querySelector('.buyer-section');
        this.sellerSection = document.querySelector('.seller-section');
        this.topPercentage = document.querySelector('.indicator-percentage.top');
        this.bottomPercentage = document.querySelector('.indicator-percentage.bottom');
        this.indicator = document.querySelector('.buyer-seller-indicator');

        this.init();
    }

    init() {
        // Set initial state
        this.updateSentiment(33, 67);
    }

    updateSentiment(buyerPercentage, sellerPercentage) {
        // Update percentage displays
        if (this.topPercentage) this.topPercentage.textContent = `${sellerPercentage}%`;
        if (this.bottomPercentage) this.bottomPercentage.textContent = `${buyerPercentage}%`;

        // Calculate heights with 1px gap
        if (this.buyerSection && this.sellerSection && this.indicator) {
            const totalHeight = this.indicator.clientHeight - 60; // Account for padding
            const gapHeight = 1;
            const availableHeight = totalHeight - gapHeight;

            const buyerHeight = Math.max(1, (buyerPercentage / 100) * availableHeight);
            const sellerHeight = Math.max(1, (sellerPercentage / 100) * availableHeight);

            // Apply heights with smooth animation
            this.buyerSection.style.height = `${buyerHeight}px`;
            this.sellerSection.style.height = `${sellerHeight}px`;
        }
    }
}

// Initialize buyer-seller indicator
const buyerSellerIndicator = new BuyerSellerIndicator();
window.buyerSellerIndicator = buyerSellerIndicator;

// Market Sentiment Manager (simplified)
class MarketSentimentManager {
    constructor() {
        this.sentimentData = [];
        this.isRunning = false;
        this.updateInterval = null;
    }

    loadDatasetSentiment(sentimentData) {
        this.sentimentData = sentimentData.map(item => {
            const match = item.sentiment.match(/Buyer-(\d+\.\d+)%, Seller-(\d+\.\d+)%/);
            if (match) {
                return {
                    time: item.time,
                    buyerPercentage: parseFloat(match[1]),
                    sellerPercentage: parseFloat(match[2])
                };
            }
            return {
                time: item.time,
                buyerPercentage: 45,
                sellerPercentage: 55
            };
        });
        this.startSentimentUpdates(1000);
    }

    startSentimentUpdates(intervalMs = 2000) {
        if (this.isRunning || !this.sentimentData.length) return;

        this.isRunning = true;
        this.updateInterval = setInterval(() => {
            this.updateSentiment();
        }, intervalMs);
        this.updateSentiment();
    }

    stopSentimentUpdates() {
        this.isRunning = false;
        if (this.updateInterval) {
            clearInterval(this.updateInterval);
            this.updateInterval = null;
        }
    }

    updateSentiment() {
        if (!this.sentimentData.length || !window.chart) return;

        const chartIndex = (window.chart.currentCandleIndex * 60) + window.chart.currentCandleElapsed;
        const sentimentIndex = Math.min(chartIndex, this.sentimentData.length - 1);
        const sentiment = this.sentimentData[sentimentIndex];

        // Use the dedicated buyer-seller indicator
        if (window.buyerSellerIndicator) {
            window.buyerSellerIndicator.updateSentiment(sentiment.buyerPercentage, sentiment.sellerPercentage);
        }
    }

    applySentiment(buyerPercentage, sellerPercentage) {
        if (window.buyerSellerIndicator) {
            window.buyerSellerIndicator.updateSentiment(buyerPercentage, sellerPercentage);
        }
    }
}

const sentimentManager = new MarketSentimentManager();
window.sentimentManager = sentimentManager;

document.addEventListener('DOMContentLoaded', function () {
    if (window.buyerSellerIndicator) {
        window.buyerSellerIndicator.updateSentiment(33, 67);
    }
});

// Asset Cards Manager
class AssetCardsManager {
    constructor() {
        this.container = document.querySelector('.asset-cards-container');
        this.cards = document.querySelectorAll('.asset-card');
        this.cardWidth = 136;
        this.cardGap = 10;
        this.init();
    }

    init() {
        this.calculateLayout();
        this.addEventListeners();
        window.addEventListener('resize', () => this.calculateLayout());
    }

    calculateLayout() {
        if (!this.container || !this.cards.length) return;

        const containerWidth = this.container.offsetWidth;
        const totalCardsWidth = this.cards.length * this.cardWidth + (this.cards.length - 1) * this.cardGap;

        if (totalCardsWidth <= containerWidth) {
            this.cards.forEach((card, index) => {
                card.style.left = `${index * (this.cardWidth + this.cardGap)}px`;
                card.style.zIndex = index + 1;
                card.style.transform = 'translateX(0)';
            });
        } else {
            const availableWidth = containerWidth - this.cardWidth;
            const overlapSpace = availableWidth / (this.cards.length - 1);

            this.cards.forEach((card, index) => {
                card.style.left = `${index * overlapSpace}px`;
                card.style.zIndex = index + 1;
                card.style.transform = 'translateX(0)';
            });
        }
    }

    addEventListeners() {
        this.cards.forEach(card => {
            card.addEventListener('mouseenter', () => this.expandCard(card));
            card.addEventListener('mouseleave', () => this.resetCard(card));
        });
    }

    expandCard(hoveredCard) {
        const containerWidth = this.container.offsetWidth;
        const totalCardsWidth = this.cards.length * this.cardWidth + (this.cards.length - 1) * this.cardGap;

        if (totalCardsWidth > containerWidth) {
            hoveredCard.style.zIndex = '200';
            hoveredCard.style.transform = 'translateX(0)';
        }
    }

    resetCard(card) {
        setTimeout(() => {
            if (!card.matches(':hover')) {
                this.calculateLayout();
            }
        }, 100);
    }
}

document.addEventListener('DOMContentLoaded', () => {
    new AssetCardsManager();
});

// Activate Charts Dropdown Manager
class ActivateChartsManager {
    constructor() {
        this.dropdown = document.getElementById('activate-dropdown-header');
        this.dropdownList = document.getElementById('activate-dropdown-list');
        this.assetSelect = document.getElementById('asset-select');
        this.assetCardsContainer = document.querySelector('.asset-card-items');
        this.isOpen = false;
        this.init();
    }

    init() {
        if (!this.dropdown || !this.dropdownList || !this.assetSelect) return;

        this.setupEventListeners();
        this.populateDropdown();

        const observer = new MutationObserver(() => this.populateDropdown());
        observer.observe(this.assetSelect, { childList: true });
    }

    setupEventListeners() {
        this.dropdown.addEventListener('click', (e) => {
            e.stopPropagation();
            this.toggleDropdown();
        });

        document.addEventListener('click', (e) => {
            if (!this.dropdown.contains(e.target) && !this.dropdownList.contains(e.target)) {
                this.closeDropdown();
            }
        });
    }

    toggleDropdown() {
        if (this.isOpen) {
            this.closeDropdown();
        } else {
            this.openDropdown();
        }
    }

    openDropdown() {
        this.populateDropdown();
        this.dropdownList.style.display = 'block';
        this.dropdown.classList.add('active');
        this.isOpen = true;
    }

    closeDropdown() {
        this.dropdownList.style.display = 'none';
        this.dropdown.classList.remove('active');
        this.isOpen = false;
    }

    async populateDropdown() {
        if (!this.dropdownList) return;
        this.dropdownList.innerHTML = '';

        try {
            const assetTypeHeader = document.getElementById('asset-type-dropdown-header');
            const selectedType = assetTypeHeader?.dataset.selectedType || 'currencyPairs';
            const response = await fetch('./js/asset-mapping.json');
            const assetMapping = await response.json();
            let assets = [];

            if (selectedType === 'currencyPairs') {
                const major = Object.keys(assetMapping.currencyPairs.major || {});
                const exotic = Object.keys(assetMapping.currencyPairs.exotic || {});
                assets = [...major, ...exotic];
            } else if (assetMapping[selectedType]) {
                assets = Object.keys(assetMapping[selectedType]);
            }

            if (assets.length > 0) {
                assets.forEach(assetName => {
                    const assetItem = document.createElement('div');
                    assetItem.className = 'activate-asset-item';
                    assetItem.innerHTML = `<span>${assetName}</span>`;
                    assetItem.dataset.assetValue = assetName.toLowerCase().replace(/[^a-z0-9]/g, '');
                    assetItem.dataset.assetName = assetName;
                    assetItem.addEventListener('click', (e) => {
                        e.stopPropagation();
                        this.createAssetCard(assetName, assetItem.dataset.assetValue);
                        this.closeDropdown();
                    });
                    this.dropdownList.appendChild(assetItem);
                });
            } else {
                const noAssetsItem = document.createElement('div');
                noAssetsItem.className = 'activate-asset-item';
                noAssetsItem.innerHTML = '<span style="color: #a0a4b8; font-style: italic;">No assets available</span>';
                noAssetsItem.style.cursor = 'default';
                this.dropdownList.appendChild(noAssetsItem);
            }
        } catch (error) {
            console.error('Error loading assets:', error);
        }
    }

    createAssetCard(assetName, assetValue) {
        if (!this.assetCardsContainer) return;

        const existingCard = this.assetCardsContainer.querySelector(`[id="${assetName}"]`);
        if (existingCard) return;

        const cardElement = document.createElement('div');
        cardElement.className = 'asset-card-tab desktop';
        cardElement.id = assetName;
        cardElement.style.left = '0px';
        cardElement.style.zIndex = '0';

        const flagsHtml = this.generateFlagsHtml(assetName);

        cardElement.innerHTML = `
            <div class="asset-card-container">
                <div class="asset-card-flags">
                    ${flagsHtml}
                </div>
                <div class="asset-card-block">
                    <div class="asset-card-blockLabel">
                        <div class="asset-card-label">${assetName}</div>
                    </div>
                    <div class="asset-card-blockPayout">
                        <div class="asset-card-payout">${this.generateRandomPayout()}%</div>
                    </div>
                </div>
            </div>
            <div class="asset-card-close">
                <svg class="icon-close-tiny">
                    <use xlink:href="./svg/spritemap.svg#icon-close-tiny"></use>
                </svg>
            </div>
            <div class="asset-card-pin">
                <svg class="icon-pin">
                    <use xlink:href="./svg/spritemap.svg#icon-pin"></use>
                </svg>
            </div>
        `;

        const closeBtn = cardElement.querySelector('.asset-card-close');
        const pinBtn = cardElement.querySelector('.asset-card-pin');

        closeBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            this.removeAssetCard(cardElement);
        });

        pinBtn.addEventListener('click', (e) => {
            e.stopPropagation();
            this.togglePinAssetCard(cardElement);
        });



        this.assetCardsContainer.appendChild(cardElement);
    }

    generateFlagsHtml(assetName) {
        const flagMap = {
            'USD': 'flag-usd', 'EUR': 'flag-eur', 'GBP': 'flag-gbp', 'JPY': 'flag-jpy',
            'AUD': 'flag-aud', 'CAD': 'flag-cad', 'CHF': 'flag-chf', 'CNY': 'flag-cny',
            'INR': 'flag-inr', 'BDT': 'flag-bdt', 'ARS': 'flag-ars'
        };

        const currencies = assetName.match(/([A-Z]{3})/g) || [];

        let flagsHtml = '';
        currencies.slice(0, 2).forEach((currency, index) => {
            const flagClass = flagMap[currency] || 'flag-usd';
            const marginClass = index === 1 ? 'asset-card-flag-ars' : 'asset-card-flag-usd';
            flagsHtml += `
                <svg class="asset-card-flag ${marginClass}">
                    <use xlink:href="./svg/flags.svg#${flagClass}"></use>
                </svg>
            `;
        });

        if (!flagsHtml) {
            flagsHtml = `
                <svg class="asset-card-flag asset-card-flag-usd">
                    <use xlink:href="./svg/flags.svg#flag-usd"></use>
                </svg>
                <svg class="asset-card-flag asset-card-flag-ars">
                    <use xlink:href="./svg/flags.svg#flag-ars"></use>
                </svg>
            `;
        }

        return flagsHtml;
    }

    async generateRandomPayout() {
        const config = window.payoutConfig;
        if (!config || config.modes.randomizePayoutControl) {
            return Math.floor(Math.random() * 26) + 68;
        } else {
            const assetName = this.assetName || document.querySelector('.asset-name')?.textContent;
            if (assetName && window.PayoutController) {
                return await window.PayoutController.getPayoutPercentage(assetName);
            }
            return Math.floor(Math.random() * 26) + 68;
        }
    }

    async getPayoutForAsset(assetName) {
        const config = window.payoutConfig;
        if (!config || config.modes.randomizePayoutControl) {
            return Math.floor(Math.random() * 26) + 68;
        } else {
            if (assetName && window.PayoutController) {
                return await window.PayoutController.getPayoutPercentage(assetName);
            }
            return Math.floor(Math.random() * 26) + 68;
        }
    }

    removeAssetCard(cardElement) {
        cardElement.remove();
    }

    togglePinAssetCard(cardElement) {
        cardElement.classList.toggle('pinned');
    }
}

document.addEventListener('DOMContentLoaded', () => {
    setTimeout(() => {
        window.activateChartsManager = new ActivateChartsManager();
    }, 1000);
});

// Dynamic Price Model
class DynamicPriceModel {
    constructor() {
        this.priceData = [];
        this.currentVolatility = 0;
        this.marketState = 'stable';
        this.gridLines = [];
        this.analysisWindow = 50;
        this.volatilityThreshold = 0.02;
    }

    async loadPriceData(filePath = './data/USDINR_price.json') {
        try {
            const response = await fetch(filePath);
            if (response.ok) {
                this.priceData = await response.json();
                return true;
            }
        } catch (error) { }
        return false;
    }

    calculateVolatility(endIndex = null) {
        if (this.priceData.length < this.analysisWindow) return 0;

        const end = endIndex || this.priceData.length - 1;
        const start = Math.max(0, end - this.analysisWindow + 1);
        const recentPrices = this.priceData.slice(start, end + 1).map(item => item.price);

        if (recentPrices.length < 2) return 0;

        const returns = [];
        for (let i = 1; i < recentPrices.length; i++) {
            const change = (recentPrices[i] - recentPrices[i - 1]) / recentPrices[i - 1];
            returns.push(change);
        }

        const mean = returns.reduce((sum, val) => sum + val, 0) / returns.length;
        const variance = returns.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / returns.length;

        return Math.sqrt(variance);
    }

    analyzeMarketState(currentIndex = null) {
        this.currentVolatility = this.calculateVolatility(currentIndex);
        this.marketState = this.currentVolatility > this.volatilityThreshold ? 'volatile' : 'stable';

        return this.marketState;
    }

    roundPrice(price) {
        if (price >= 100) {
            return Math.round(price * 100) / 100;
        } else if (price >= 10) {
            return Math.round(price * 1000) / 1000;
        } else {
            return Math.round(price * 10000) / 10000;
        }
    }

    generateRoundNumbers(minPrice, maxPrice, interval) {
        const roundNumbers = [];

        let startPrice = Math.floor(minPrice / interval) * interval;
        if (startPrice < minPrice) startPrice += interval;

        for (let price = startPrice; price <= maxPrice; price += interval) {
            roundNumbers.push(this.roundPrice(price));
        }

        return roundNumbers;
    }

    generatePriceGrid(currentIndex = null) {
        if (this.priceData.length === 0) return [];

        this.analyzeMarketState(currentIndex);

        const end = currentIndex || this.priceData.length - 1;
        const start = Math.max(0, end - this.analysisWindow + 1);
        const recentPrices = this.priceData.slice(start, end + 1).map(item => item.price);

        const minPrice = Math.min(...recentPrices);
        const maxPrice = Math.max(...recentPrices);
        const priceRange = maxPrice - minPrice;
        const currentPrice = recentPrices[recentPrices.length - 1];

        let baseInterval;

        if (this.marketState === 'volatile') {
            if (priceRange > 1.0) {
                baseInterval = 0.1;
            } else if (priceRange > 0.5) {
                baseInterval = 0.05;
            } else {
                baseInterval = 0.02;
            }
        } else {
            if (priceRange > 1.0) {
                baseInterval = 0.05;
            } else if (priceRange > 0.5) {
                baseInterval = 0.02;
            } else {
                baseInterval = 0.01;
            }
        }

        const extendedMin = minPrice - (priceRange * 0.1);
        const extendedMax = maxPrice + (priceRange * 0.1);

        this.gridLines = this.generateRoundNumbers(extendedMin, extendedMax, baseInterval);

        return {
            gridLines: this.gridLines,
            marketState: this.marketState,
            volatility: this.currentVolatility,
            currentPrice: currentPrice,
            priceRange: priceRange,
            interval: baseInterval
        };
    }

    getGridLinesForChart(chartMinPrice, chartMaxPrice) {
        return this.gridLines.filter(price => price >= chartMinPrice && price <= chartMaxPrice);
    }

    updateGrid(newPriceData) {
        if (newPriceData) {
            this.priceData.push(newPriceData);

            if (this.priceData.length > 1000) {
                this.priceData = this.priceData.slice(-500);
            }
        }

        return this.generatePriceGrid();
    }

    getMarketSummary() {
        return {
            marketState: this.marketState,
            volatility: (this.currentVolatility * 100).toFixed(2) + '%',
            gridCount: this.gridLines.length,
            dataPoints: this.priceData.length,
            lastUpdate: new Date().toISOString()
        };
    }
}

window.DynamicPriceModel = DynamicPriceModel;

// Activate Charts Dropdown
setTimeout(() => {
    const dropdown = document.getElementById('activate-dropdown-header');
    const dropdownList = document.getElementById('activate-dropdown-list');
    const controlDropdown = document.getElementById('control-dropdown-header');
    const controlDropdownList = document.getElementById('control-dropdown-list');
    const selectDataDropdown = document.getElementById('select-data-dropdown-header');
    const selectDataDropdownList = document.getElementById('select-data-dropdown-list');
    const assetSelect = document.getElementById('asset-select');

    if (!dropdown || !dropdownList || !controlDropdown || !controlDropdownList || !selectDataDropdown || !selectDataDropdownList) return;

    async function populateDropdown() {
        dropdownList.innerHTML = '';

        try {
            const assetTypeHeader = document.getElementById('asset-type-dropdown-header');
            const selectedType = assetTypeHeader?.dataset.selectedType || 'currencyPairs';
            const response = await fetch('./js/asset-mapping.json');
            const assetMapping = await response.json();
            let assetsWithFlags = [];

            if (selectedType === 'currencyPairs') {
                if (assetMapping.currencyPairs.major) {
                    Object.entries(assetMapping.currencyPairs.major).forEach(([name, flags]) => {
                        assetsWithFlags.push({ name, flags });
                    });
                }
                if (assetMapping.currencyPairs.exotic) {
                    Object.entries(assetMapping.currencyPairs.exotic).forEach(([name, flags]) => {
                        assetsWithFlags.push({ name, flags });
                    });
                }
            } else if (assetMapping[selectedType]) {
                Object.entries(assetMapping[selectedType]).forEach(([name, flags]) => {
                    assetsWithFlags.push({ name, flags });
                });
            }

            if (assetsWithFlags.length > 0) {
                assetsWithFlags.forEach(({ name, flags }) => {
                    const assetValue = name.toLowerCase().replace(/[^a-z0-9]/g, '');
                    addAssetToDropdown(name, assetValue, flags);
                });
            } else {
                const noAssetsItem = document.createElement('div');
                noAssetsItem.className = 'activate-asset-item';
                noAssetsItem.innerHTML = '<span style="color: #a0a4b8; font-style: italic;">No assets available</span>';
                noAssetsItem.style.cursor = 'default';
                dropdownList.appendChild(noAssetsItem);
            }
        } catch (error) {
            console.error('Error loading assets:', error);
        }
    }

    function addAssetToDropdown(assetName, assetValue, flags = []) {
        const assetItem = document.createElement('div');
        assetItem.className = 'activate-asset-item';
        assetItem.style.cssText = 'padding: 10px; cursor: pointer; border-bottom: 1px solid #3D4354; display: flex; align-items: center;';

        const existingCard = document.querySelector(`[id="${assetName}"]`);
        const flagContainer = document.createElement('div');
        flagContainer.style.cssText = 'display: flex; align-items: center; margin-right: 2px;';

        if (existingCard) {
            assetItem.classList.add('disabled');
            assetItem.style.cursor = 'not-allowed';

            flags.forEach((flagCode, index) => {
                const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                svg.setAttribute('width', '16');
                svg.setAttribute('height', '16');
                svg.style.cssText = `width: 16px; height: 16px; border: 2px solid #3D4354; border-radius: 50%; display: inline-block; margin-left: ${index === 0 ? '0' : '-7px'}; overflow: hidden; opacity: 0.5;`;
                const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
                use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', `./svg/flags.svg#flag-${flagCode}`);
                svg.appendChild(use);
                flagContainer.appendChild(svg);
            });

            assetItem.appendChild(flagContainer);

            const span = document.createElement('span');
            span.style.cssText = 'opacity: 0.5; color: #666; font-size: 13px;';
            span.textContent = `${assetName} (Active)`;
            assetItem.appendChild(span);
        } else {
            flags.forEach((flagCode, index) => {
                const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
                svg.setAttribute('width', '16');
                svg.setAttribute('height', '16');
                svg.style.cssText = `width: 16px; height: 16px; border: 2px solid #3D4354; border-radius: 50%; display: inline-block; margin-left: ${index === 0 ? '0' : '-7px'}; overflow: hidden;`;
                const use = document.createElementNS('http://www.w3.org/2000/svg', 'use');
                use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', `./svg/flags.svg#flag-${flagCode}`);
                svg.appendChild(use);
                flagContainer.appendChild(svg);
            });

            assetItem.appendChild(flagContainer);

            const span = document.createElement('span');
            span.style.cssText = 'font-size: 13px;';
            span.textContent = assetName;
            assetItem.appendChild(span);

            assetItem.addEventListener('click', (e) => {
                e.stopPropagation();
                createAssetCard(assetName, assetValue);
                closeDropdown();
            });
        }

        dropdownList.appendChild(assetItem);
    }

    function openControlDropdown() {
        populateControlDropdown();
        controlDropdownList.style.display = 'block';
        controlDropdown.classList.add('active');
        setTimeout(() => updateAccordionHeight(), 50);
    }

    function closeControlDropdown() {
        controlDropdownList.style.display = 'none';
        controlDropdown.classList.remove('active');
        setTimeout(() => updateAccordionHeight(), 50);
    }

    function populateControlDropdown() {
        controlDropdownList.innerHTML = '';
        const activeCards = document.querySelectorAll('.asset-card-tab');

        if (activeCards.length === 0) {
            const noChartsItem = document.createElement('div');
            noChartsItem.className = 'activate-asset-item';
            noChartsItem.innerHTML = '<span style="color: #a0a4b8; font-style: italic;">No active charts</span>';
            noChartsItem.style.cursor = 'default';
            controlDropdownList.appendChild(noChartsItem);
        } else {
            activeCards.forEach(card => {
                const assetName = card.id;
                const chartItem = document.createElement('div');
                chartItem.className = 'activate-asset-item';
                chartItem.innerHTML = `<span>${assetName}</span>`;

                chartItem.addEventListener('click', (e) => {
                    e.stopPropagation();
                    selectAssetForDataSource(assetName);
                    closeControlDropdown();
                });

                controlDropdownList.appendChild(chartItem);
            });
        }
    }

    function openSelectDataDropdown() {
        populateSelectDataDropdown();
        selectDataDropdownList.style.display = 'block';
        selectDataDropdown.classList.add('active');
        setTimeout(() => updateAccordionHeight(), 50);
    }

    function closeSelectDataDropdown() {
        selectDataDropdownList.style.display = 'none';
        selectDataDropdown.classList.remove('active');
        setTimeout(() => updateAccordionHeight(), 50);
    }

    let selectedAssetForData = null;
    let selectedDataset = null;
    let activeCharts = {};

    function showChartLoading() {
        const chartContainer = document.getElementById('chartContainer');
        if (!chartContainer) return;

        let overlay = document.getElementById('chart-loading-overlay');
        if (!overlay) {
            overlay = document.createElement('div');
            overlay.id = 'chart-loading-overlay';
            overlay.className = 'chart-loading-overlay';
            // overlay.innerHTML = `
            //     <div class="chart-loader-container">
            //         <img src="./images/loading.gif" alt="Loading..." class="chart-loader-gif">
            //     </div>
            // `;
            chartContainer.appendChild(overlay);
        }

        overlay.style.display = 'flex';
        window.chartLoadingStartTime = Date.now();
    }

    function hideChartLoading() {
        const overlay = document.getElementById('chart-loading-overlay');
        if (!overlay) return;

        const minDisplayTime = 3000;

        // Ensure chart loader completes EXACTLY at 8 seconds from page load
        const timeSincePageLoad = Date.now() - (window.pageLoadTime || Date.now());
        const remainingTo8Sec = Math.max(0, 8000 - timeSincePageLoad);

        const elapsed = Date.now() - (window.chartLoadingStartTime || 0);
        const standardDelay = Math.max(0, minDisplayTime - elapsed);

        const delay = Math.max(remainingTo8Sec, standardDelay);

        if (delay > 0) {
            setTimeout(() => {
                overlay.style.display = 'none';
            }, delay);
        } else {
            overlay.style.display = 'none';
        }
    }

    function saveCurrentChartProgress() {
        const activeCard = document.querySelector('.asset-card-tab.active');
        if (activeCard && activeCard.id && activeCharts[activeCard.id] && window.chart) {
            const chartKey = activeCard.id;
            activeCharts[chartKey].currentCandleIndex = window.chart.currentCandleIndex;
            activeCharts[chartKey].currentCandleElapsed = window.chart.currentCandleElapsed;
            activeCharts[chartKey].completedCandles = window.chart.candleData.map(c => c.isComplete);

            if (activeCharts[chartKey].isPlaying) {
                if (!window.chart.isPlaying && window.chart.rawData && window.chart.rawData.length > 0) {
                    setTimeout(() => {
                        if (activeCharts[chartKey].isPlaying) {
                            window.chart.startAnimation();
                        }
                    }, 500);
                }
            }

            localStorage.setItem('activeCharts', JSON.stringify(activeCharts));
        }
    }

    setInterval(saveCurrentChartProgress, 2000);

    function selectAssetForDataSource(assetName) {
        selectedAssetForData = assetName;

        const controlHeader = document.getElementById('control-dropdown-header');
        if (controlHeader) {
            controlHeader.querySelector('span').textContent = assetName;
        }

        loadDataSourcesForAsset(assetName);
    }

    async function loadDataSourcesForAsset(assetName) {
        try {
            const simplifiedAssetName = assetName.toLowerCase().replace(/[^a-zA-Z0-9]/g, '');

            const response = await fetch('php/get_asset_datasets.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ assetName: simplifiedAssetName })
            });

            const result = await response.json();

            if (result.success && result.datasets && result.datasets.length > 0) {
                populateSelectDataDropdown(result.datasets);
            } else {
                populateSelectDataDropdown([]);
            }
        } catch (error) {
            populateSelectDataDropdown([]);
        }
    }

    function populateSelectDataDropdown(datasets = null) {
        selectDataDropdownList.innerHTML = '';

        if (!selectedAssetForData) {
            const noAssetItem = document.createElement('div');
            noAssetItem.className = 'activate-asset-item';
            noAssetItem.innerHTML = '<span style="color: #a0a4b8; font-style: italic;">Select an asset first</span>';
            noAssetItem.style.cursor = 'default';
            selectDataDropdownList.appendChild(noAssetItem);
            return;
        }

        if (!datasets || datasets.length === 0) {
            const noDataItem = document.createElement('div');
            noDataItem.className = 'activate-asset-item';
            noDataItem.innerHTML = `<span style="color: #a0a4b8; font-style: italic;">No datasets found for ${selectedAssetForData}</span>`;
            noDataItem.style.cursor = 'default';
            selectDataDropdownList.appendChild(noDataItem);
            return;
        }

        datasets.forEach(dataset => {
            const dataItem = document.createElement('div');
            dataItem.className = 'activate-asset-item';
            dataItem.innerHTML = `<span>${dataset}</span>`;

            dataItem.addEventListener('click', (e) => {
                e.stopPropagation();
                selectedDataset = dataset;

                const dataHeader = document.getElementById('select-data-dropdown-header');
                if (dataHeader) {
                    dataHeader.querySelector('span').textContent = dataset;
                }

                closeSelectDataDropdown();
            });

            selectDataDropdownList.appendChild(dataItem);
        });
    }

    function updateAccordionHeight() {
        const chartControlsAccordion = document.getElementById('chart-controls');
        if (chartControlsAccordion && chartControlsAccordion.classList.contains('active')) {
            chartControlsAccordion.style.maxHeight = chartControlsAccordion.scrollHeight + 'px';
        }
    }

    async function saveAssetCards() {
        const activeCards = [];
        document.querySelectorAll('.asset-card-tab').forEach(card => {
            activeCards.push({
                name: card.id,
                pinned: card.classList.contains('pinned'),
                active: card.classList.contains('active')
            });
        });
        await window.assetCardDB.sync(activeCards);
    }

    async function loadAssetCards() {
        const savedCards = await window.assetCardDB.load();
        if (savedCards && Object.keys(savedCards).length > 0) {
            for (const [assetName, cardData] of Object.entries(savedCards)) {
                await createAssetCard(assetName, assetName, cardData.status.pinned, cardData.status.active);
            }
        }
    }

    // Helper function to update card label based on active state
    function updateCardLabel(cardElement, assetName) {
        const label = cardElement.querySelector('.asset-card-label');
        if (!label || !assetName) return;

        const isActive = cardElement.classList.contains('active');
        let displayName = assetName;

        if (window.assetNameMapping && window.assetNameMapping[assetName]) {
            // Use cardNameActive if card is active, otherwise use cardName
            const context = isActive ? 'cardNameActive' : 'cardName';
            displayName = window.assetNameMapping[assetName][context] ||
                window.assetNameMapping[assetName].cardName ||
                assetName;
        } else {
            // Fallback to truncation if no mapping exists
            displayName = assetName.length > 7 ? assetName.substring(0, 7) + '...' : assetName;
        }

        label.textContent = displayName;
    }

    async function getPayoutForAsset(assetName) {
        const config = window.payoutConfig;
        if (!config || config.modes.randomizePayoutControl) {
            return Math.floor(Math.random() * 26) + 68;
        } else {
            if (assetName && window.PayoutController) {
                return await window.PayoutController.getPayoutPercentage(assetName);
            }
            return Math.floor(Math.random() * 26) + 68;
        }
    }

    async function createAssetCard(assetName, assetValue, isPinned = false, isActive = false) {
        const container = document.querySelector('.asset-card-items');
        if (!container) return;

        if (container.querySelector(`[id="${assetName}"]`)) return;

        const cardElement = document.createElement('div');
        cardElement.className = 'asset-card-tab desktop';
        if (isPinned) cardElement.classList.add('pinned');
        if (isActive) cardElement.classList.add('active');
        cardElement.id = assetName;
        cardElement.style.left = '0px';
        cardElement.style.zIndex = '0';

        // Generate flags using flag detection algorithm or fallback to regex
        let flagsHtml = '';
        if (window.flagDetectionAlgorithm) {
            // Wait for flag detection to be ready
            if (!window.flagDetectionAlgorithm.isReady) {
                await window.flagDetectionAlgorithm.readyPromise;
            }

            // Debug logging for Boeing
            if (assetName.includes('Boeing')) {
                console.log('🔍 Boeing Debug - Asset Name:', assetName);
                console.log('🔍 Boeing Debug - directFlagMapping:', window.flagDetectionAlgorithm.directFlagMapping[assetName]);
            }

            // Use flag detection algorithm for all asset types
            flagsHtml = await window.flagDetectionAlgorithm.generateTradeFlags(assetName, 'asset-card-flag');

            // Debug logging for Boeing
            if (assetName.includes('Boeing')) {
                console.log('🔍 Boeing Debug - Generated HTML:', flagsHtml);
            }
        } else {
            // Fallback to regex extraction for currency pairs
            const currencies = assetName.match(/([A-Z]{3})/g) || ['USD', 'EUR'];
            flagsHtml = currencies.slice(0, 2).map((currency, index) => {
                const flagName = currency.toLowerCase();
                const marginClass = index === 1 ? 'asset-card-flag-ars' : 'asset-card-flag-usd';
                return `<svg class="asset-card-flag ${marginClass}"><use xlink:href="./svg/flags.svg#flag-${flagName}"></use></svg>`;
            }).join('');
        }

        // Use mapping from asset-name-mapping.json for display name
        let displayName = assetName;
        if (window.assetNameMapping && window.assetNameMapping[assetName]) {
            // Use the mapped cardName from asset-name-mapping.json
            displayName = window.assetNameMapping[assetName].cardName || assetName;
        } else {
            // Fallback to truncation if no mapping exists
            displayName = assetName.length > 7 ? assetName.substring(0, 7) + '...' : assetName;
        }

        cardElement.innerHTML = `
            <div class="asset-card-container">
                <div class="asset-card-flags">${flagsHtml}</div>
                <div class="asset-card-block">
                    <div class="asset-card-blockLabel">
                        <div class="asset-card-label">${displayName}</div>
                    </div>
                    <div class="asset-card-blockPayout">
                        <div class="asset-card-payout">${await getPayoutForAsset(assetName)}%</div>
                    </div>
                </div>
            </div>
            <div class="asset-card-close">
                <svg class="icon-close-tiny"><use xlink:href="./svg/spritemap.svg#icon-close-tiny"></use></svg>
            </div>
            <div class="asset-card-pin">
                <svg class="icon-pin"><use xlink:href="./svg/spritemap.svg#icon-pin"></use></svg>
            </div>
        `;

        cardElement.querySelector('.asset-card-close').addEventListener('click', async (e) => {
            e.stopPropagation();
            await window.assetCardDB.remove(assetName);
            cardElement.remove();
            if (dropdownList.style.display === 'block') {
                populateDropdown();
            }
            if (controlDropdownList.style.display === 'block') {
                populateControlDropdown();
            }
        });

        cardElement.querySelector('.asset-card-pin').addEventListener('click', async (e) => {
            e.stopPropagation();
            cardElement.classList.toggle('pinned');
            const isPinned = cardElement.classList.contains('pinned');
            await window.assetCardDB.update(assetName, { pinned: isPinned });
        });

        cardElement.addEventListener('click', async (e) => {
            if (e.target.closest('.asset-card-close') || e.target.closest('.asset-card-pin')) return;

            // Remove active from all cards and update their labels to cardName
            document.querySelectorAll('.asset-card-tab').forEach(card => {
                card.classList.remove('active');
                updateCardLabel(card, card.id);
            });

            // Add active to clicked card and update its label to cardNameActive
            cardElement.classList.add('active');
            updateCardLabel(cardElement, assetName);

            // Update database
            await window.assetCardDB.update(assetName, { active: true });

            if (activeCharts[assetName] && window.chart) {
                saveCurrentChartProgress();

                showChartLoading();

                setTimeout(() => {
                    const chartData = activeCharts[assetName];
                    window.chart.loadDataset(chartData.candleData, chartData.sentimentData);

                    if (chartData.currentCandleIndex !== undefined) {
                        window.chart.currentCandleIndex = chartData.currentCandleIndex;
                        window.chart.currentCandleElapsed = chartData.currentCandleElapsed;

                        if (chartData.completedCandles) {
                            chartData.completedCandles.forEach((isComplete, index) => {
                                if (window.chart.candleData[index]) {
                                    window.chart.candleData[index].isComplete = isComplete;
                                }
                            });
                        }

                        const currentCandle = window.chart.candleData[chartData.currentCandleIndex];
                        if (currentCandle && currentCandle.secondData && currentCandle.secondData[chartData.currentCandleElapsed]) {
                            window.chart.currentPrice = currentCandle.secondData[chartData.currentCandleElapsed].price;
                            window.chart.targetPrice = window.chart.currentPrice;
                        }

                        window.chart._initRunningExtremes();
                        window.chart.updateDisplays();
                        window.chart.updateCurrentCandleLines(true);
                    }

                    if (chartData.isPlaying) {
                        window.chart.startAnimation();
                    }

                    if (window.sentimentManager) {
                        window.sentimentManager.loadDatasetSentiment(chartData.sentimentData);
                    }

                    hideChartLoading();
                }, 800);
            }

            updateRightSidebar(assetName);
        });

        container.appendChild(cardElement);

        if (!document.querySelector('.asset-card-tab.active')) {
            cardElement.classList.add('active');
            updateCardLabel(cardElement, assetName);
            updateRightSidebar(assetName);
            await window.assetCardDB.add(assetName, true, isPinned);
        } else if (isActive) {
            document.querySelectorAll('.asset-card-tab').forEach(card => {
                card.classList.remove('active');
                updateCardLabel(card, card.id);
            });
            cardElement.classList.add('active');
            updateCardLabel(cardElement, assetName);
            updateRightSidebar(assetName);
            await window.assetCardDB.add(assetName, true, isPinned);
        } else {
            await window.assetCardDB.add(assetName, false, isPinned);
        }
    }

    function openDropdown() {
        populateDropdown();
        dropdownList.style.display = 'block';
        dropdown.classList.add('active');
        setTimeout(() => updateAccordionHeight(), 50);
    }

    function closeDropdown() {
        dropdownList.style.display = 'none';
        dropdown.classList.remove('active');
        setTimeout(() => updateAccordionHeight(), 50);
    }

    dropdown.addEventListener('click', (e) => {
        e.stopPropagation();
        if (dropdownList.style.display === 'block') {
            closeDropdown();
        } else {
            openDropdown();
        }
    });

    controlDropdown.addEventListener('click', (e) => {
        e.stopPropagation();
        if (controlDropdownList.style.display === 'block') {
            closeControlDropdown();
        } else {
            openControlDropdown();
        }
    });

    selectDataDropdown.addEventListener('click', (e) => {
        e.stopPropagation();
        if (selectDataDropdownList.style.display === 'block') {
            closeSelectDataDropdown();
        } else {
            if (!selectedAssetForData) {
                alert('Please select an asset from Control Charts first');
                return;
            }
            loadDataSourcesForAsset(selectedAssetForData);
            openSelectDataDropdown();
        }
    });

    document.addEventListener('click', (e) => {
        if (!dropdown.contains(e.target) && !dropdownList.contains(e.target)) {
            closeDropdown();
        }
        if (!controlDropdown.contains(e.target) && !controlDropdownList.contains(e.target)) {
            closeControlDropdown();
        }
        if (!selectDataDropdown.contains(e.target) && !selectDataDropdownList.contains(e.target)) {
            closeSelectDataDropdown();
        }
    });

    if (assetSelect) {
        const observer = new MutationObserver(() => {
            populateDropdown();
        });
        observer.observe(assetSelect, { childList: true, subtree: true });
    }

    setTimeout(async () => {
        // Wait for payout config to load
        let attempts = 0;
        while (!window.payoutConfig && attempts < 50) {
            await new Promise(resolve => setTimeout(resolve, 100));
            attempts++;
        }

        await loadAssetCards();
        loadActiveCharts();
    }, 100);

    function loadActiveCharts() {
        const savedCharts = localStorage.getItem('activeCharts');
        if (savedCharts) {
            activeCharts = JSON.parse(savedCharts);

            setTimeout(() => {
                Object.keys(activeCharts).forEach(assetName => {
                    const chartData = activeCharts[assetName];
                    if (chartData.isPlaying) {
                        document.querySelectorAll('.asset-card-tab').forEach(card => card.classList.remove('active'));
                        const assetCard = document.getElementById(assetName);
                        if (assetCard) {
                            assetCard.classList.add('active');
                            updateRightSidebar(assetName);
                        }

                        if (window.chart) {
                            window.chart.loadDataset(chartData.candleData, chartData.sentimentData);

                            if (chartData.currentCandleIndex !== undefined) {
                                window.chart.currentCandleIndex = chartData.currentCandleIndex;
                                window.chart.currentCandleElapsed = chartData.currentCandleElapsed;

                                if (chartData.completedCandles) {
                                    chartData.completedCandles.forEach((isComplete, index) => {
                                        if (window.chart.candleData[index]) {
                                            window.chart.candleData[index].isComplete = isComplete;
                                        }
                                    });
                                }

                                const currentCandle = window.chart.candleData[chartData.currentCandleIndex];
                                if (currentCandle && currentCandle.secondData && currentCandle.secondData[chartData.currentCandleElapsed]) {
                                    window.chart.currentPrice = currentCandle.secondData[chartData.currentCandleElapsed].price;
                                    window.chart.targetPrice = window.chart.currentPrice;
                                }

                                window.chart._initRunningExtremes();
                                window.chart.updateDisplays();
                                window.chart.updateCurrentCandleLines(true);
                            }

                            window.chart.startAnimation();
                        }

                        if (window.sentimentManager) {
                            window.sentimentManager.loadDatasetSentiment(chartData.sentimentData);
                        }

                        return;
                    }
                });
            }, 3000);
        }
    }

    setTimeout(() => {
        populateDropdown();

        const activeCard = document.querySelector('.asset-card-tab.active');
        if (activeCard) {
            if (!activeCard.id) {
                const cardLabel = activeCard.querySelector('.asset-card-label');
                if (cardLabel && cardLabel.textContent) {
                    activeCard.id = cardLabel.textContent;
                }
            }
            if (activeCard.id) {
                updateRightSidebar(activeCard.id);
            }
        }
    }, 500);

    populateDropdown();

    async function updateRightSidebar(assetName) {
        const sidebarAssetName = document.querySelector('.asset-name');
        const sidebarAssetReturn = document.querySelector('.asset-return');

        if (sidebarAssetName && sidebarAssetReturn && assetName) {
            // Get original asset name using reverse lookup
            const originalAssetName = window.getOriginalAssetName ? window.getOriginalAssetName(assetName) : assetName;

            // Get proper display name from asset-name-mapping.json
            let displayName = assetName;
            if (window.assetNameMapping) {
                const mapping = window.assetNameMapping[originalAssetName];
                if (mapping && mapping.rightSidebarName) {
                    displayName = mapping.rightSidebarName;
                }
            }

            sidebarAssetName.textContent = displayName;

            const activeCard = document.querySelector('.asset-card-tab.active');
            let percentage;
            if (activeCard) {
                const cardPayout = activeCard.querySelector('.asset-card-payout');
                percentage = cardPayout ? cardPayout.textContent : `${await getPayoutForAsset(assetName)}%`;
            } else {
                percentage = `${await getPayoutForAsset(assetName)}%`;
            }
            sidebarAssetReturn.textContent = percentage;

            // Use flag detection algorithm for all asset types
            if (window.flagDetectionAlgorithm) {
                await window.flagDetectionAlgorithm.updateAssetSectionFlags(originalAssetName);
            }

            updatePayoutInfo();
        }
    }

    function updatePayoutInfo() {
        const investmentInput = document.querySelector('.investment-value');
        const assetReturn = document.querySelector('.asset-return');
        const payoutInfo = document.querySelector('.payout-info');

        if (investmentInput && assetReturn && payoutInfo) {
            const rawInvestmentValue = investmentInput.value;
            const investmentAmount = parseFloat(rawInvestmentValue.replace(/[^0-9.]/g, '')) || 100;

            const rawAssetReturnText = assetReturn.textContent;
            const percentage = parseFloat(rawAssetReturnText.replace('%', '')) || 80;

            const profit = investmentAmount * (percentage / 100);
            const totalPayout = investmentAmount + profit;

            const formattedPayout = totalPayout.toFixed(2);
            // Payout Info Injection
            payoutInfo.innerHTML = `
                <span class="info-label">Your payout</span>
                <span class="info-dots"></span>
                <span class="info-value"><b style="color: #FFFFFF;">${formattedPayout} $</b></span>
            `;
        }
    }

    const assetReturn = document.querySelector('.asset-return');
    if (assetReturn) {
        const observer = new MutationObserver(updatePayoutInfo);
        observer.observe(assetReturn, { childList: true, subtree: true, characterData: true });
        setInterval(updatePayoutInfo, 100);
    }

    const investmentInput = document.querySelector('.investment-value');
    if (investmentInput) {
        investmentInput.addEventListener('input', updatePayoutInfo);
    }

    async function updatePayoutPercentages() {
        const config = window.payoutConfig;
        if (!config || !config.modes.randomizePayoutControl) return;

        const payoutElements = document.querySelectorAll('.asset-card-payout');
        for (const payoutElement of payoutElements) {
            const assetName = payoutElement.closest('.asset-card-tab')?.querySelector('.asset-card-label')?.textContent;
            if (assetName) {
                const newPercentage = Math.floor(Math.random() * 26) + 68;
                payoutElement.textContent = `${newPercentage}%`;
            }
        }

        const activeCard = document.querySelector('.asset-card-tab.active');
        if (activeCard) {
            const sidebarAssetReturn = document.querySelector('.asset-return');
            const cardPayout = activeCard.querySelector('.asset-card-payout');
            if (sidebarAssetReturn && cardPayout) {
                sidebarAssetReturn.textContent = cardPayout.textContent;
            }
        }
    }

    // Payout Interval Update
    setInterval(updatePayoutPercentages, 1800000);

    const existingCard = document.querySelector('.asset-card-tab');
    if (existingCard) {
        if (!existingCard.id) {
            existingCard.id = existingCard.querySelector('.asset-card-label')?.textContent || 'USD/ARS (OTC)';
        }

        const existingLabel = existingCard.querySelector('.asset-card-label');
        if (existingLabel && existingCard.id) {
            // Card starts as active, so use cardNameActive
            existingCard.classList.add('active');
            updateCardLabel(existingCard, existingCard.id);
        }

        updateRightSidebar(existingCard.id);

        existingCard.addEventListener('click', (e) => {
            if (e.target.closest('.asset-card-close') || e.target.closest('.asset-card-pin')) return;

            document.querySelectorAll('.asset-card-tab').forEach(card => {
                card.classList.remove('active');
                updateCardLabel(card, card.id);
            });

            existingCard.classList.add('active');
            updateCardLabel(existingCard, existingCard.id);
            updateRightSidebar(existingCard.id);
        });

        const closeBtn = existingCard.querySelector('.asset-card-close');
        if (closeBtn) {
            closeBtn.addEventListener('click', async (e) => {
                e.stopPropagation();
                await window.assetCardDB.remove(existingCard.id);
                existingCard.remove();
                const remainingCards = document.querySelectorAll('.asset-card-tab');
                if (remainingCards.length > 0) {
                    remainingCards[0].classList.add('active');
                    updateRightSidebar(remainingCards[0].id);
                }
                if (dropdownList.style.display === 'block') {
                    populateDropdown();
                }
                if (controlDropdownList.style.display === 'block') {
                    populateControlDropdown();
                }
            });
        }

        const pinBtn = existingCard.querySelector('.asset-card-pin');
        if (pinBtn) {
            pinBtn.addEventListener('click', async (e) => {
                e.stopPropagation();
                existingCard.classList.toggle('pinned');
                const isPinned = existingCard.classList.contains('pinned');
                await window.assetCardDB.update(existingCard.id, { pinned: isPinned });
            });
        }
    }

    // Chart control buttons
    const playBtn = document.getElementById('chart-play-btn');
    const pauseBtn = document.getElementById('chart-pause-btn');
    const resetBtn = document.getElementById('chart-reset-btn');
    const buildAllBtn = document.getElementById('chart-build-all-btn');

    if (playBtn) {
        playBtn.addEventListener('click', () => {
            if (!selectedAssetForData || !selectedDataset) {
                alert('Please select an asset and dataset first');
                return;
            }

            const chartKey = selectedAssetForData;
            if (activeCharts[chartKey]) {
                activeCharts[chartKey].isPlaying = true;
                localStorage.setItem('activeCharts', JSON.stringify(activeCharts));

                if (window.chart) {
                    const chartData = activeCharts[chartKey];
                    window.chart.loadDataset(chartData.candleData, chartData.sentimentData);
                    window.chart.startAnimation();

                    if (window.sentimentManager) {
                        window.sentimentManager.loadDatasetSentiment(chartData.sentimentData);
                    }
                }

                document.querySelectorAll('.asset-card-tab').forEach(card => card.classList.remove('active'));
                const assetCard = document.getElementById(selectedAssetForData);
                if (assetCard) {
                    assetCard.classList.add('active');
                    updateRightSidebar(selectedAssetForData);
                }
            } else {
                loadAndPlayDataset();
            }
        });
    }

    if (pauseBtn) {
        pauseBtn.addEventListener('click', () => {
            if (selectedAssetForData && activeCharts[selectedAssetForData]) {
                activeCharts[selectedAssetForData].isPlaying = false;
                localStorage.setItem('activeCharts', JSON.stringify(activeCharts));
            }

            if (window.chart) {
                window.chart.stopAnimation();
            }
        });
    }

    if (resetBtn) {
        resetBtn.addEventListener('click', () => {
            if (selectedAssetForData && activeCharts[selectedAssetForData]) {
                const wasPlaying = activeCharts[selectedAssetForData].isPlaying;
                activeCharts[selectedAssetForData].currentCandleIndex = 0;
                activeCharts[selectedAssetForData].currentCandleElapsed = 0;
                activeCharts[selectedAssetForData].completedCandles = [];
                activeCharts[selectedAssetForData].startTime = Date.now();
                activeCharts[selectedAssetForData].isPlaying = wasPlaying;
                localStorage.setItem('activeCharts', JSON.stringify(activeCharts));
            }

            if (window.chart && window.chart.rawData) {
                window.chart.restart();
                if (selectedAssetForData && activeCharts[selectedAssetForData] && activeCharts[selectedAssetForData].isPlaying) {
                    setTimeout(() => window.chart.startAnimation(), 100);
                }
            }
        });
    }

    if (buildAllBtn) {
        buildAllBtn.addEventListener('click', () => {
            if (!selectedAssetForData || !selectedDataset) {
                alert('Please select an asset and dataset first');
                return;
            }

            if (selectedAssetForData && activeCharts[selectedAssetForData]) {
                activeCharts[selectedAssetForData].isPlaying = false;
                localStorage.setItem('activeCharts', JSON.stringify(activeCharts));
            }

            if (window.chart && window.chart.rawData && window.chart.rawData.length > 0) {
                window.chart.buildAllCandles();
            } else {
                loadAndPlayDataset().then(() => {
                    if (window.chart) {
                        window.chart.buildAllCandles();
                        if (selectedAssetForData && activeCharts[selectedAssetForData]) {
                            activeCharts[selectedAssetForData].isPlaying = false;
                            localStorage.setItem('activeCharts', JSON.stringify(activeCharts));
                        }
                    }
                });
            }
        });
    }

    async function loadAndPlayDataset() {
        try {
            const simplifiedAssetName = selectedAssetForData.toLowerCase().replace(/[^a-zA-Z0-9]/g, '');

            // Get current user's session info to build correct path
            const sessionResponse = await fetch('./php/session_manager.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ action: 'getCurrentUser' })
            });

            const sessionData = await sessionResponse.json();
            const username = sessionData.username;

            const candlePath = `data/${username}/${simplifiedAssetName}/${selectedDataset}/candle_data.json`;
            const sentimentPath = `data/${username}/${simplifiedAssetName}/${selectedDataset}/sentiment_data.json`;

            const candleResponse = await fetch(candlePath);
            if (!candleResponse.ok) throw new Error('Failed to load candle data');
            const candleData = await candleResponse.json();

            const sentimentResponse = await fetch(sentimentPath);
            if (!sentimentResponse.ok) throw new Error('Failed to load sentiment data');
            const sentimentData = await sentimentResponse.json();

            const chartKey = selectedAssetForData;
            activeCharts[chartKey] = {
                assetName: selectedAssetForData,
                dataset: selectedDataset,
                candleData: candleData,
                sentimentData: sentimentData,
                isPlaying: true,
                startTime: Date.now(),
                currentCandleIndex: 0,
                currentCandleElapsed: 0,
                completedCandles: []
            };

            localStorage.setItem('activeCharts', JSON.stringify(activeCharts));

            showChartLoading();

            setTimeout(() => {
                if (window.chart) {
                    window.chart.loadDataset(candleData, sentimentData);
                }

                if (window.sentimentManager) {
                    window.sentimentManager.loadDatasetSentiment(sentimentData);
                }

                hideChartLoading();
            }, 1000);

            document.querySelectorAll('.asset-card-tab').forEach(card => {
                card.classList.remove('active');
            });
            const assetCard = document.getElementById(selectedAssetForData);
            if (assetCard) {
                assetCard.classList.add('active');
                updateRightSidebar(selectedAssetForData);
            }

        } catch (error) {
            alert('Failed to load dataset: ' + error.message);
        }
    }

}, 2000);

// Initialize price model
setTimeout(() => {
    window.priceModel = new DynamicPriceModel();
}, 100);
// Sync level-icon with account-level-icon dynamically
document.addEventListener('DOMContentLoaded', function () {
    const accountLevelIcon = document.getElementById('account-level-icon');
    const levelIcon = document.querySelector('.level-icon svg');

    if (accountLevelIcon && levelIcon) {
        levelIcon.innerHTML = accountLevelIcon.innerHTML;
        levelIcon.className = accountLevelIcon.className;
    }

    // Toggle balance edit input and button
    const pencilIcon = document.querySelector('.select-balance-edit');
    const editInput = document.querySelector('.select-balance-edit-input');

    if (pencilIcon && editInput) {
        pencilIcon.addEventListener('click', function () {
            if (editInput.style.display === 'none' || editInput.style.display === '') {
                editInput.style.display = 'block';
            } else {
                editInput.style.display = 'none';
            }
        });
    }
});
// Login form animation and password update functionality
document.addEventListener('DOMContentLoaded', function () {
    const loginTitle = document.getElementById('loginTitle');
    const loginForm = document.getElementById('loginForm');
    const passwordUpdateForm = document.getElementById('passwordUpdateForm');

    // Check if we need to show password update form
    const needsPasswordUpdate = passwordUpdateForm && passwordUpdateForm.style.display === 'block';

    if (needsPasswordUpdate) {
        // Animate title change
        setTimeout(() => {
            if (loginTitle) {
                loginTitle.style.transition = 'all 0.3s ease';
                loginTitle.textContent = 'Password Update';
            }
        }, 100);
    }

    // Password matching validation
    if (passwordUpdateForm) {
        const newPasswordInput = passwordUpdateForm.querySelector('input[name="new_password"]');
        const confirmPasswordInput = passwordUpdateForm.querySelector('input[name="confirm_password"]');

        function validatePasswords() {
            if (newPasswordInput.value && confirmPasswordInput.value) {
                if (newPasswordInput.value !== confirmPasswordInput.value) {
                    confirmPasswordInput.style.borderColor = '#ff4757';
                    confirmPasswordInput.style.boxShadow = '0 0 20px rgba(255, 71, 87, 0.3)';
                } else {
                    confirmPasswordInput.style.borderColor = '#0FA054';
                    confirmPasswordInput.style.boxShadow = '0 0 20px rgba(15, 160, 84, 0.3)';
                }
            }
        }

        if (newPasswordInput && confirmPasswordInput) {
            confirmPasswordInput.addEventListener('input', validatePasswords);
            newPasswordInput.addEventListener('input', validatePasswords);
        }
    }
});
