/**
 * 数据监控系统 - 优化版本
 * 主要功能：实时价格监控、基差计算、警报系统
 * 
 * @author AI Assistant
 * @version 2.0.0
 * @date 2024-12-19
 */

class DataMonitoring {
    constructor() {
        // 配置常量
        this.CONFIG = {
            WS_URL: `${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${window.location.hostname}:${window.location.port}/ws/GetData`,
            RECONNECT_INTERVAL: 1000,
            MAX_RECONNECT_ATTEMPTS: 10,
            HEARTBEAT_INTERVAL: 30000,
            STABILITY_CHECK_INTERVAL: 300000,
            MESSAGE_TIMEOUT: 30000,
            DEBOUNCE_DELAY: 300,
            REFRESH_INTERVAL: 200,
            SOUND_ENABLED: true
        };

        // 状态管理
        this.state = {
            tradingSymbols: [],
            panelConfigs: new Map(),
            panelCounter: 0,
            wsConnection: null,
            reconnectTimer: null,
            heartbeatTimer: null,
            stabilityTimer: null,
            lastMessageTime: 0,
            reconnectAttempts: 0,
            isInitialized: false
        };

        // 缓存DOM元素，避免重复查询
        this.cache = {
            panels: new Map(),
            templates: new Map(),
            selectors: {}
        };

        // 音频相关初始化
        this.audio = new Audio('lib/air_raid_siren.mp3');
        this.audio.volume = 1;
        this.isPlaying = false;
        this.currentAudioInstance = null;
        this.cooldown = 100;
        this.userHasInteracted = false;
        this.audioInitialized = false;
        this.audioPlaybackAllowed = false;

        // 监听用户交互事件，用于解决自动播放限制
        this.initUserInteractionListener();

        // 预加载音频，但不立即播放
        this.preloadAudio();

        // 事件委托处理器缓存
        this.eventHandlers = new Map();

        this.init();
    }

    /**
     * 内存管理 - 清理资源
     */
    destroy() {
        this.cleanupTimers();
        this.cleanupEventListeners();
        this.cleanupWebSocket();
        // 修复：this.cache是一个普通对象，不是Map，不支持clear()方法
        // 手动清理cache中的内容
        this.cache.panels.clear();
        this.cache.templates.clear();
        this.cache.selectors = {};
        this.state.panelConfigs.clear();
        this.eventHandlers.clear();
    }

    /**
     * 清理所有定时器
     */
    cleanupTimers() {
        const timers = [
            'reconnectTimer', 'heartbeatTimer', 'stabilityTimer'
        ];

        timers.forEach(timerName => {
            if (this.state[timerName]) {
                clearInterval(this.state[timerName]);
                this.state[timerName] = null;
            }
        });
    }

    /**
     * 清理事件监听器
     */
    cleanupEventListeners() {
        this.eventHandlers.forEach((handler, key) => {
            if (handler && handler.remove) {
                handler.remove();
            }
        });
        this.eventHandlers.clear();
    }

    /**
     * 清理WebSocket连接
     */
    cleanupWebSocket() {
        if (this.state.wsConnection) {
            this.state.wsConnection.close();
            this.state.wsConnection = null;
        }
    }

    //#region WebSocket管理

    /**
     * 初始化WebSocket连接
     */
    initWebSocket() {
        this.connectWebSocket();
        this.startStabilityCheck();
    }

    /**
     * 建立WebSocket连接
     */
    connectWebSocket() {
        try {
            this.state.wsConnection = new WebSocket(this.CONFIG.WS_URL);
            const ws = this.state.wsConnection;

            ws.onopen = this.handleWebSocketOpen.bind(this);
            ws.onmessage = this.handleWebSocketMessage.bind(this);
            ws.onclose = this.handleWebSocketClose.bind(this);
            ws.onerror = this.handleWebSocketError.bind(this);

        } catch (error) {
            console.error('WebSocket连接失败:', error);
            this.scheduleReconnect();
        }
    }

    /**
     * WebSocket连接成功处理
     */
    handleWebSocketOpen() {
        console.log('WebSocket连接已建立');
        this.state.reconnectAttempts = 0;
        this.startHeartbeat();
        this.showMessage('实时数据连接已建立', 'success');
    }

    /**
     * 处理WebSocket消息
     * @param {MessageEvent} event - WebSocket消息事件
     */
    handleWebSocketMessage(event) {
        try {
            const data = JSON.parse(event.data);

            if (Array.isArray(data)) {
                this.processPriceData(data);
            }

            this.state.lastMessageTime = Date.now();
        } catch (error) {
            console.error('处理WebSocket消息失败:', error);
        }
    }

    /**
     * WebSocket连接关闭处理
     * @param {CloseEvent} event - 关闭事件
     */
    handleWebSocketClose(event) {
        console.log('WebSocket连接断开:', event.code, event.reason);
        this.stopHeartbeat();
        this.scheduleReconnect();
    }

    /**
     * WebSocket错误处理
     * @param {Event} error - 错误事件
     */
    handleWebSocketError(error) {
        console.error('WebSocket错误:', error);
        this.showMessage('实时数据连接错误', 'error');
    }

    /**
     * 处理价格数据（优化版本）
     * @param {Array} priceData - 价格数据数组
     */
    processPriceData(priceData) {
        if (!priceData || priceData.length === 0) return;

        // 创建价格映射，避免双重循环
        const priceMap = new Map();
        priceData.forEach(item => {
            if (item.name) {
                // WebSocket 返回的 name 是 SymbolRemark，直接用它作为 key
                priceMap.set(item.name, item);
            }
        });

        // 批量更新所有面板
        this.state.panelConfigs.forEach((config, panelId) => {
            const var0 = priceMap.get(config.symbol0);
            const var1 = priceMap.get(config.symbol1);

            if (var0) this.updatePanelItem(panelId, 0, var0);
            if (var1) this.updatePanelItem(panelId, 1, var1);

            if (var0 && var1) {
                this.updatePanelDisplay(panelId, var0, var1);
            }
        });
    }

    /**
     * 开始心跳
     */
    startHeartbeat() {
        this.state.heartbeatTimer = setInterval(() => {
            if (this.isWebSocketReady()) {
                this.sendWebSocketMessage({ type: 'heartbeat' });
            }
        }, this.CONFIG.HEARTBEAT_INTERVAL);
    }

    /**
     * 停止心跳
     */
    stopHeartbeat() {
        if (this.state.heartbeatTimer) {
            clearInterval(this.state.heartbeatTimer);
            this.state.heartbeatTimer = null;
        }
    }

    /**
     * 开始稳定性检查
     */
    startStabilityCheck() {
        this.state.stabilityTimer = setInterval(() => {
            this.checkConnectionHealth();
        }, this.CONFIG.STABILITY_CHECK_INTERVAL);
    }

    /**
     * 检查连接健康状态
     */
    checkConnectionHealth() {
        const now = Date.now();
        const timeSinceLastMessage = now - this.state.lastMessageTime;

        // 检查消息超时
        if (this.state.lastMessageTime > 0 && timeSinceLastMessage > this.CONFIG.MESSAGE_TIMEOUT) {
            console.log('长时间未收到消息，重新连接');
            this.reconnectWebSocket();
            return;
        }

        // 检查重连次数过多
        if (this.state.reconnectAttempts >= this.CONFIG.MAX_RECONNECT_ATTEMPTS) {
            console.log('连接不稳定，主动重连');
            this.reconnectWebSocket();
        }
    }

    /**
     * 计划重连
     */
    scheduleReconnect() {
        this.state.reconnectAttempts++;
        console.log(`WebSocket重连尝试 ${this.state.reconnectAttempts}`);

        this.state.reconnectTimer = setTimeout(() => {
            this.connectWebSocket();
        }, this.CONFIG.RECONNECT_INTERVAL);
    }

    /**
     * 主动重连WebSocket
     */
    reconnectWebSocket() {
        this.cleanupWebSocket();
        this.cleanupTimers();
        this.connectWebSocket();
    }

    /**
     * 发送WebSocket消息
     * @param {Object} message - 消息对象
     */
    sendWebSocketMessage(message) {
        if (this.isWebSocketReady()) {
            this.state.wsConnection.send(JSON.stringify(message));
        } else {
            console.warn('WebSocket未连接，消息发送失败');
        }
    }

    /**
     * 检查WebSocket是否就绪
     * @returns {boolean} 是否就绪
     */
    isWebSocketReady() {
        return this.state.wsConnection &&
            this.state.wsConnection.readyState === WebSocket.OPEN;
    }

    //#endregion

    //#region 初始化与设置

    /**
     * 应用初始化
     */
    async init() {
        try {
            await this.loadDependencies();
            await this.fetchTradingSymbols();
            this.setupEventHandlers();
            this.initWebSocket();
            this.loadSavedPanels();
            this.state.isInitialized = true;
            
            // 初始化完成后检测音频播放能力
            this.checkAudioPlaybackCapability();
        } catch (error) {
            console.error('应用初始化失败:', error);
            this.showMessage('应用初始化失败', 'error');
        }
    }



    /**
     * 加载依赖库
     */
    async loadDependencies() {
        // 等待Layui加载完成
        if (typeof layui === 'undefined') {
            await new Promise(resolve => {
                const checkLayui = setInterval(() => {
                    if (typeof layui !== 'undefined') {
                        clearInterval(checkLayui);
                        resolve();
                    }
                }, 100);
            });
        }

        // 初始化Layui组件
        layui.use(['layer', 'form', 'element'], () => {
            this.layer = layui.layer;
            this.form = layui.form;
            this.element = layui.element;
        });
    }

    /**
     * 获取交易品种列表
     */
    async fetchTradingSymbols() {
        try {
            const response = await fetch('/API/GetSymbols');
            if (!response.ok) throw new Error(`HTTP ${response.status}`);

            this.state.tradingSymbols = await response.json();
        } catch (error) {
            console.error('获取交易品种失败:', error);
            this.showMessage('获取交易品种失败', 'error');
        }
    }

    /**
     * 设置事件处理器
     */
    setupEventHandlers() {
        // 使用事件委托减少监听器数量
        this.setupAddPanelHandler();
        this.setupGlobalEventHandlers();
    }

    /**
     * 设置添加面板按钮事件
     */
    setupAddPanelHandler() {
        const addBtn = document.getElementById('addPanelBtn');
        if (addBtn) {
            addBtn.addEventListener('click', this.showSymbolSelection.bind(this));
        }
    }

    /**
     * 设置全局事件处理器
     */
    setupGlobalEventHandlers() {
        // 页面卸载时清理资源
        window.addEventListener('beforeunload', this.destroy.bind(this));
        // 设置切换按钮事件
        this.setupToggleButtons();

        // 新增：监听页面可见性变化，解决手机端切换窗口后需要重新连接的问题
        document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this));
    }

    /**
     * 处理页面可见性变化事件
     * 当用户从其他应用切换回当前页面时，检查和维护WebSocket连接
     */
    handleVisibilityChange() {
        // 当页面变为可见时
        if (!document.hidden) {
            console.log('页面变为可见，检查WebSocket连接状态');

            // 检查连接是否已断开或不可用
            if (!this.isWebSocketReady()) {
                console.log('WebSocket连接已断开，尝试重新连接');
                this.reconnectWebSocket();
            } else {
                console.log('WebSocket连接正常，发送心跳确认');
                // 发送心跳消息确认连接是否正常
                this.sendWebSocketMessage({ type: 'heartbeat' });
            }
        }
    }

    /**
     * 设置切换按钮事件
     */
    setupToggleButtons() {
        // 使用事件委托，在文档层面监听点击事件，处理切换按钮交互
        document.addEventListener('click', (e) => {
            // 检查点击事件的目标是否为切换按钮或其内部元素
            if (e.target.closest('.toggle-btn')) {
                let btn;
                if (e.target.closest('.amount_folding')) {
                    btn = e.target.closest('.amount_folding');
                } else if (e.target.closest('.calculate_folding')) {
                    btn = e.target.closest('.calculate_folding');
                } else {
                    // 如果未匹配到特定按钮，跳过后续逻辑
                    return;
                }
                // 从按钮上获取要切换显示状态的目标元素选择器
                const targetSelector = btn.getAttribute('data-target');
                if (!targetSelector) {
                    // 如果未获取到目标选择器，跳过后续逻辑
                    console.warn('未找到切换按钮的 data-target 属性');
                    return;
                }
                // 查找按钮的最近祖先元素，其类名为 card-body
                const parent = e.target.closest('.card-container');
                // 若找到符合条件的祖先元素
                if (parent) {
                    // 调用 toggleContent 方法来切换目标内容的显示与隐藏状态
                    this.toggleContent(parent, targetSelector, btn);
                } else {
                    console.warn('未找到类名为 card-body 的祖先元素');
                }
            }
        });
    }

    /**
     * 切换内容显示/隐藏
     */
    toggleContent(parent, targetSelector, btn) {

        // 查找目标元素，该元素为当前点击按钮对应的需要切换显示状态的元素
        const tar = parent.querySelector(".layui-card-body");
        const target = tar.querySelector(targetSelector);
        // 若未找到目标元素，则直接返回，终止本次操作
        if (!target) return;

        // 判断目标元素当前是否处于隐藏状态
        const isHidden = target.style.display === 'none';
        // 根据判断结果切换目标元素的显示状态，只切换display属性，不修改其他样式以保持与CSS定义一致
        target.style.display = isHidden ? '' : 'none';

        // 根据目标元素的显示状态更新切换按钮的颜色，若显示则为绿色，若隐藏则为红色
        btn.style.backgroundColor = isHidden ? '#16baaa' : 'red';

    }

    //#endregion

    //#region 面板管理

    /**
     * 显示品种选择弹窗
     */
    showSymbolSelection() {
        if (!this.state.tradingSymbols.length) {
            this.showMessage('暂无可用交易品种', 'warning');
            return;
        }

        const content = this.createSymbolSelectionHTML();

        this.layer.open({
            type: 1,
            title: '选择交易品种',
            content: content,
            area: ['400px', '600px'],
            btn: ['确定', '取消'],
            yes: (index) => {
                const symbol1 = document.querySelector('select[name="symbol1"]').value;
                const symbol2 = document.querySelector('select[name="symbol2"]').value;

                if (this.validateSymbols(symbol1, symbol2)) {
                    this.createPanel(symbol1, symbol2);
                    this.layer.close(index);
                }
            }
        });

        // 初始化表单
        this.form.render('select');
    }

    /**
     * 创建品种选择HTML
     */
    createSymbolSelectionHTML() {
        const options = this.state.tradingSymbols.map(item =>
            `<option value="${item.remarkText}">${item.remarkText}</option>`
        ).join('');

        return `
            <div style="padding: 20px;">
                <div class="layui-form">
                    <div class="layui-form-item">
                        <label class="layui-form-label">品种1</label>
                        <div class="layui-input-block">
                            <select name="symbol1" lay-verify="required">
                                <option value="">请选择品种</option>
                                ${options}
                            </select>
                        </div>
                    </div>
                    <div class="layui-form-item">
                        <label class="layui-form-label">品种2</label>
                        <div class="layui-input-block">
                            <select name="symbol2" lay-verify="required">
                                <option value="">请选择品种</option>
                                ${options}
                            </select>
                        </div>
                    </div>
                    <div id="symbolErrorMsg" style="color: red; text-align: center; margin-top: 10px;"></div>
                </div>
            </div>
        `;
    }

    /**
     * 验证品种选择
     */
    validateSymbols(symbol1, symbol2) {
        const errorMsg = document.getElementById('symbolErrorMsg');

        if (!symbol1 || !symbol2) {
            errorMsg.textContent = '请选择两个交易品种';
            return false;
        }

        if (symbol1 === symbol2) {
            errorMsg.textContent = '请选择两个不同的交易品种';
            return false;
        }

        errorMsg.textContent = '';
        return true;
    }

    /**
     * 创建新面板
     */
    createPanel(symbol1, symbol2, panelId = null) {
        if (!panelId) {
            panelId = `panel-${++this.state.panelCounter}`;
        }

        const template = document.querySelector('.template-panel');
        if (!template) return;

        const panel = template.cloneNode(true);
        panel.classList.remove('template-panel');
        panel.setAttribute('data-panel-id', panelId);

        // 初始化面板配置
        this.initPanelConfig(panelId, symbol1, symbol2);

        // 设置显示内容
        this.setupPanelDisplay(panel, panelId, symbol1, symbol2);

        // 绑定事件
        this.bindPanelEvents(panel, panelId);

        // 插入到页面
        template.parentNode.insertBefore(panel, template);
        panel.style.display = 'block';

        // 保存配置
        this.savePanels();
    }

    /**
     * 初始化面板配置
     */
    initPanelConfig(panelId, symbol1, symbol2) {
        const findSymbol = (remarkText) => {
            return this.state.tradingSymbols.find(item => item.remarkText === remarkText);
        };

        this.state.panelConfigs.set(panelId, {
            symbol0: symbol1,
            symbol0_remark: symbol1,
            symbol1: symbol2,
            symbol1_remark: symbol2,
            soundEnabled: true,
            correspondingState: 0,
            basis_high: 0,
            basis_low: 0,
            symbol0_config: {
                direction: 'up',
                entryPrice: 0.00,
                quantity: 1
            },
            symbol1_config: {
                direction: 'up',
                entryPrice: 0.00,
                quantity: 1
            }
        });
    }

    /**
     * 设置面板显示
     */
    setupPanelDisplay(panel, panelId, symbol1, symbol2) {
        // 获取所有symbol0类的元素并更新内容
        const symbol0Elements = panel.querySelectorAll('.symbol0');
        symbol0Elements.forEach(element => {
            element.textContent = this.state.panelConfigs.get(panelId).symbol0_remark;
        });

        // 获取所有symbol1类的元素并更新内容
        const symbol1Elements = panel.querySelectorAll('.symbol1');
        symbol1Elements.forEach(element => {
            element.textContent = this.state.panelConfigs.get(panelId).symbol1_remark;
        });
    }

    /**
     * 绑定面板事件
     */
    bindPanelEvents(panel, panelId) {
        // 使用防抖处理输入事件
        const debouncedUpdate = this.debounce((field, value, rowIndex) => {
            this.updatePanelConfig(panelId, field, value, rowIndex);
        }, this.CONFIG.DEBOUNCE_DELAY);

        // 基差计算方向
        panel.querySelector('.correspondingState').addEventListener('change', (e) => {
            this.updatePanelConfig(panelId, 'correspondingState', parseInt(e.target.value) || 0);
            // 手动触发价格重新计算和警报检查
            this.recheckPanelAlarms(panelId);
        });

        // 基差高低点
        panel.querySelector('.basis_high').addEventListener('input', (e) => {
            debouncedUpdate('basis_high', parseFloat(e.target.value) || 0);
        });

        panel.querySelector('.basis_low').addEventListener('input', (e) => {
            debouncedUpdate('basis_low', parseFloat(e.target.value) || 0);
        });

        // 交易配置
        const items = panel.querySelectorAll('.comparison-item');
        items.forEach((item, index) => {
            this.bindTradingConfigEvents(item, panelId, index);
        });

        // 声音开关
        panel.querySelector('.sound_switch').addEventListener('click', () => {
            this.toggleSound(panelId);
        });

        // 删除面板
        panel.querySelector('.remove-panel-btn').addEventListener('click', () => {
            this.removePanel(panel, panelId);
        });
    }

    /**
     * 绑定交易配置事件
     */
    bindTradingConfigEvents(item, panelId, index) {
        const debouncedUpdate = this.debounce((field, value) => {
            this.updatePanelConfig(panelId, field, value, index);
            this.updateProfitDisplay(item, panelId, index);
        }, this.CONFIG.DEBOUNCE_DELAY);

        item.querySelector('.direction').addEventListener('change', (e) => {
            this.updatePanelConfig(panelId, 'direction', e.target.value, index);
            this.updateProfitDisplay(item, panelId, index);
        });

        item.querySelector('.entryPrice').addEventListener('input', (e) => {
            debouncedUpdate('entryPrice', parseFloat(e.target.value) || 0);
        });

        item.querySelector('.quantity').addEventListener('input', (e) => {
            debouncedUpdate('quantity', parseInt(e.target.value) || 1);
        });
    }


    /**
     * 更新盈亏显示
     */
    updateProfitDisplay(item, panelId, index) {
        const config = this.state.panelConfigs.get(panelId);
        if (!config) return;

        const symbolConfig = config[`symbol${index}_config`];
        if (!symbolConfig || !symbolConfig.entryPrice || !symbolConfig.quantity) return;

        // 尝试获取当前价格数据
        const dataItem = item.querySelector('.data-item');
        if (!dataItem) return;

        const bid = parseFloat(dataItem.querySelector('.data-bid').textContent) || 0;
        const ask = parseFloat(dataItem.querySelector('.data-ask').textContent) || 0;

        // 计算盈亏
        let profit = 0;
        if (symbolConfig.entryPrice > 0 && symbolConfig.quantity > 0) {
            profit = symbolConfig.direction === 'up'
                ? (bid - symbolConfig.entryPrice) * symbolConfig.quantity
                : (symbolConfig.entryPrice - ask) * symbolConfig.quantity;
        }

        // 更新显示
        const profitEl = item.querySelector('.profit');
        if (profitEl) {
            profitEl.textContent = profit.toFixed(2);
            profitEl.style.color = profit >= 0 ? 'red' : 'green';
        }

        // 同时更新总盈亏
        const panel = document.querySelector(`[data-panel-id="${panelId}"]`);
        if (panel) {
            this.updateTotalProfit(panel, panelId);
        }
    }



    /**
     * 更新面板配置
     */
    updatePanelConfig(panelId, field, value, rowIndex = null) {
        const config = this.state.panelConfigs.get(panelId);
        if (!config) return;

        if (rowIndex !== null) {
            config[`symbol${rowIndex}_config`][field] = value;
        } else {
            config[field] = value;
        }

        this.savePanels();
    }

    /**
     * 更新面板单项
     */
    updatePanelItem(panelId, index, priceData) {
        const panel = document.querySelector(`[data-panel-id="${panelId}"]`);
        if (!panel) return;

        const item = panel.querySelectorAll('.data-item')[index];
        const profitEl = panel.querySelectorAll('.profit')[index];
        if (!item) return;

        const config = this.state.panelConfigs.get(panelId);
        if (!config) return;

        // 更新价格显示
        item.querySelector('.data-time').textContent = priceData.datetime || '--';
        item.querySelector('.data-bid').textContent = priceData.bid || '0.00';
        item.querySelector('.data-ask').textContent = priceData.ask || '0.00';
        item.querySelector('.data-volume').textContent =
            ((priceData.ask - priceData.bid) || 0).toFixed(2);

        let profit = 0;
        // 计算盈亏
        const symbolConfig = config[`symbol${index}_config`];
        if (symbolConfig && symbolConfig.entryPrice && symbolConfig.quantity) {
            // 当entryPrice和quantity都大于1时才计算盈亏
            if (symbolConfig.entryPrice > 0 && symbolConfig.quantity > 0) {
                profit = symbolConfig.direction === 'up'
                    ? (priceData.bid - symbolConfig.entryPrice) * symbolConfig.quantity
                    : (symbolConfig.entryPrice - priceData.ask) * symbolConfig.quantity;
            }
        }

        profitEl.textContent = profit.toFixed(2);
        profitEl.style.color = profit >= 0 ? 'red' : 'green';
    }

    /**
     * 更新面板显示
     */
    updatePanelDisplay(panelId, var0, var1) {
        const panel = document.querySelector(`[data-panel-id="${panelId}"]`);
        if (!panel) return;

        const config = this.state.panelConfigs.get(panelId);
        if (!config) return;

        let priceDisplay = 0;
        switch (config.correspondingState) {
            case 0: priceDisplay = var0.ask - var1.ask; break;
            case 1: priceDisplay = var0.ask - var1.bid; break;
            case 2: priceDisplay = var0.bid - var1.bid; break;
            case 3: priceDisplay = var0.bid - var1.ask; break;
            case 4: priceDisplay = var0.ask / var1.ask; break;
            case 5: priceDisplay = var0.ask / var1.bid; break;
            case 6: priceDisplay = var0.bid / var1.bid; break;
            case 7: priceDisplay = var0.bid / var1.ask; break;
        }

        priceDisplay = parseFloat(priceDisplay.toFixed(2));

        // 更新价格显示
        const priceEl = panel.querySelector('.price-display');
        priceEl.textContent = priceDisplay.toFixed(2);

        // 更新颜色
        priceEl.classList.remove('price-up', 'price-down');
        if (priceDisplay > 0) priceEl.classList.add('price-up');
        else if (priceDisplay < 0) priceEl.classList.add('price-down');

        // 检查警报 - 修复逻辑错误：应该是价格超出范围时触发警报
        // 增加条件：如果basis_high或basis_low为空或为0时不判断
        const hasValidBasisLow = config.basis_low !== undefined && config.basis_low !== null && config.basis_low !== 0;
        const hasValidBasisHigh = config.basis_high !== undefined && config.basis_high !== null && config.basis_high !== 0;

        if ((hasValidBasisLow || hasValidBasisHigh) && 
            ((hasValidBasisLow && priceDisplay <= config.basis_low) || 
            (hasValidBasisHigh && priceDisplay >= config.basis_high))) {
            this.triggerAlarm(panel, panelId);
        } else {
            this.clearAlarmVisualEffect(panel);
        }

        // 更新总盈亏
        this.updateTotalProfit(panel, panelId);
    }

    /**
     * 触发声光警报
     */
    triggerAlarm(panel, panelId) {
        // 检查是否已经在警报状态，避免重复触发
        if (panel.alarmActive) return;

        // 标记为警报状态
        panel.alarmActive = true;

        // 播放声音警报
        this.playAlertSound(panelId);

        // 添加视觉警报效果
        this.applyAlarmVisualEffect(panel);

        // 设置定时器，一段时间后移除视觉效果
        if (panel.alarmTimeout) {
            clearTimeout(panel.alarmTimeout);
        }

        panel.alarmTimeout = setTimeout(() => {
            this.clearAlarmVisualEffect(panel);
        }, 3000); // 3秒后移除视觉效果，可根据需要调整
    }

    /**
     * 应用视觉警报效果
     */
    applyAlarmVisualEffect(panel) {
        // 添加红色边框
        panel.style.border = '2px solid red';
        panel.style.boxShadow = '0 0 10px rgba(255, 0, 0, 0.5)';

        // 保存原始样式，以便稍后恢复
        if (!panel.originalStyle) {
            panel.originalStyle = {
                border: panel.style.border,
                boxShadow: panel.style.boxShadow
            };
        }

        // 可选：添加闪烁动画效果
        panel.classList.add('alarm-blinking');
    }

    /**
     * 清除视觉警报效果
     */
    clearAlarmVisualEffect(panel) {
        // 恢复原始样式
        if (panel.originalStyle) {
            panel.style.border = panel.originalStyle.border;
            panel.style.boxShadow = panel.originalStyle.boxShadow;
            panel.originalStyle = null;
        } else {
            // 如果没有保存原始样式，则重置为默认值
            panel.style.border = '';
            panel.style.boxShadow = '';
        }

        // 移除闪烁动画类
        panel.classList.remove('alarm-blinking');

        // 清除警报状态标记
        panel.alarmActive = false;
        // 停止警报声音
        this.stopAlertSound();

        // 清除定时器
        if (panel.alarmTimeout) {
            clearTimeout(panel.alarmTimeout);
            panel.alarmTimeout = null;
        }
    }

    /**
     * 重新检查面板警报
     * @param {string} panelId - 面板ID
     */
    recheckPanelAlarms(panelId) {
        const panel = document.querySelector(`[data-panel-id="${panelId}"]`);
        if (!panel) return;

        // 尝试获取面板中显示的当前价格数据
        const dataItems = panel.querySelectorAll('.data-item');
        if (dataItems.length >= 2) {
            // 模拟价格数据对象
            const var0 = {
                ask: parseFloat(dataItems[0].querySelector('.data-ask').textContent) || 0,
                bid: parseFloat(dataItems[0].querySelector('.data-bid').textContent) || 0
            };
            const var1 = {
                ask: parseFloat(dataItems[1].querySelector('.data-ask').textContent) || 0,
                bid: parseFloat(dataItems[1].querySelector('.data-bid').textContent) || 0
            };

            // 使用模拟的价格数据重新计算并检查警报
            if (var0.ask || var0.bid || var1.ask || var1.bid) {
                this.updatePanelDisplay(panelId, var0, var1);
            }
        }
    }

    /**
     * 更新总盈亏
     */
    updateTotalProfit(panel, panelId) {
        const profits = panel.querySelectorAll('.profit');
        if (profits.length >= 2) {
            const total = Array.from(profits).reduce((sum, el) => {
                return sum + (parseFloat(el.textContent) || 0);
            }, 0);

            const totalEl = panel.querySelector('.profit-value');
            if (totalEl) {
                totalEl.textContent = total.toFixed(2);
                totalEl.style.color = total >= 0 ? 'red' : 'green';
            }
        }
    }

    /**
     * 切换声音开关
     */
    toggleSound(panelId) {
        const config = this.state.panelConfigs.get(panelId);
        if (!config) return;

        config.soundEnabled = !config.soundEnabled;

        const panel = document.querySelector(`[data-panel-id="${panelId}"]`);
        if (panel) {
            const btn = panel.querySelector('.sound_switch');
            const icon = btn.querySelector('.layui-icon');
            btn.classList.toggle('layui-bg-green', config.soundEnabled);
            icon.classList.toggle('layui-icon-sound', config.soundEnabled);
            btn.classList.toggle('layui-bg-red', !config.soundEnabled);
            icon.classList.toggle('layui-icon-mute', !config.soundEnabled);

        }

        this.savePanels();
    }

    /**
     * 删除面板
     */
    removePanel(panel, panelId) {
        panel.style.transition = 'opacity 0.3s';
        panel.style.opacity = '0';

        setTimeout(() => {
            panel.remove();
            this.state.panelConfigs.delete(panelId);
            this.savePanels();
            this.showMessage('面板已删除', 'success');
        }, 300);
    }

    //#endregion

    //#region 工具方法

    /**
     * 防抖函数
     * @param {Function} func - 要执行的函数
     * @param {number} wait - 等待时间(ms)
     */
    debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }

    /**
     * 初始化用户交互监听器，用于解决浏览器自动播放限制
     */
    initUserInteractionListener() {
        const interactionEvents = ['click', 'keydown', 'touchstart', 'mousedown'];

        const handleInteraction = () => {
            if (!this.userHasInteracted) {
                this.userHasInteracted = true;

                // 移除所有监听器，避免重复调用
                interactionEvents.forEach(event => {
                    document.removeEventListener(event, handleInteraction);
                });
            }
        };

        // 添加交互监听器
        interactionEvents.forEach(event => {
            document.addEventListener(event, handleInteraction, { once: true, passive: true });
        });
    }

    /**
     * 检测音频播放能力
     * 在页面加载后检测是否能够播放音频，如果不能则弹出提示
     */
    async checkAudioPlaybackCapability() {
        // 创建一个静音的测试音频，用于检测播放能力
        const testAudio = new Audio('lib/air_raid_siren.mp3');
        testAudio.volume = 0; // 静音测试
        
        try {
            await testAudio.play();
            this.audioPlaybackAllowed = true;
            console.log('音频播放能力检测通过');
        } catch (error) {
            this.audioPlaybackAllowed = false;
            console.warn('音频播放被阻止，需要用户交互:', error);
            this.showAudioPermissionModal();
        } finally {
            testAudio.pause();
        }
    }

    /**
     * 显示音频权限提示弹窗
     */
    showAudioPermissionModal() {
        const content = `
            <div style="padding: 20px; text-align: center;">
                <div style="font-size: 24px; margin-bottom: 15px;">🔊</div>
                <h3 style="margin-bottom: 10px;">音频权限提示</h3>
                <p style="color: #666; margin-bottom: 20px; line-height: 1.6;">
                    当前浏览器阻止了自动播放音频功能。<br/>
                    为了确保警报功能正常工作，请点击下方按钮进行授权。
                </p>
                <button id="audioPermissionBtn" 
                    style="padding: 10px 40px; background: #16baaa; color: white; border: none; border-radius: 4px; font-size: 16px; cursor: pointer;">
                    点击授权音频
                </button>
            </div>
        `;

        const modalIndex = this.layer.open({
            type: 1,
            title: '音频权限',
            content: content,
            area: ['400px', '280px'],
            btn: [], // 不使用默认按钮
            shade: 0.5,
            shadeClose: true, // 点击遮罩关闭弹窗
            success: (layero, index) => {
                // 绑定按钮点击事件
                const btn = layero.find('#audioPermissionBtn')[0];
                btn.addEventListener('click', () => {
                    this.grantAudioPermission(index);
                });

                // 点击遮罩时也执行授权操作
                const shade = document.querySelector('.layui-layer-shade');
                if (shade) {
                    shade.addEventListener('click', () => {
                        this.grantAudioPermission(index);
                    });
                }
            }
        });
    }

    /**
     * 请求音频播放权限
     * @param {number} index - 弹窗索引
     */
    async grantAudioPermission(index) {
        const testAudio = new Audio('lib/air_raid_siren.mp3');
        testAudio.volume = 0;

        try {
            await testAudio.play();
            this.audioPlaybackAllowed = true;
            this.userHasInteracted = true;
            this.layer.close(index);
            this.showMessage('音频权限已获取', 'success');
        } catch (error) {
            console.warn('音频权限获取失败:', error);
            this.showMessage('音频权限获取失败', 'error');
        } finally {
            testAudio.pause();
        }
    }

    /**
     * 预加载音频文件
     */
    preloadAudio() {
        this.audio.preload = 'auto';

        // 使用事件监听器替代Promise处理，避免load()方法不返回Promise导致的错误
        const handleLoadSuccess = function () {
            this.audioInitialized = true;
            this.audio.removeEventListener('canplaythrough', handleLoadSuccess);
            this.audio.removeEventListener('error', handleLoadError);
        }.bind(this);

        const handleLoadError = function (error) {
            console.warn('音频预加载失败，但不影响功能:', error);
            this.audio.removeEventListener('canplaythrough', handleLoadSuccess);
            this.audio.removeEventListener('error', handleLoadError);
        }.bind(this);

        this.audio.addEventListener('canplaythrough', handleLoadSuccess);
        this.audio.addEventListener('error', handleLoadError);

        // 调用load方法，但不使用其返回值
        try {
            if (this.audio && typeof this.audio.load === 'function') {
                this.audio.load();
            }
        } catch (err) {
            console.warn('音频加载方法调用出错:', err);
        }
    }

    /**
     * 播放警报声音
     */
    playAlertSound(panelId) {
        if (!this.CONFIG.SOUND_ENABLED) return;
        if (!this.state.panelConfigs.get(panelId).soundEnabled) return;
        if (!this.userHasInteracted) {
            console.warn('无法自动播放音频：用户尚未与页面交互。请先点击页面以启用音频警报功能。');
            return;
        }

        try {
            // 停止当前正在播放的音频
            if (this.isPlaying && this.currentAudioInstance) {
                this.stopAlertSound();
            }

            this.isPlaying = true;
            this.currentAudioInstance = new Audio('lib/air_raid_siren.mp3');
            this.currentAudioInstance.volume = 1;

            this.currentAudioInstance.play().catch(error => {
                console.warn('音频播放失败:', error);
                this.isPlaying = false;
                this.currentAudioInstance = null;
            });

            this.currentAudioInstance.addEventListener('ended', () => {
                this.isPlaying = false;
                this.currentAudioInstance = null;
            });

            this.currentAudioInstance.addEventListener('error', (error) => {
                console.warn('音频播放失败:', error);
                this.isPlaying = false;
                this.currentAudioInstance = null;
            });
        } catch (error) {
            console.warn('音频播放异常:', error);
            this.isPlaying = false;
            this.currentAudioInstance = null;
        }
    }

    stopAlertSound() {
        if (this.isPlaying && this.currentAudioInstance) {
            // 休眠200ms后执行停止音频播放操作（可调整或取消延时）
            setTimeout(() => {
                try {
                    this.currentAudioInstance.pause();
                    this.currentAudioInstance.currentTime = 0;
                    // 移除事件监听（可选）
                    const clone = this.currentAudioInstance.cloneNode(true);
                    this.currentAudioInstance = clone;
                } catch (error) {
                    console.warn('停止音频播放时出错:', error);
                } finally {
                    this.isPlaying = false;
                    this.currentAudioInstance = null;
                }
            }, 1000); // 保持旧版延时
        }
    }


    /**
     * 显示消息提示
     * @param {string} message - 消息内容
     * @param {string} type - 消息类型(success, error, warning)
     */
    showMessage(message, type = 'info') {
        if (this.layer) {
            const iconMap = { success: 1, error: 2, warning: 0 };
            this.layer.msg(message, {
                icon: iconMap[type] || 0,
                time: 2000
            });
        } else {
            console.log(`[${type.toUpperCase()}] ${message}`);
        }
    }

    /**
     * 保存面板到本地存储
     */
    savePanels() {
        try {
            const configs = Array.from(this.state.panelConfigs.entries());
            // 确保保存所有需要的字段
            const filteredConfigs = configs.map(([panelId, config]) => {
                return [panelId, {
                    symbol0: config.symbol0,
                    symbol0_remark: config.symbol0_remark,
                    symbol1: config.symbol1,
                    symbol1_remark: config.symbol1_remark,
                    soundEnabled: config.soundEnabled,
                    correspondingState: config.correspondingState,
                    basis_high: config.basis_high,
                    basis_low: config.basis_low,
                    symbol0_config: {
                        direction: config.symbol0_config.direction,
                        entryPrice: config.symbol0_config.entryPrice,
                        quantity: config.symbol0_config.quantity
                    },
                    symbol1_config: {
                        direction: config.symbol1_config.direction,
                        entryPrice: config.symbol1_config.entryPrice,
                        quantity: config.symbol1_config.quantity
                    }
                }];
            });
            localStorage.setItem('monitoring_panels', JSON.stringify(filteredConfigs));
        } catch (error) {
            console.error('保存面板配置失败:', error);
        }
    }

    /**
     * 从本地存储加载面板
     */
    loadSavedPanels() {
        try {
            const saved = localStorage.getItem('monitoring_panels');
            if (saved) {
                const configs = JSON.parse(saved);
                // 首先将所有配置加载到panelConfigs中
                configs.forEach(([panelId, config]) => {
                    // 先保存配置到类的字段中
                    this.state.panelConfigs.set(panelId, { ...config });
                    // 记录最大的面板ID，确保面板计数正确
                    this.state.panelCounter = Math.max(
                        this.state.panelCounter,
                        parseInt(panelId.split('-')[1]) || 0
                    );
                });

                // 然后再创建面板
                configs.forEach(([panelId, config]) => {
                    // 创建面板，但不覆盖已保存的配置
                    this.createPanelWithConfig(panelId, config);
                });
            }
        } catch (error) {
            console.error('加载面板配置失败:', error);
        }
    }

    /**
     * 使用已有的配置创建面板
     * @param {string} panelId - 面板ID
     * @param {object} config - 面板配置
     */
    createPanelWithConfig(panelId, config) {
        const template = document.querySelector('.template-panel');
        if (!template) return;

        const panel = template.cloneNode(true);
        panel.classList.remove('template-panel');
        panel.setAttribute('data-panel-id', panelId);

        // 设置显示内容
        this.setupPanelDisplay(panel, panelId, config.symbol0, config.symbol1);

        // 绑定事件
        this.bindPanelEvents(panel, panelId);

        // 插入到页面
        template.parentNode.insertBefore(panel, template);
        panel.style.display = 'block';

        // 同步配置到面板DOM
        if (panel) {
            // 设置correspondingState
            panel.querySelector('.correspondingState').value = config.correspondingState;
            // 设置basis_low和basis_high
            panel.querySelector('.basis_low').value = config.basis_low;
            panel.querySelector('.basis_high').value = config.basis_high;
            // 设置交易配置
            const items = panel.querySelectorAll('.comparison-item');
            items.forEach((item, index) => {
                const symbolConfig = config[`symbol${index}_config`];
                if (symbolConfig) {
                    item.querySelector('.direction').value = symbolConfig.direction;
                    item.querySelector('.entryPrice').value = symbolConfig.entryPrice;
                    item.querySelector('.quantity').value = symbolConfig.quantity;
                }
            });
        }
    }

    //#endregion
}

// 应用启动
document.addEventListener('DOMContentLoaded', () => {
    window.dataMonitor = new DataMonitoring();
});

// 全局错误处理
window.addEventListener('error', (event) => {
    console.error('全局错误:', event.error);
});

// 页面卸载时清理资源
window.addEventListener('beforeunload', () => {
    if (window.dataMonitor) {
        window.dataMonitor.destroy();
    }
});