/**
 * WebSocket 测试页面控制器
 * 
 * 功能描述：
 * - 提供一个简单的WebSocket测试界面，可以直接在浏览器中测试WebSocket连接
 * - 包含API调用监控功能，帮助前端开发者了解接口调用情况
 * - 支持聊天测试和通知系统测试两种模式
 * 
 * 架构定位：
 * - 层级：Gateway层（网关层）
 * - 职责：HTTP协议处理、测试页面暴露
 * - 依赖：无业务逻辑依赖，纯测试工具
 * 
 * 职责分离：
 * - 测试界面：提供交互式WebSocket测试页面
 * - 连接测试：支持WebSocket连接、认证、消息发送测试
 * - API监控：实时显示HTTP请求和响应信息
 * - 通知测试：提供通知系统功能测试
 * 
 * 最近修改：
 * - 2026-01-14: 架构优化 - 从Business层迁移到Gateway层，符合四层架构规范 (修改者: moyin)
 * - 2026-01-14: 代码规范优化 - 完善文件头注释和职责分离描述 (修改者: moyin)
 * - 2026-01-09: 功能新增 - 初始创建WebSocket测试页面控制器 (修改者: moyin)
 * 
 * @author moyin
 * @version 2.0.0
 * @since 2026-01-09
 * @lastModified 2026-01-14
 */

import { Controller, Get, Res } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { Response } from 'express';

@ApiTags('websocket')
@Controller('websocket-test')
export class WebSocketTestController {

  @Get()
  @ApiOperation({
    summary: '🔌 WebSocket 测试页面 + 通知系统 - 一键测试工具 + API监控',
    description: `
**🚀 功能强大的WebSocket测试工具 + 通知系统**

提供完整的WebSocket测试功能：
- ✅ 自动获取JWT Token
- ✅ 一键建立WebSocket连接  
- ✅ 用户认证和登录
- ✅ 聊天消息发送测试
- ✅ 位置更新测试
- ✅ 实时消息日志
- 📡 **API调用监控** - 实时显示所有HTTP请求
- 🔔 **通知系统测试** - 完整的通知功能测试

**新增通知系统功能**：
- 🔔 实时通知WebSocket连接
- 📢 通知发送和接收测试
- 📋 通知列表管理
- 🔢 未读通知统计
- 🎯 支持系统、用户、广播通知
- ⏰ 定时通知功能

**使用方法**：
1. 点击下方"Execute"按钮
2. 在响应中会返回完整的测试页面HTML
3. 或直接访问: /websocket-test

**推荐**：直接在新标签页中打开 [/websocket-test](/websocket-test)
    `
  })
  @ApiResponse({
    status: 200,
    description: 'WebSocket测试页面HTML',
    content: {
      'text/html': {
        schema: {
          type: 'string'
        }
      }
    }
  })
  getTestPage(@Res() res: Response) {
    const html = `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket 测试工具 + 通知系统 - Pixel Game Server</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            max-width: 1400px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 20px;
            min-height: 200px; /* 确保容器有最小高度 */
        }
        .status {
            padding: 10px;
            border-radius: 4px;
            margin-bottom: 15px;
            font-weight: bold;
        }
        .status.disconnected { background-color: #ffebee; color: #c62828; }
        .status.connected { background-color: #e8f5e8; color: #2e7d32; }
        .status.connecting { background-color: #fff3e0; color: #ef6c00; }
        
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: 500;
        }
        input, textarea, select, button {
            width: 100%;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
        }
        button {
            background-color: #1976d2;
            color: white;
            border: none;
            cursor: pointer;
            font-weight: 500;
        }
        button:hover { background-color: #1565c0; }
        button:disabled {
            background-color: #ccc;
            cursor: not-allowed;
        }
        
        .message-log, .api-log {
            height: 300px;
            overflow-y: auto;
            overflow-x: hidden;
            border: 1px solid #ddd;
            padding: 10px;
            background-color: #fafafa;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            word-wrap: break-word;
            box-sizing: border-box;
            max-width: 100%;
            width: 100%;
        }
        .message-item {
            margin-bottom: 8px;
            padding: 4px 8px;
            border-radius: 3px;
            word-wrap: break-word;
            overflow-wrap: break-word;
            max-width: 100%;
            box-sizing: border-box;
            overflow: hidden;
            white-space: pre-wrap;
        }
        .message-sent { background-color: #e3f2fd; }
        .message-received { background-color: #f3e5f5; }
        .message-system { background-color: #fff3e0; }
        .message-error { background-color: #ffebee; }
        
        .api-log {
            background-color: #f8f9fa;
        }
        .api-item {
            margin-bottom: 8px;
            padding: 8px;
            border-radius: 3px;
            border-left: 4px solid #ddd;
            word-wrap: break-word;
            overflow-wrap: break-word;
            max-width: 100%;
            box-sizing: border-box;
            overflow: hidden;
            white-space: pre-wrap;
        }
        .api-request { 
            background-color: #e3f2fd; 
            border-left-color: #2196f3;
        }
        .api-response-success { 
            background-color: #e8f5e8; 
            border-left-color: #4caf50;
        }
        .api-response-error { 
            background-color: #ffebee; 
            border-left-color: #f44336;
        }
        .api-method {
            font-weight: bold;
            color: #1976d2;
        }
        .api-url {
            color: #666;
            word-break: break-all;
            overflow-wrap: break-word;
            white-space: normal;
            max-width: 100%;
            display: inline-block;
        }
        .api-status {
            font-weight: bold;
        }
        .api-status.success { color: #4caf50; }
        .api-status.error { color: #f44336; }
        .api-body {
            margin-top: 5px;
            padding: 5px;
            background-color: rgba(0,0,0,0.05);
            border-radius: 3px;
            font-size: 11px;
            max-height: 100px;
            overflow-y: auto;
            word-wrap: break-word;
            overflow-wrap: break-word;
            white-space: pre-wrap;
            max-width: 100%;
            overflow-x: hidden;
        }
        
        .quick-actions {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 10px;
            margin-top: 15px;
        }
        .quick-action {
            padding: 8px 12px;
            background-color: #f5f5f5;
            border: 1px solid #ddd;
            border-radius: 4px;
            cursor: pointer;
            text-align: center;
            font-size: 12px;
        }
        .quick-action:hover { background-color: #eeeeee; }
        
        .info-panel {
            background-color: #e8f4fd;
            border: 1px solid #bbdefb;
            border-radius: 4px;
            padding: 15px;
            margin-bottom: 20px;
        }
        .info-panel h3 {
            margin-top: 0;
            color: #1976d2;
        }
        
        .two-column {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            min-height: 400px; /* 确保两列布局有最小高度 */
        }
        
        .logs-section {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            max-width: 100%;
            overflow: hidden;
        }
        
        .logs-section .container {
            max-width: 100%;
            min-width: 0;
            overflow: hidden;
        }
        
        @media (max-width: 768px) {
            .two-column, .logs-section {
                grid-template-columns: 1fr;
            }
            .logs-section .container {
                max-width: 100vw;
                overflow: hidden;
            }
            .message-log, .api-log {
                max-width: calc(100vw - 60px);
            }
        }
        
        /* 通知模式特定样式 */
        #noticeMode {
            width: 100%;
            min-height: 500px;
        }
        
        #noticeMode .container {
            background: white;
            border: 1px solid #ddd;
            min-height: 300px;
        }
        
        #noticeMode h2, #noticeMode h3 {
            color: #1976d2;
            margin-top: 0;
        }
    </style>
</head>
<body>
    <h1>🎮 Pixel Game Server - WebSocket 测试工具 + 通知系统</h1>
    
    <div class="info-panel">
        <h3>📋 使用说明</h3>
        <p><strong>🚀 一键测试:</strong> 点击"🚀 一键测试"按钮，系统会自动生成随机账号并完成所有步骤</p>
        <p><strong>🔐 认证方式:</strong> 支持密码登录和验证码登录两种方式</p>
        <p><strong>🎲 随机账号:</strong> 自动生成符合要求的随机测试账号，方便多用户测试</p>
        <p><strong>🔧 灵活配置:</strong> 可以自定义用户信息、使用默认账号或生成随机账号</p>
        <p><strong>📡 API监控:</strong> 实时显示所有HTTP请求，帮助前端开发者了解接口调用情况</p>
        <p><strong>WebSocket地址:</strong> <code>wss://whaletownend.xinghangee.icu/game</code></p>
        
        <div style="margin-top: 15px; padding: 10px; background-color: #e8f5e8; border-radius: 4px;">
            <strong>💡 新功能亮点：</strong><br>
            • 🎲 随机账号生成：自动生成符合要求的测试账号，方便多用户测试<br>
            • 🤖 智能注册登录：自动检测账号状态，不存在则自动注册<br>
            • 📱 验证码注册：支持邮箱验证码注册新账号<br>
            • 🔍 调试验证码：自动获取验证码，无需真实邮箱<br>
            • 🔄 自动重试：用户名冲突时自动生成新用户名<br>
            • 💾 本地存储：自动保存Token，下次访问无需重新获取<br>
            • 📧 真实邮箱支持：检测到真实邮箱时使用真实验证码发送<br>
            • 📡 **API调用监控**：实时显示所有HTTP请求和响应，方便调试<br>
            • 🔍 详细日志：支持显示请求体、响应体和调用统计<br>
            • 🔔 **通知系统测试**：完整的通知功能测试，支持实时推送和API调用
        </div>
        
        <div style="margin-top: 15px; padding: 10px; background-color: #fff3e0; border-radius: 4px;">
            <strong>🎯 多标签页测试说明：</strong><br>
            • 每个标签页都有独立的标签页ID，确保账号不冲突<br>
            • 每次点击"一键测试"都会生成新的随机账号<br>
            • 邮箱格式：test[时间戳后6位][标签页ID][随机码]@[域名] (简洁格式)<br>
            • 用户名格式：user[时间戳后6位][标签页ID][随机码]<br>
            • 密码自动生成，包含字母数字，符合安全要求<br>
            • 支持同时打开多个标签页进行多用户测试<br>
            • 每个标签页的Token独立存储，互不干扰
        </div>
        
        <div style="margin-top: 15px; padding: 10px; background-color: #e3f2fd; border-radius: 4px;">
            <strong>📡 API监控功能说明：</strong><br>
            • 🔍 实时监控：自动捕获所有HTTP请求和响应<br>
            • 📊 详细信息：显示请求方法、URL、状态码、响应时间<br>
            • 📋 请求体显示：可选择显示请求体内容，方便调试<br>
            • 📥 响应体显示：可选择显示响应体内容<br>
            • 📈 统计信息：实时统计请求总数、成功数、失败数<br>
            • 🎨 颜色区分：请求、成功响应、错误响应用不同颜色标识<br>
            • ⏱️ 性能分析：显示每个请求的耗时，便于性能优化
        </div>
        
        <div style="margin-top: 15px; padding: 10px; background-color: #e3f2fd; border-radius: 4px;">
            <strong>🔗 相关链接：</strong>
            <a href="/api-docs" target="_blank" style="margin-right: 15px; color: #1976d2; text-decoration: none; font-weight: bold;">📚 返回 API 文档</a>
            <a href="/websocket/docs" target="_blank" style="margin-right: 15px; color: #1976d2; text-decoration: none;">📖 WebSocket API 文档</a>
            <a href="/websocket-api/connection-info" target="_blank" style="color: #1976d2; text-decoration: none;">🔧 连接配置信息</a>
        </div>
    </div>

    <!-- 功能切换按钮 -->
    <div class="container" style="text-align: center; margin-bottom: 20px;">
        <h2>🎛️ 功能选择</h2>
        <div style="display: flex; gap: 10px; justify-content: center;">
            <button id="chatModeBtn" onclick="switchMode('chat')" style="flex: 1; max-width: 200px; background-color: #1976d2;">💬 聊天测试</button>
            <button id="noticeModeBtn" onclick="switchMode('notice')" style="flex: 1; max-width: 200px; background-color: #666;">🔔 通知测试</button>
        </div>
    </div>

    <!-- 聊天模式 -->
    <div id="chatMode">
    <div class="two-column">
        <div class="container">
            <h2>🔌 连接控制</h2>
            <div id="connectionStatus" class="status disconnected">未连接</div>
            
            <div class="form-group">
                <label for="wsUrl">WebSocket 地址:</label>
                <input type="text" id="wsUrl" value="wss://whaletownend.xinghangee.icu/game" />
            </div>
            
            <button id="connectBtn" onclick="toggleConnection()">连接</button>
            <button onclick="quickTest()" style="background-color: #4caf50; margin-top: 10px;">🚀 一键测试 (自动获取Token + 连接 + 登录)</button>
            
            <h3>🔐 用户认证</h3>
            <div class="form-group">
                <label>认证方式:</label>
                <div style="display: flex; gap: 10px; margin-bottom: 10px;">
                    <button type="button" onclick="switchAuthMode('password')" id="passwordModeBtn" style="flex: 1; background-color: #1976d2;">密码登录</button>
                    <button type="button" onclick="switchAuthMode('code')" id="codeModeBtn" style="flex: 1; background-color: #666;">验证码登录</button>
                </div>
            </div>
            
            <!-- 密码登录模式 -->
            <div id="passwordAuthMode">
                <div class="form-group">
                    <label for="testCredentials">测试账号:</label>
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
                        <input type="email" id="testEmail" placeholder="邮箱" value="test@example.com" />
                        <input type="password" id="testPassword" placeholder="密码" value="Test123456" />
                    </div>
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px;">
                        <input type="text" id="testUsername" placeholder="用户名 (可选)" />
                        <input type="text" id="testNickname" placeholder="昵称 (可选)" />
                    </div>
                    <div style="display: flex; gap: 10px; margin-top: 10px;">
                        <button id="getTokenBtn" onclick="getTestToken()" style="flex: 2;">获取测试Token</button>
                        <button onclick="smartRegisterAndLogin()" style="flex: 2; background-color: #ff9800;">智能注册登录</button>
                        <button onclick="useDefaultAccount()" style="flex: 1; background-color: #4caf50;">默认账号</button>
                        <button onclick="applyRandomTestAccount()" style="flex: 1; background-color: #9c27b0;">随机账号</button>
                    </div>
                    <div style="display: flex; gap: 10px; margin-top: 5px;">
                        <button onclick="clearCurrentTabToken()" style="flex: 1; background-color: #f44336; font-size: 12px;">清空本标签页Token</button>
                        <button onclick="clearAllTabTokens()" style="flex: 1; background-color: #ff5722; font-size: 12px;">清空所有标签页Token</button>
                    </div>
                </div>
            </div>
            
            <!-- 验证码登录模式 -->
            <div id="codeAuthMode" style="display: none;">
                <div class="form-group">
                    <label for="codeEmail">邮箱地址:</label>
                    <input type="email" id="codeEmail" placeholder="输入邮箱地址" value="test@example.com" />
                    <div style="display: flex; gap: 10px; margin-top: 10px;">
                        <button onclick="sendVerificationCode()" id="sendCodeBtn" style="flex: 2;">发送验证码</button>
                        <button onclick="getDebugVerificationCode(document.getElementById('codeEmail').value)" style="flex: 1; background-color: #9c27b0;">获取验证码</button>
                    </div>
                </div>
                <div class="form-group">
                    <label for="verificationCode">验证码:</label>
                    <input type="text" id="verificationCode" placeholder="输入6位验证码" maxlength="6" />
                    <button onclick="loginWithCode()" id="codeLoginBtn" style="margin-top: 10px;" disabled>验证码登录</button>
                </div>
                <div class="form-group" style="border-top: 1px solid #ddd; padding-top: 15px; margin-top: 15px;">
                    <label>如果邮箱未注册，可以先注册:</label>
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px;">
                        <input type="text" id="codeUsername" placeholder="用户名 (可选)" />
                        <input type="text" id="codeNickname" placeholder="昵称 (可选)" />
                    </div>
                    <input type="password" id="codePassword" placeholder="设置密码" style="margin-top: 10px;" />
                    <div style="display: flex; gap: 10px; margin-top: 10px;">
                        <button onclick="registerWithCode()" id="registerCodeBtn" style="flex: 2; background-color: #ff9800;">验证码注册</button>
                        <button onclick="sendEmailVerificationForRegister()" style="flex: 1; background-color: #9c27b0;">发送注册验证码</button>
                    </div>
                </div>
            </div>
            
            <div class="form-group">
                <label for="jwtToken">JWT Token:</label>
                <textarea id="jwtToken" rows="3" placeholder="点击上方按钮自动获取，或手动输入JWT Token"></textarea>
            </div>
            <button id="loginBtn" onclick="login()" disabled>登录</button>
        </div>

        <div class="container">
            <h2>💬 消息发送</h2>
            
            <div class="form-group">
                <label for="messageType">消息类型:</label>
                <select id="messageType">
                    <option value="chat">聊天消息</option>
                    <option value="position">位置更新</option>
                </select>
            </div>
            
            <div id="chatFields">
                <div class="form-group">
                    <label for="chatContent">消息内容:</label>
                    <input type="text" id="chatContent" placeholder="输入聊天消息" />
                </div>
                <div class="form-group">
                    <label for="chatScope">消息范围:</label>
                    <select id="chatScope">
                        <option value="local">本地 (当前地图)</option>
                        <option value="global">全局 (所有玩家)</option>
                    </select>
                </div>
            </div>
            
            <div id="positionFields" style="display: none;">
                <div class="form-group">
                    <label for="posX">X坐标:</label>
                    <input type="number" id="posX" value="150" />
                </div>
                <div class="form-group">
                    <label for="posY">Y坐标:</label>
                    <input type="number" id="posY" value="400" />
                </div>
                <div class="form-group">
                    <label for="mapId">地图ID:</label>
                    <select id="mapId">
                        <option value="whale_port">Whale Port (鲸鱼港)</option>
                        <option value="pumpkin_valley">Pumpkin Valley (南瓜谷)</option>
                        <option value="novice_village">Novice Village (新手村)</option>
                    </select>
                </div>
            </div>
            
            <button id="sendBtn" onclick="sendMessage()" disabled>发送消息</button>
            
            <div class="quick-actions">
                <div class="quick-action" onclick="sendQuickMessage('Hello!')">快速发送: Hello!</div>
                <div class="quick-action" onclick="sendQuickMessage('大家好！')">快速发送: 大家好！</div>
                <div class="quick-action" onclick="sendQuickPosition()">发送位置更新</div>
                <div class="quick-action" onclick="clearLog()">清空消息日志</div>
                <div class="quick-action" onclick="clearApiLog()">清空API日志</div>
                <div class="quick-action" onclick="showDebugInfo()">显示调试信息</div>
            </div>
        </div>
    </div>
    </div>

    <!-- 通知模式 -->
    <div id="noticeMode" style="display: none; background-color: #f0f8ff; border: 2px solid red; padding: 20px;">
        <h1 style="color: red; font-size: 24px;">🔔 通知测试模式</h1>
        <p style="color: blue; font-size: 18px;">如果你能看到这个文字，说明通知模式正常显示了！</p>
        
        <div class="two-column">
            <div class="container">
                <h2>🔔 通知系统控制</h2>
                <div id="noticeConnectionStatus" class="status disconnected">未连接</div>
                
                <div class="form-group">
                    <label for="noticeWsUrl">通知WebSocket地址:</label>
                    <input type="text" id="noticeWsUrl" value="ws://localhost:3000/ws/notice" />
                </div>
                
                <button id="noticeConnectBtn" onclick="toggleNoticeConnection()">连接通知系统</button>
                
                <h3>🔐 用户认证</h3>
                <div class="form-group">
                    <label for="noticeUserId">用户ID:</label>
                    <input type="number" id="noticeUserId" value="1" placeholder="输入用户ID" />
                </div>
                
                <div class="form-group">
                    <label for="noticeJwtToken">JWT Token:</label>
                    <textarea id="noticeJwtToken" rows="3" placeholder="输入JWT Token (可从聊天模式复制)"></textarea>
                    <button onclick="copyTokenFromChat()" style="margin-top: 5px; background-color: #4caf50;">从聊天模式复制Token</button>
                </div>
                
                <button onclick="authenticateNotice()">认证通知连接</button>
            </div>

            <div class="container">
                <h2>📢 发送通知</h2>
                
                <div class="form-group">
                    <label for="noticeTitle">通知标题:</label>
                    <input type="text" id="noticeTitle" placeholder="输入通知标题" />
                </div>
                
                <div class="form-group">
                    <label for="noticeContent">通知内容:</label>
                    <textarea id="noticeContent" rows="3" placeholder="输入通知内容"></textarea>
                </div>
                
                <div class="form-group">
                    <label for="noticeType">通知类型:</label>
                    <select id="noticeType">
                        <option value="system">系统通知</option>
                        <option value="user">用户通知</option>
                        <option value="broadcast">广播通知</option>
                    </select>
                </div>
                
                <div class="form-group">
                    <label for="targetUserId">目标用户ID (留空为广播):</label>
                    <input type="number" id="targetUserId" placeholder="目标用户ID" />
                </div>
                
                <div class="form-group">
                    <label for="scheduledTime">定时发送 (可选):</label>
                    <input type="datetime-local" id="scheduledTime" />
                </div>
                
                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
                    <button onclick="sendNoticeViaAPI()" style="background-color: #4caf50;">� 过通过API发送</button>
                    <button onclick="sendNoticeViaWS()" style="background-color: #ff9800;">🔌 通过WebSocket发送</button>
                </div>
                
                <div class="quick-actions" style="margin-top: 15px;">
                    <div class="quick-action" onclick="sendQuickNotice('系统维护', '系统将在今晚进行维护')">快速: 系统维护</div>
                    <div class="quick-action" onclick="sendQuickNotice('新功能上线', '我们上线了新的通知功能！')">快速: 新功能</div>
                    <div class="quick-action" onclick="sendQuickNotice('测试通知', '这是一条测试通知')">快速: 测试通知</div>
                    <div class="quick-action" onclick="loadNoticeList()">� 刷取新通知列表</div>
                    <div class="quick-action" onclick="getUnreadCount()">� 获取未读数日</div>
                    <div class="quick-action" onclick="clearNoticeLog()">🗑️ 清空通知日志</div>
                </div>
                
                <h3>📋 通知管理</h3>
                <div style="display: flex; gap: 10px; margin-bottom: 10px;">
                    <button onclick="loadNoticeList()" style="flex: 1;">获取通知列表</button>
                    <button onclick="getUnreadCount()" style="flex: 1; background-color: #ff9800;">获取未读数量</button>
                </div>
                
                <div id="noticeList" style="max-height: 200px; overflow-y: auto; border: 1px solid #ddd; padding: 10px; background-color: #fafafa;">
                    <div style="text-align: center; color: #666;">点击"获取通知列表"加载通知</div>
                </div>
            </div>
        </div>
    </div>

    <!-- 日志区域 - 消息日志和API监控并排显示 -->
    <div class="logs-section">
        <div class="container">
            <h2 id="logTitle">📋 消息日志</h2>
            <div id="messageLog" class="message-log"></div>
        </div>
        
        <div class="container">
            <h2 id="apiLogTitle">📡 API 调用日志</h2>
            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
                <span style="font-size: 14px; color: #666;" id="apiLogSubtitle">实时监控前端API调用</span>
                <div>
                    <button onclick="clearApiLog()" style="padding: 4px 8px; font-size: 12px; background-color: #ff9800;">清空日志</button>
                    <button onclick="toggleApiLogDetails()" id="toggleDetailsBtn" style="padding: 4px 8px; font-size: 12px; background-color: #9c27b0; margin-left: 5px;">显示详情</button>
                </div>
            </div>
            <div id="apiLog" class="api-log"></div>
            <div style="margin-top: 10px; font-size: 12px; color: #666;">
                <div>📊 统计: <span id="apiStats">请求: 0, 成功: 0, 失败: 0</span></div>
                <div style="margin-top: 5px;">
                    <label style="font-size: 12px;">
                        <input type="checkbox" id="autoScrollApi" checked> 自动滚动
                    </label>
                    <label style="font-size: 12px; margin-left: 15px;">
                        <input type="checkbox" id="showRequestBody" checked> 显示请求体
                    </label>
                    <label style="font-size: 12px; margin-left: 15px;">
                        <input type="checkbox" id="showResponseBody"> 显示响应体
                    </label>
                </div>
            </div>
        </div>
    </div>

    <script>
        let ws = null;
        let isLoggedIn = false;
        let currentAuthMode = 'password';
        let generatedAccounts = new Set();
        let apiCallCount = 0;
        let apiSuccessCount = 0;
        let apiErrorCount = 0;
        let showApiDetails = false;
        let currentMode = 'chat'; // 当前模式：chat 或 notice
        
        // 通知系统相关变量
        let noticeWs = null;
        let noticeAuthenticated = false;
        
        // API监控相关变量
        const originalFetch = window.fetch;
        
        // 重写fetch函数以监控API调用
        window.fetch = function(...args) {
            const [url, options = {}] = args;
            const method = options.method || 'GET';
            const startTime = Date.now();
            
            // 记录请求
            logApiCall('request', {
                method,
                url,
                body: options.body,
                headers: options.headers
            });
            
            // 调用原始fetch
            return originalFetch.apply(this, args)
                .then(response => {
                    const endTime = Date.now();
                    const duration = endTime - startTime;
                    
                    // 记录响应
                    logApiCall('response', {
                        method,
                        url,
                        status: response.status,
                        statusText: response.statusText,
                        duration,
                        success: response.ok
                    }, response.clone());
                    
                    return response;
                })
                .catch(error => {
                    const endTime = Date.now();
                    const duration = endTime - startTime;
                    
                    // 记录错误
                    logApiCall('error', {
                        method,
                        url,
                        error: error.message,
                        duration,
                        success: false
                    });
                    
                    throw error;
                });
        };
        
        // 记录API调用
        function logApiCall(type, data, response = null) {
            const timestamp = new Date();
            const apiLog = document.getElementById('apiLog');
            const apiItem = document.createElement('div');
            
            if (type === 'request') {
                apiCallCount++;
                apiItem.className = 'api-item api-request';
                
                let content = \`
                    <div>
                        <span class="api-method">\${data.method}</span> 
                        <span class="api-url">\${data.url}</span>
                        <span style="float: right; color: #666; font-size: 11px;">\${timestamp.toLocaleTimeString()}</span>
                    </div>
                \`;
                
                // 显示请求体
                if (document.getElementById('showRequestBody')?.checked && data.body) {
                    let bodyContent = data.body;
                    try {
                        if (typeof bodyContent === 'string') {
                            bodyContent = JSON.stringify(JSON.parse(bodyContent), null, 2);
                        }
                    } catch (e) {
                        // 保持原始格式
                    }
                    content += \`<div class="api-body">📤 请求体: <pre>\${bodyContent}</pre></div>\`;
                }
                
                // 显示请求头（如果开启详情模式）
                if (showApiDetails && data.headers) {
                    content += \`<div class="api-body">📋 请求头: <pre>\${JSON.stringify(data.headers, null, 2)}</pre></div>\`;
                }
                
                apiItem.innerHTML = content;
                
            } else if (type === 'response') {
                if (data.success) {
                    apiSuccessCount++;
                    apiItem.className = 'api-item api-response-success';
                } else {
                    apiErrorCount++;
                    apiItem.className = 'api-item api-response-error';
                }
                
                let content = \`
                    <div>
                        <span class="api-method">\${data.method}</span> 
                        <span class="api-url">\${data.url}</span>
                        <span class="api-status \${data.success ? 'success' : 'error'}">\${data.status} \${data.statusText}</span>
                        <span style="float: right; color: #666; font-size: 11px;">\${data.duration}ms</span>
                    </div>
                \`;
                
                // 显示响应体
                if (document.getElementById('showResponseBody')?.checked && response) {
                    response.text().then(responseText => {
                        try {
                            const jsonResponse = JSON.parse(responseText);
                            const formattedResponse = JSON.stringify(jsonResponse, null, 2);
                            const responseDiv = apiItem.querySelector('.response-body') || document.createElement('div');
                            responseDiv.className = 'api-body response-body';
                            responseDiv.innerHTML = \`📥 响应体: <pre>\${formattedResponse}</pre>\`;
                            if (!apiItem.querySelector('.response-body')) {
                                apiItem.appendChild(responseDiv);
                            }
                        } catch (e) {
                            if (responseText) {
                                const responseDiv = apiItem.querySelector('.response-body') || document.createElement('div');
                                responseDiv.className = 'api-body response-body';
                                responseDiv.innerHTML = \`📥 响应体: <pre>\${responseText}</pre>\`;
                                if (!apiItem.querySelector('.response-body')) {
                                    apiItem.appendChild(responseDiv);
                                }
                            }
                        }
                    }).catch(() => {
                        // 忽略响应体读取错误
                    });
                }
                
                apiItem.innerHTML = content;
                
            } else if (type === 'error') {
                apiErrorCount++;
                apiItem.className = 'api-item api-response-error';
                
                const content = \`
                    <div>
                        <span class="api-method">\${data.method}</span> 
                        <span class="api-url">\${data.url}</span>
                        <span class="api-status error">ERROR</span>
                        <span style="float: right; color: #666; font-size: 11px;">\${data.duration}ms</span>
                    </div>
                    <div class="api-body">❌ 错误: \${data.error}</div>
                \`;
                
                apiItem.innerHTML = content;
            }
            
            apiLog.appendChild(apiItem);
            
            // 自动滚动
            if (document.getElementById('autoScrollApi')?.checked) {
                apiLog.scrollTop = apiLog.scrollHeight;
            }
            
            // 更新统计
            updateApiStats();
        }
        
        // 更新API统计
        function updateApiStats() {
            const statsEl = document.getElementById('apiStats');
            if (statsEl) {
                statsEl.textContent = \`请求: \${apiCallCount}, 成功: \${apiSuccessCount}, 失败: \${apiErrorCount}\`;
            }
        }
        
        // 清空API日志
        function clearApiLog() {
            document.getElementById('apiLog').innerHTML = '';
            apiCallCount = 0;
            apiSuccessCount = 0;
            apiErrorCount = 0;
            updateApiStats();
            addMessage('system', '🗑️ API调用日志已清空');
        }
        
        // 切换API日志详情显示
        function toggleApiLogDetails() {
            showApiDetails = !showApiDetails;
            const btn = document.getElementById('toggleDetailsBtn');
            btn.textContent = showApiDetails ? '隐藏详情' : '显示详情';
            btn.style.backgroundColor = showApiDetails ? '#f44336' : '#9c27b0';
            
            addMessage('system', showApiDetails ? '🔍 API详情模式已开启' : '🔍 API详情模式已关闭');
        }
        
        // 测试邮箱域名列表
        const TEST_EMAIL_DOMAINS = [
            'test.com', 'example.com', 'demo.org', 'sample.net', 'testmail.org'
        ];
        
        // 检测邮箱是否为测试邮箱
        function isTestEmail(email) {
            if (!email || typeof email !== 'string') {
                return true;
            }
            
            const emailLower = email.toLowerCase();
            
            if (emailLower.includes('test_user_') || emailLower.startsWith('test')) {
                return true;
            }
            
            const domain = emailLower.split('@')[1];
            if (domain && TEST_EMAIL_DOMAINS.includes(domain)) {
                return true;
            }
            
            const testPatterns = [
                /test.*@/,
                /demo.*@/,
                /sample.*@/,
                /@.*test\\./,
                /@.*demo\\./,
                /@.*sample\\./
            ];
            
            for (const pattern of testPatterns) {
                if (pattern.test(emailLower)) {
                    return true;
                }
            }
            
            return false;
        }
        
        // 默认测试账号配置
        const DEFAULT_TEST_ACCOUNT = {
            email: 'websocket.test@example.com',
            password: 'WebSocket123!',
            username: 'websocket_test_user'
        };
        
        // 切换认证模式
        function switchAuthMode(mode) {
            currentAuthMode = mode;
            const passwordMode = document.getElementById('passwordAuthMode');
            const codeMode = document.getElementById('codeAuthMode');
            const passwordBtn = document.getElementById('passwordModeBtn');
            const codeBtn = document.getElementById('codeModeBtn');
            
            if (mode === 'password') {
                passwordMode.style.display = 'block';
                codeMode.style.display = 'none';
                passwordBtn.style.backgroundColor = '#1976d2';
                codeBtn.style.backgroundColor = '#666';
            } else {
                passwordMode.style.display = 'none';
                codeMode.style.display = 'block';
                passwordBtn.style.backgroundColor = '#666';
                codeBtn.style.backgroundColor = '#1976d2';
            }
        }
        
        // 发送验证码
        async function sendVerificationCode() {
            const email = document.getElementById('codeEmail').value.trim();
            const sendCodeBtn = document.getElementById('sendCodeBtn');
            
            if (!email) {
                addMessage('error', '❌ 请输入邮箱地址');
                return;
            }
            
            sendCodeBtn.disabled = true;
            sendCodeBtn.textContent = '发送中...';
            addMessage('system', '🔄 正在发送验证码到: ' + email);
            
            try {
                const response = await fetch('/auth/send-login-verification-code', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        identifier: email
                    })
                });
                
                const result = await response.json();
                
                if (response.ok) {
                    addMessage('system', '✅ 验证码已发送到邮箱');
                    document.getElementById('codeLoginBtn').disabled = false;
                    
                    // 如果是测试模式，显示验证码
                    if (result.data && result.data.verification_code) {
                        addMessage('system', '🔧 测试模式验证码: ' + result.data.verification_code);
                        document.getElementById('verificationCode').value = result.data.verification_code;
                    } else {
                        // 尝试获取调试验证码
                        addMessage('system', '🔍 尝试获取验证码...');
                        await getDebugVerificationCode(email);
                    }
                    
                    // 开始倒计时
                    startCountdown(sendCodeBtn, 60);
                } else {
                    addMessage('error', '❌ 发送失败: ' + (result.message || '未知错误'));
                    sendCodeBtn.disabled = false;
                    sendCodeBtn.textContent = '发送验证码';
                }
            } catch (error) {
                addMessage('error', '❌ 请求失败: ' + error.message);
                sendCodeBtn.disabled = false;
                sendCodeBtn.textContent = '发送验证码';
            }
        }
        
        // 获取调试验证码
        async function getDebugVerificationCode(email) {
            try {
                const response = await fetch('/auth/debug-verification-code', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        email: email
                    })
                });
                
                const result = await response.json();
                
                if (response.ok && result.data) {
                    addMessage('system', '🔧 调试信息: ' + JSON.stringify(result.data));
                    
                    // 检查验证码是否存在且有效
                    if (result.data.exists && result.data.parsedData && result.data.parsedData.code) {
                        const code = result.data.parsedData.code;
                        addMessage('system', '🔧 调试模式验证码: ' + code);
                        document.getElementById('verificationCode').value = code;
                    } else if (result.data.rawData) {
                        // 尝试解析rawData
                        try {
                            const rawData = JSON.parse(result.data.rawData);
                            if (rawData.code) {
                                addMessage('system', '🔧 从rawData获取验证码: ' + rawData.code);
                                document.getElementById('verificationCode').value = rawData.code;
                            }
                        } catch (e) {
                            addMessage('system', '💡 无法解析rawData: ' + result.data.rawData);
                        }
                    } else {
                        addMessage('system', '💡 验证码不存在或已过期，请重新发送');
                    }
                } else {
                    addMessage('system', '💡 无法获取验证码，请手动输入或使用真实邮箱');
                }
            } catch (error) {
                addMessage('system', '💡 调试接口不可用，请手动输入验证码');
            }
        }
        
        // 验证码登录
        async function loginWithCode() {
            const email = document.getElementById('codeEmail').value.trim();
            const code = document.getElementById('verificationCode').value.trim();
            const codeLoginBtn = document.getElementById('codeLoginBtn');
            
            if (!email || !code) {
                addMessage('error', '❌ 请输入邮箱和验证码');
                return;
            }
            
            codeLoginBtn.disabled = true;
            codeLoginBtn.textContent = '登录中...';
            addMessage('system', '🔄 正在验证码登录...');
            
            try {
                const response = await fetch('/auth/verification-code-login', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        identifier: email,
                        verification_code: code
                    })
                });
                
                const result = await response.json();
                
                if (response.ok && result.data && result.data.access_token) {
                    document.getElementById('jwtToken').value = result.data.access_token;
                    addMessage('system', '✅ 验证码登录成功');
                    addMessage('system', '💡 现在可以点击"连接"按钮建立WebSocket连接');
                } else {
                    addMessage('error', '❌ 验证码登录失败: ' + (result.message || '未知错误'));
                    
                    // 如果是用户不存在，提示可以注册
                    if (result.message && result.message.includes('用户不存在')) {
                        addMessage('system', '💡 用户不存在，可以使用下方的"验证码注册"功能');
                    }
                }
            } catch (error) {
                addMessage('error', '❌ 请求失败: ' + error.message);
            } finally {
                codeLoginBtn.disabled = false;
                codeLoginBtn.textContent = '验证码登录';
            }
        }
        
        // 验证码注册
        async function registerWithCode() {
            const email = document.getElementById('codeEmail').value.trim();
            const code = document.getElementById('verificationCode').value.trim();
            const password = document.getElementById('codePassword').value.trim();
            let username = document.getElementById('codeUsername').value.trim();
            let nickname = document.getElementById('codeNickname').value.trim();
            
            if (!email || !code || !password) {
                addMessage('error', '❌ 请输入邮箱、验证码和密码');
                return;
            }
            
            // 自动生成用户名和昵称
            if (!username) {
                username = 'user_' + Date.now();
                document.getElementById('codeUsername').value = username;
            }
            
            if (!nickname) {
                nickname = username;
                document.getElementById('codeNickname').value = nickname;
            }
            
            addMessage('system', '🔄 正在验证码注册...');
            
            try {
                // 直接使用验证码进行注册
                const response = await fetch('/auth/register', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        email: email,
                        password: password,
                        username: username,
                        nickname: nickname,
                        email_verification_code: code
                    })
                });
                
                const result = await response.json();
                
                if (response.ok) {
                    addMessage('system', '✅ 验证码注册成功！');
                    
                    // 自动登录
                    await new Promise(resolve => setTimeout(resolve, 1000));
                    
                    // 切换到密码模式并填入信息
                    document.getElementById('testEmail').value = email;
                    document.getElementById('testPassword').value = password;
                    
                    const loginSuccess = await attemptLogin();
                    
                    if (loginSuccess) {
                        addMessage('system', '🎉 验证码注册并登录成功！');
                    } else {
                        addMessage('system', '✅ 注册成功，请手动登录');
                    }
                } else {
                    // 检查是否是用户名冲突
                    if (result.message && result.message.includes('用户名')) {
                        addMessage('system', '⚠️ 用户名冲突，请修改用户名后重试');
                        
                        // 自动生成新用户名
                        const newUsername = 'user_' + Date.now() + '_' + Math.random().toString(36).substr(2, 5);
                        document.getElementById('codeUsername').value = newUsername;
                        addMessage('system', '💡 已自动生成新用户名: ' + newUsername);
                    } else {
                        addMessage('error', '❌ 验证码注册失败: ' + (result.message || '未知错误'));
                    }
                }
                
            } catch (error) {
                addMessage('error', '❌ 验证码注册请求失败: ' + error.message);
            }
        }
        
        // 发送注册验证码
        async function sendEmailVerificationForRegister() {
            const email = document.getElementById('codeEmail').value.trim();
            
            if (!email) {
                addMessage('error', '❌ 请输入邮箱地址');
                return;
            }
            
            addMessage('system', '🔄 正在发送注册验证码到: ' + email);
            
            try {
                const response = await fetch('/auth/send-email-verification', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        email: email
                    })
                });
                
                const result = await response.json();
                
                if (response.ok) {
                    addMessage('system', '✅ 注册验证码已发送');
                    
                    // 如果是测试模式，显示验证码
                    if (result.data && result.data.verification_code) {
                        addMessage('system', '🔧 测试模式验证码: ' + result.data.verification_code);
                        document.getElementById('verificationCode').value = result.data.verification_code;
                    } else {
                        // 尝试获取调试验证码
                        addMessage('system', '🔍 尝试获取验证码...');
                        await getDebugVerificationCode(email);
                    }
                } else {
                    addMessage('error', '❌ 发送失败: ' + (result.message || '未知错误'));
                }
            } catch (error) {
                addMessage('error', '❌ 请求失败: ' + error.message);
            }
        }
        
        // 倒计时函数
        function startCountdown(button, seconds) {
            let remaining = seconds;
            const originalText = button.textContent;
            
            const timer = setInterval(() => {
                button.textContent = '重新发送 (' + remaining + 's)';
                remaining--;
                
                if (remaining < 0) {
                    clearInterval(timer);
                    button.disabled = false;
                    button.textContent = originalText;
                }
            }, 1000);
        }
        function generateRandomTestAccount() {
            const timestamp = Date.now();
            const randomId = Math.random().toString(36).substr(2, 6);
            const tabId = window.tabId ? window.tabId.split('_').pop().substr(0, 4) : Math.random().toString(36).substr(2, 4);
            
            const emailDomains = ['test.com', 'example.com', 'demo.org'];
            const randomDomain = emailDomains[Math.floor(Math.random() * emailDomains.length)];
            const emailPrefix = 'test' + timestamp.toString().substr(-6) + tabId + randomId;
            const email = emailPrefix + '@' + randomDomain;
            
            const username = 'user' + timestamp.toString().substr(-6) + tabId + randomId;
            
            const nicknames = ['测试用户', '演示账号', '样例用户', 'TestUser', 'DemoAccount'];
            const randomNickname = nicknames[Math.floor(Math.random() * nicknames.length)] + tabId;
            
            const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            let password = 'Test123';
            for (let i = 0; i < 4; i++) {
                password += chars.charAt(Math.floor(Math.random() * chars.length));
            }
            
            const account = {
                email: email,
                password: password,
                username: username,
                nickname: randomNickname
            };
            
            generatedAccounts.add(account.email);
            generatedAccounts.add(account.username);
            
            return account;
        }
        
        // 使用默认测试账号
        function useDefaultAccount() {
            document.getElementById('testEmail').value = DEFAULT_TEST_ACCOUNT.email;
            document.getElementById('testPassword').value = DEFAULT_TEST_ACCOUNT.password;
            document.getElementById('testUsername').value = DEFAULT_TEST_ACCOUNT.username;
            document.getElementById('testNickname').value = DEFAULT_TEST_ACCOUNT.username;
            addMessage('system', '✅ 已设置默认测试账号: ' + DEFAULT_TEST_ACCOUNT.email);
        }
        
        // 应用随机测试账号到表单
        function applyRandomTestAccount() {
            const account = generateRandomTestAccount();
            
            document.getElementById('testEmail').value = account.email;
            document.getElementById('testPassword').value = account.password;
            document.getElementById('testUsername').value = account.username;
            document.getElementById('testNickname').value = account.nickname;
            
            document.getElementById('jwtToken').value = '';
            
            addMessage('system', '🎲 已生成随机测试账号:');
            addMessage('system', '📧 邮箱: ' + account.email);
            addMessage('system', '👤 用户名: ' + account.username);
            addMessage('system', '🏷️ 昵称: ' + account.nickname);
            addMessage('system', '🔑 密码: ' + account.password);
            
            return account;
        }
        
        // 智能注册并登录 - 处理频率限制（改进真实邮箱支持）
        async function smartRegisterAndLogin(recursionDepth = 0) {
            // 防止无限递归
            if (recursionDepth > 3) {
                addMessage('error', '❌ 重试次数过多，请手动操作');
                addMessage('system', '💡 建议：刷新页面或手动生成新账号');
                return false;
            }
            
            const email = document.getElementById('testEmail').value.trim();
            const password = document.getElementById('testPassword').value.trim();
            let username = document.getElementById('testUsername').value.trim();
            let nickname = document.getElementById('testNickname').value.trim();
            
            if (!email || !password) {
                addMessage('error', '❌ 请输入邮箱和密码');
                return false;
            }
            
            // 如果没有填写用户名，自动生成
            if (!username) {
                username = 'user' + Date.now() + '_' + Math.random().toString(36).substr(2, 6);
                document.getElementById('testUsername').value = username;
            }
            
            // 如果没有填写昵称，使用用户名
            if (!nickname) {
                nickname = username;
                document.getElementById('testNickname').value = nickname;
            }
            
            if (recursionDepth === 0) {
                addMessage('system', '🔄 开始智能注册登录流程...');
                addMessage('system', '📋 使用账号信息:');
                addMessage('system', '  📧 邮箱: ' + email);
                addMessage('system', '  👤 用户名: ' + username);
                addMessage('system', '  🏷️ 昵称: ' + nickname);
            } else {
                addMessage('system', '🔄 重试注册登录 (第' + (recursionDepth + 1) + '次)...');
            }
            
            // 1. 先尝试登录
            addMessage('system', '1️⃣ 尝试登录现有账号...');
            const loginSuccess = await attemptLogin();
            
            if (loginSuccess) {
                addMessage('system', '✅ 账号已存在，登录成功！');
                return true;
            }
            
            // 2. 登录失败，尝试注册
            addMessage('system', '2️⃣ 账号不存在，开始注册新账号...');
            
            const registerResult = await attemptRegister(email, password, username, nickname);
            
            // 处理不同的注册结果
            if (registerResult === true) {
                // 注册成功，尝试登录
                addMessage('system', '3️⃣ 注册成功，正在登录...');
                await new Promise(resolve => setTimeout(resolve, 1000)); // 等待1秒
                
                const finalLoginSuccess = await attemptLogin();
                
                if (finalLoginSuccess) {
                    addMessage('system', '🎉 智能注册登录完成！');
                    return true;
                } else {
                    addMessage('error', '❌ 注册成功但登录失败，请手动登录');
                    return false;
                }
            } else if (registerResult === 'RATE_LIMITED') {
                // 遇到频率限制，直接返回，不要重试
                addMessage('system', '⏰ 遇到频率限制，停止自动重试');
                addMessage('system', '💡 建议操作:');
                addMessage('system', '  1️⃣ 等待1分钟后重新尝试');
                addMessage('system', '  2️⃣ 切换到验证码模式手动操作');
                addMessage('system', '  3️⃣ 使用现有的测试账号');
                return 'RATE_LIMITED'; // 向上传递频率限制状态
            } else if (registerResult === 'REAL_EMAIL_SENT') {
                // 真实邮箱验证码已发送，需要手动处理
                addMessage('system', '📬 真实邮箱验证码已发送！');
                addMessage('system', '💡 由于使用了真实邮箱，需要手动完成注册：');
                addMessage('system', '  1️⃣ 切换到"验证码登录"模式');
                addMessage('system', '  2️⃣ 查收邮箱中的验证码');
                addMessage('system', '  3️⃣ 使用"验证码注册"功能完成注册');
                addMessage('system', '  4️⃣ 注册成功后可继续使用一键测试');
                return 'REAL_EMAIL_SENT'; // 向上传递真实邮箱状态
            } else {
                // 其他注册失败，可能是账号冲突，尝试重新生成
                if (recursionDepth < 2) { // 减少重试次数，避免触发频率限制
                    addMessage('system', '⚠️ 注册失败，可能是账号冲突，重新生成账号...');
                    applyRandomTestAccount();
                    // 添加更长的延迟避免触发频率限制
                    await new Promise(resolve => setTimeout(resolve, 2000));
                    return await smartRegisterAndLogin(recursionDepth + 1);
                } else {
                    addMessage('error', '❌ 注册失败，请检查信息或手动操作');
                    addMessage('system', '💡 建议操作:');
                    addMessage('system', '  1️⃣ 点击"重新生成账号"按钮');
                    addMessage('system', '  2️⃣ 或切换到验证码模式手动注册');
                    addMessage('system', '  3️⃣ 或刷新页面重新开始');
                    return false;
                }
            }
        }
        
        // 尝试注册账号（添加真实邮箱支持）
        async function attemptRegister(email, password, username, nickname, retryCount = 0) {
            // 限制重试次数
            if (retryCount > 2) {
                addMessage('error', '❌ 注册重试次数过多，请手动操作');
                return false;
            }
            
            try {
                // 检测邮箱类型
                const isRealEmailAddress = !isTestEmail(email);
                addMessage('system', '📧 邮箱类型检测: ' + (isRealEmailAddress ? '真实邮箱' : '测试邮箱'));
                
                // 1. 发送邮箱验证码
                addMessage('system', '📧 发送邮箱验证码...');
                const codeResponse = await fetch('/auth/send-email-verification', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        email: email
                    })
                });
                
                const codeResult = await codeResponse.json();
                let verificationCode = '';
                
                addMessage('system', '📧 发送验证码响应: ' + JSON.stringify(codeResult));
                
                if (codeResponse.ok) {
                    if (isRealEmailAddress) {
                        // 真实邮箱：提示用户查收邮件
                        addMessage('system', '📬 真实邮箱验证码已发送，请查收邮件');
                        addMessage('system', '💡 请手动输入收到的验证码，或切换到验证码模式操作');
                        
                        // 对于真实邮箱，我们不能自动获取验证码，需要用户手动输入
                        // 这里返回特殊标识，让调用方知道需要手动处理
                        return 'REAL_EMAIL_SENT';
                    } else {
                        // 测试邮箱：尝试自动获取验证码
                        if (codeResult.data && codeResult.data.verification_code) {
                            verificationCode = codeResult.data.verification_code;
                            addMessage('system', '🔧 测试模式验证码: ' + verificationCode);
                        } else if (codeResult.data && codeResult.data.is_test_mode === false) {
                            // 如果不是测试模式，尝试获取调试验证码
                            addMessage('system', '🔍 尝试获取调试验证码...');
                            const debugCode = await getDebugEmailVerificationCode(email);
                            if (debugCode) {
                                verificationCode = debugCode;
                            } else {
                                addMessage('error', '❌ 无法获取验证码，请使用手动验证码注册功能');
                                return false;
                            }
                        } else {
                            // 如果都没有，提示用户手动操作
                            addMessage('error', '❌ 无法自动获取验证码，请切换到验证码模式手动操作');
                            return false;
                        }
                    }
                } else {
                    // 检查是否是频率限制错误
                    if (codeResult.error_code === 'TOO_MANY_REQUESTS' || codeResult.message.includes('频繁')) {
                        addMessage('error', '❌ 发送验证码失败: ' + (codeResult.message || '未知错误'));
                        addMessage('system', '⏰ 检测到频率限制，建议等待或使用其他方式');
                        addMessage('system', '💡 解决方案:');
                        addMessage('system', '  1️⃣ 等待1分钟后重试');
                        addMessage('system', '  2️⃣ 切换到验证码模式手动操作');
                        addMessage('system', '  3️⃣ 使用现有账号登录');
                        return 'RATE_LIMITED'; // 返回特殊标识
                    } else {
                        addMessage('error', '❌ 发送验证码失败: ' + (codeResult.message || '未知错误'));
                        return false;
                    }
                }
                
                // 2. 使用验证码进行注册（只有测试邮箱才会执行到这里）
                if (verificationCode) {
                    addMessage('system', '📝 开始注册，使用验证码: ' + verificationCode);
                    const response = await fetch('/auth/register', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({
                            email: email,
                            password: password,
                            username: username,
                            nickname: nickname,
                            email_verification_code: verificationCode
                        })
                    });
                    
                    const result = await response.json();
                    addMessage('system', '📝 注册响应: ' + JSON.stringify(result));
                    
                    if (response.ok) {
                        addMessage('system', '✅ 账号注册成功');
                        return true;
                    } else {
                        // 显示详细的错误信息
                        addMessage('error', '❌ 注册失败: ' + (result.message || '未知错误'));
                        addMessage('system', '📋 注册请求详情:');
                        addMessage('system', '  📧 邮箱: ' + email);
                        addMessage('system', '  👤 用户名: ' + username);
                        addMessage('system', '  🏷️ 昵称: ' + nickname);
                        addMessage('system', '  🔄 重试次数: ' + retryCount);
                        
                        // 检查是否是用户名冲突
                        if (result.message && (result.message.includes('用户名') || result.message.includes('username'))) {
                            addMessage('system', '⚠️ 用户名冲突，尝试生成新用户名...');
                            
                            // 生成新的用户名（增加更多随机性）
                            const newUsername = 'user' + Date.now() + '_' + Math.random().toString(36).substr(2, 8) + '_retry' + retryCount;
                            document.getElementById('testUsername').value = newUsername;
                            
                            // 添加延迟避免过快重试
                            await new Promise(resolve => setTimeout(resolve, 1000));
                            
                            // 递归重试（带重试计数）
                            return await attemptRegister(email, password, newUsername, nickname, retryCount + 1);
                        } 
                        // 检查是否是邮箱冲突
                        else if (result.message && (result.message.includes('邮箱') || result.message.includes('email'))) {
                            addMessage('system', '⚠️ 邮箱冲突，这不应该发生，因为我们生成了唯一邮箱');
                            addMessage('system', '💡 建议：刷新页面重新开始，或手动修改邮箱');
                            return false;
                        } else {
                            addMessage('error', '❌ 注册失败: ' + (result.message || '未知错误'));
                            
                            // 如果是验证码错误，提示用户手动操作
                            if (result.message && result.message.includes('验证码')) {
                                addMessage('system', '💡 建议：切换到验证码登录模式，手动获取和输入验证码');
                            }
                            return false;
                        }
                    }
                } else {
                    // 真实邮箱的情况，返回特殊标识
                    return 'REAL_EMAIL_SENT';
                }
            } catch (error) {
                addMessage('error', '❌ 注册请求失败: ' + error.message);
                return false;
            }
        }
        
        // 获取邮箱验证码的调试信息
        async function getDebugEmailVerificationCode(email) {
            try {
                // 等待一下，确保验证码已经生成
                await new Promise(resolve => setTimeout(resolve, 1000));
                
                const response = await fetch('/auth/debug-verification-code', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        email: email
                    })
                });
                
                const result = await response.json();
                
                if (response.ok && result.data) {
                    addMessage('system', '🔧 调试信息: ' + JSON.stringify(result.data));
                    
                    // 检查验证码是否存在且有效
                    if (result.data.exists && result.data.parsedData && result.data.parsedData.code) {
                        const code = result.data.parsedData.code;
                        addMessage('system', '🔧 调试模式验证码: ' + code);
                        return code;
                    } else if (result.data.rawData) {
                        // 尝试解析rawData
                        try {
                            const rawData = JSON.parse(result.data.rawData);
                            if (rawData.code) {
                                addMessage('system', '🔧 从rawData获取验证码: ' + rawData.code);
                                return rawData.code;
                            }
                        } catch (e) {
                            addMessage('system', '💡 无法解析rawData: ' + result.data.rawData);
                        }
                    }
                    
                    addMessage('system', '💡 验证码不存在或已过期');
                    return null;
                } else {
                    addMessage('system', '💡 调试接口响应: ' + JSON.stringify(result));
                    return null;
                }
            } catch (error) {
                addMessage('system', '💡 调试接口异常: ' + error.message);
                return null;
            }
        }
        
        // 尝试登录
        async function attemptLogin() {
            const email = document.getElementById('testEmail').value.trim();
            const password = document.getElementById('testPassword').value.trim();
            
            try {
                const response = await fetch('/auth/login', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        identifier: email,
                        password: password
                    })
                });
                
                const result = await response.json();
                
                if (response.ok && result.data && result.data.access_token) {
                    document.getElementById('jwtToken').value = result.data.access_token;
                    addMessage('system', '✅ 登录成功，Token已获取');
                    return true;
                } else {
                    addMessage('system', '⚠️ 登录失败: ' + (result.message || '未知错误'));
                    return false;
                }
            } catch (error) {
                addMessage('system', '⚠️ 登录请求失败: ' + error.message);
                return false;
            }
        }
        
        // 自动获取JWT Token的函数
        async function getTestToken() {
            const email = document.getElementById('testEmail').value.trim();
            const password = document.getElementById('testPassword').value.trim();
            const getTokenBtn = document.getElementById('getTokenBtn');
            
            if (!email || !password) {
                addMessage('error', '❌ 请输入邮箱和密码');
                return;
            }
            
            getTokenBtn.disabled = true;
            getTokenBtn.textContent = '获取中...';
            
            const success = await attemptLogin();
            
            getTokenBtn.disabled = false;
            getTokenBtn.textContent = '获取测试Token';
            
            if (!success) {
                addMessage('system', '💡 提示: 请确保测试账号存在，或点击"智能注册登录"');
            }
        }
        
        // 快速测试函数 - 一键连接并登录（修复频率限制检测，支持真实邮箱）
        async function quickTest() {
            addMessage('system', '🚀 开始一键测试流程...');
            
            // 1. 智能获取Token
            const tokenResult = await smartGetToken();
            
            // 检查Token获取结果
            if (tokenResult === 'RATE_LIMITED') {
                // 频率限制，停止执行
                addMessage('system', '⏰ 检测到频率限制，建议等待后重试');
                addMessage('system', '💡 解决方案:');
                addMessage('system', '  1️⃣ 等待1分钟后重新点击"一键测试"');
                addMessage('system', '  2️⃣ 或者使用现有账号手动登录');
                addMessage('system', '  3️⃣ 如需立即测试，可切换到验证码模式手动操作');
                return; // 直接返回，不继续执行
            } else if (tokenResult === 'REAL_EMAIL_SENT') {
                // 真实邮箱验证码已发送，需要手动处理
                addMessage('system', '📬 检测到真实邮箱，验证码已发送');
                addMessage('system', '💡 请手动完成注册后再使用一键测试：');
                addMessage('system', '  1️⃣ 切换到"验证码登录"模式');
                addMessage('system', '  2️⃣ 查收邮箱中的验证码');
                addMessage('system', '  3️⃣ 使用"验证码注册"功能完成注册');
                addMessage('system', '  4️⃣ 注册成功后重新点击"一键测试"');
                
                // 自动切换到验证码模式
                switchAuthMode('code');
                
                // 复制邮箱到验证码模式
                const email = document.getElementById('testEmail').value;
                if (email) {
                    document.getElementById('codeEmail').value = email;
                }
                return; // 直接返回，不继续执行
            } else if (!tokenResult) {
                // 其他类型的失败才切换到验证码模式
                addMessage('system', '💡 自动获取Token失败，尝试手动验证码方式...');
                addMessage('system', '🔄 切换到验证码模式，请手动操作：');
                addMessage('system', '1️⃣ 切换到"验证码登录"标签');
                addMessage('system', '2️⃣ 点击"发送验证码"或"获取验证码"');
                addMessage('system', '3️⃣ 输入验证码后点击"验证码登录"或"验证码注册"');
                
                // 自动切换到验证码模式
                switchAuthMode('code');
                
                // 复制邮箱到验证码模式
                const email = document.getElementById('testEmail').value;
                if (email) {
                    document.getElementById('codeEmail').value = email;
                }
                return; // 直接返回，不继续执行
            }
            
            // 2. Token获取成功，建立连接
            if (!ws || ws.readyState !== WebSocket.OPEN) {
                addMessage('system', '🔌 建立WebSocket连接...');
                connect();
                
                // 等待连接建立
                await new Promise(resolve => {
                    const checkConnection = () => {
                        if (ws && ws.readyState === WebSocket.OPEN) {
                            resolve();
                        } else if (ws && ws.readyState === WebSocket.CLOSED) {
                            addMessage('error', '❌ 连接失败');
                            resolve();
                        } else {
                            setTimeout(checkConnection, 100);
                        }
                    };
                    checkConnection();
                });
            }
            
            // 3. 自动登录
            if (ws && ws.readyState === WebSocket.OPEN) {
                addMessage('system', '🔐 自动登录...');
                setTimeout(() => {
                    login();
                }, 1000);
            }
        }
        
        // 智能获取Token - 自动检测和处理各种情况（改进频率限制处理）
        async function smartGetToken() {
            addMessage('system', '🔄 开始智能获取Token...');
            
            // 1. 检查是否已有Token
            const existingToken = document.getElementById('jwtToken').value.trim();
            if (existingToken) {
                addMessage('system', '✅ 检测到现有Token，跳过获取');
                return true;
            }
            
            // 2. 检查是否有输入的账号信息
            const email = document.getElementById('testEmail').value.trim();
            const password = document.getElementById('testPassword').value.trim();
            
            // 3. 如果没有账号信息，生成随机测试账号
            if (!email || !password || email === 'test@example.com') {
                addMessage('system', '🎲 未检测到账号信息，生成随机测试账号...');
                applyRandomTestAccount();
                await new Promise(resolve => setTimeout(resolve, 500)); // 等待表单更新
            }
            
            // 4. 根据当前认证模式获取Token
            if (currentAuthMode === 'password') {
                const result = await smartPasswordLogin();
                
                // 如果是频率限制，向上传递
                if (result === 'RATE_LIMITED') {
                    return 'RATE_LIMITED';
                }
                
                return result;
            } else {
                addMessage('system', '💡 验证码模式需要手动发送验证码并登录');
                return false;
            }
        }
        
        // 智能密码登录（改进返回值处理）
        async function smartPasswordLogin() {
            const email = document.getElementById('testEmail').value.trim();
            const password = document.getElementById('testPassword').value.trim();
            
            // 1. 确保有账号信息（此时应该已经通过smartGetToken生成了）
            if (!email || !password) {
                addMessage('error', '❌ 缺少账号信息');
                return false;
            }
            
            // 2. 尝试登录
            const loginSuccess = await attemptLogin();
            if (loginSuccess) {
                return true;
            }
            
            // 3. 登录失败，尝试智能注册登录
            addMessage('system', '🔧 登录失败，尝试智能注册...');
            const registerResult = await smartRegisterAndLogin();
            
            // 传递频率限制状态
            if (registerResult === 'RATE_LIMITED') {
                return 'RATE_LIMITED';
            }
            
            return registerResult;
        }
        
        // 切换消息类型时显示对应字段
        document.getElementById('messageType').addEventListener('change', function() {
            const chatFields = document.getElementById('chatFields');
            const positionFields = document.getElementById('positionFields');
            
            if (this.value === 'chat') {
                chatFields.style.display = 'block';
                positionFields.style.display = 'none';
            } else {
                chatFields.style.display = 'none';
                positionFields.style.display = 'block';
            }
        });
        
        function updateStatus(status, message) {
            const statusEl = document.getElementById('connectionStatus');
            statusEl.className = 'status ' + status;
            statusEl.textContent = message;
        }
        
        function addMessage(type, content, timestamp = new Date()) {
            const log = document.getElementById('messageLog');
            if (!log) {
                console.error('messageLog element not found');
                return;
            }
            
            const messageEl = document.createElement('div');
            messageEl.className = 'message-item message-' + type;
            
            const timeStr = timestamp.toLocaleTimeString();
            
            // 处理长内容，但要小心避免破坏HTML
            let processedContent = content;
            if (typeof content === 'string') {
                try {
                    // 先尝试格式化JSON
                    if (content.includes('{') || content.includes('[')) {
                        const jsonMatch = content.match(/(\{.*\}|\[.*\])/s);
                        if (jsonMatch) {
                            const jsonPart = JSON.parse(jsonMatch[1]);
                            const formattedJson = JSON.stringify(jsonPart, null, 2);
                            processedContent = content.replace(jsonMatch[1], formattedJson);
                        }
                    }
                } catch (e) {
                    // 如果JSON解析失败，保持原样
                    console.log('JSON parse failed, keeping original content');
                }
            }
            
            // 安全地设置内容
            try {
                messageEl.innerHTML = '<strong>[' + timeStr + ']</strong> ' + processedContent;
            } catch (e) {
                // 如果innerHTML设置失败，使用textContent
                messageEl.textContent = '[' + timeStr + '] ' + content;
            }
            
            log.appendChild(messageEl);
            log.scrollTop = log.scrollHeight;
        }
        
        function toggleConnection() {
            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.close();
            } else {
                connect();
            }
        }
        
        function connect() {
            const url = document.getElementById('wsUrl').value;
            updateStatus('connecting', '连接中...');
            
            try {
                ws = new WebSocket(url);
                
                ws.onopen = function() {
                    updateStatus('connected', '已连接');
                    document.getElementById('connectBtn').textContent = '断开';
                    document.getElementById('loginBtn').disabled = false;
                    addMessage('system', '✅ WebSocket连接成功');
                };
                
                ws.onmessage = function(event) {
                    try {
                        const data = JSON.parse(event.data);
                        addMessage('received', '📥 ' + JSON.stringify(data, null, 2));
                        
                        if (data.t === 'login_success') {
                            isLoggedIn = true;
                            document.getElementById('sendBtn').disabled = false;
                            addMessage('system', '✅ 登录成功！用户: ' + data.username);
                        } else if (data.t === 'login_error') {
                            addMessage('error', '❌ 登录失败: ' + data.message);
                        } else if (data.t === 'chat_render') {
                            addMessage('system', '💬 收到消息: ' + data.from + ' 说: ' + data.txt);
                        }
                    } catch (e) {
                        addMessage('received', '📥 ' + event.data);
                    }
                };
                
                ws.onclose = function() {
                    updateStatus('disconnected', '未连接');
                    document.getElementById('connectBtn').textContent = '连接';
                    document.getElementById('loginBtn').disabled = true;
                    document.getElementById('sendBtn').disabled = true;
                    isLoggedIn = false;
                    addMessage('system', '🔌 WebSocket连接已关闭');
                };
                
                ws.onerror = function(error) {
                    addMessage('error', '❌ 连接错误: ' + error);
                };
                
            } catch (error) {
                updateStatus('disconnected', '连接失败');
                addMessage('error', '❌ 连接失败: ' + error.message);
            }
        }
        
        function login() {
            if (!ws || ws.readyState !== WebSocket.OPEN) {
                addMessage('error', '❌ 请先建立WebSocket连接');
                return;
            }
            
            const token = document.getElementById('jwtToken').value.trim();
            if (!token) {
                addMessage('error', '❌ 请输入JWT Token');
                return;
            }
            
            const message = {
                type: 'login',
                token: token
            };
            
            ws.send(JSON.stringify(message));
            addMessage('sent', '📤 ' + JSON.stringify(message, null, 2));
        }
        
        function sendMessage() {
            if (!ws || ws.readyState !== WebSocket.OPEN) {
                addMessage('error', '❌ 请先建立WebSocket连接');
                return;
            }
            
            if (!isLoggedIn) {
                addMessage('error', '❌ 请先登录');
                return;
            }
            
            const messageType = document.getElementById('messageType').value;
            let message;
            
            if (messageType === 'chat') {
                const content = document.getElementById('chatContent').value.trim();
                if (!content) {
                    addMessage('error', '❌ 请输入消息内容');
                    return;
                }
                
                message = {
                    t: 'chat',
                    content: content,
                    scope: document.getElementById('chatScope').value
                };
            } else {
                message = {
                    t: 'position',
                    x: parseInt(document.getElementById('posX').value),
                    y: parseInt(document.getElementById('posY').value),
                    mapId: document.getElementById('mapId').value
                };
            }
            
            ws.send(JSON.stringify(message));
            addMessage('sent', '📤 ' + JSON.stringify(message, null, 2));
            
            if (messageType === 'chat') {
                document.getElementById('chatContent').value = '';
            }
        }
        
        function sendQuickMessage(content) {
            if (!isLoggedIn) {
                addMessage('error', '❌ 请先登录');
                return;
            }
            
            document.getElementById('messageType').value = 'chat';
            document.getElementById('chatContent').value = content;
            document.getElementById('messageType').dispatchEvent(new Event('change'));
            sendMessage();
        }
        
        function sendQuickPosition() {
            if (!isLoggedIn) {
                addMessage('error', '❌ 请先登录');
                return;
            }
            
            document.getElementById('messageType').value = 'position';
            document.getElementById('messageType').dispatchEvent(new Event('change'));
            sendMessage();
        }
        
        function clearLog() {
            document.getElementById('messageLog').innerHTML = '';
        }
        
        function showDebugInfo() {
            addMessage('system', '🔍 调试信息:');
            addMessage('system', '  🆔 标签页ID: ' + (window.tabId || '未设置'));
            addMessage('system', '  📊 已生成账号数: ' + generatedAccounts.size);
            addMessage('system', '  🔌 WebSocket状态: ' + (ws ? ws.readyState : '未连接'));
            addMessage('system', '  🔐 登录状态: ' + (isLoggedIn ? '已登录' : '未登录'));
            addMessage('system', '  🎛️ 认证模式: ' + currentAuthMode);
            addMessage('system', '  📡 API调用统计: 请求' + apiCallCount + '次, 成功' + apiSuccessCount + '次, 失败' + apiErrorCount + '次');
            addMessage('system', '  🔍 API详情模式: ' + (showApiDetails ? '开启' : '关闭'));
        }
        
        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function() {
            generatedAccounts.clear();
            
            const timestamp = Date.now();
            const microTime = Math.floor(performance.now() * 1000);
            const randomPart = Math.random().toString(36).substr(2, 8);
            const tabId = 'tab_' + timestamp + '_' + microTime + '_' + randomPart;
            window.tabId = tabId;
            
            addMessage('system', '🎮 WebSocket测试工具已就绪 (标签页: ' + tabId + ')');
            addMessage('system', '💡 快速开始: 点击"🚀 一键测试"按钮自动完成所有步骤');
            addMessage('system', '📋 手动步骤: 1️⃣获取Token → 2️⃣连接 → 3️⃣登录 → 4️⃣发送消息');
            addMessage('system', '🔧 支持密码登录和验证码登录两种方式');
            addMessage('system', '🎲 一键测试会自动生成随机测试账号，方便多用户测试');
            addMessage('system', '📡 新功能: API调用监控已启用，可实时查看所有HTTP请求');
            addMessage('system', '🔍 API日志支持显示请求体、响应体和详细统计信息');
            addMessage('system', '🔔 新增: 通知系统测试功能，可切换到通知模式进行测试');
            
            // 请求通知权限
            if (Notification.permission === 'default') {
                Notification.requestPermission().then(permission => {
                    if (permission === 'granted') {
                        addMessage('system', '✅ 浏览器通知权限已获取');
                    }
                });
            }
            
            // 检查URL参数，看是否从API文档跳转过来
            const urlParams = new URLSearchParams(window.location.search);
            if (urlParams.get('from') === 'api-docs') {
                addMessage('system', '👋 欢迎从API文档跳转过来！建议使用"一键测试"快速体验');
            }
            
            // 检查是否有存储的Token（使用标签页特定的key）
            const storedToken = localStorage.getItem('websocket_test_token_' + tabId);
            if (storedToken) {
                document.getElementById('jwtToken').value = storedToken;
                addMessage('system', '✅ 检测到本标签页存储的Token');
            } else {
                // 检查是否有通用的Token（向后兼容）
                const generalToken = localStorage.getItem('websocket_test_token');
                if (generalToken) {
                    addMessage('system', '💡 检测到通用Token，建议重新生成专用Token');
                }
            }
        });
        
        // 保存Token到本地存储（使用标签页特定的key）
        function saveTokenToStorage() {
            const token = document.getElementById('jwtToken').value.trim();
            if (token && window.tabId) {
                localStorage.setItem('websocket_test_token_' + window.tabId, token);
                addMessage('system', '💾 Token已保存到本标签页存储');
            }
        }
        
        // 清空当前标签页的Token
        function clearCurrentTabToken() {
            if (window.tabId) {
                localStorage.removeItem('websocket_test_token_' + window.tabId);
                document.getElementById('jwtToken').value = '';
                addMessage('system', '🗑️ 已清空当前标签页的Token');
            }
        }
        
        // 清空所有标签页的Token
        function clearAllTabTokens() {
            // 清空所有以websocket_test_token开头的localStorage项
            const keysToRemove = [];
            for (let i = 0; i < localStorage.length; i++) {
                const key = localStorage.key(i);
                if (key && key.startsWith('websocket_test_token')) {
                    keysToRemove.push(key);
                }
            }
            
            keysToRemove.forEach(key => localStorage.removeItem(key));
            document.getElementById('jwtToken').value = '';
            
            addMessage('system', '🗑️ 已清空所有标签页的Token (' + keysToRemove.length + '个)');
        }
        
        // 清空本地生成的账号记录
        function clearGeneratedAccounts() {
            const oldSize = generatedAccounts.size;
            generatedAccounts.clear();
            addMessage('system', '🗑️ 已清空本地账号记录 (' + oldSize + '个)');
        }
        
        // 监听Token输入框变化
        document.addEventListener('DOMContentLoaded', function() {
            const tokenInput = document.getElementById('jwtToken');
            if (tokenInput) {
                tokenInput.addEventListener('input', saveTokenToStorage);
            }
        });
        
        // 页面卸载时清理资源
        window.addEventListener('beforeunload', function() {
            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.close();
            }
        });
        
        // 添加一个全局错误处理函数
        window.addEventListener('error', function(event) {
            addMessage('error', '❌ 页面错误: ' + event.error.message);
        });
        
        // ==================== 通知系统功能 ====================
        
        // 切换功能模式
        function switchMode(mode) {
            console.log('switchMode called with:', mode);
            currentMode = mode;
            const chatMode = document.getElementById('chatMode');
            const noticeMode = document.getElementById('noticeMode');
            const chatBtn = document.getElementById('chatModeBtn');
            const noticeBtn = document.getElementById('noticeModeBtn');
            const logTitle = document.getElementById('logTitle');
            const apiLogTitle = document.getElementById('apiLogTitle');
            const apiLogSubtitle = document.getElementById('apiLogSubtitle');
            
            console.log('Elements found:', {
                chatMode: !!chatMode,
                noticeMode: !!noticeMode,
                chatBtn: !!chatBtn,
                noticeBtn: !!noticeBtn
            });
            
            if (mode === 'chat') {
                if (chatMode) chatMode.style.display = 'block';
                if (noticeMode) noticeMode.style.display = 'none';
                if (chatBtn) chatBtn.style.backgroundColor = '#1976d2';
                if (noticeBtn) noticeBtn.style.backgroundColor = '#666';
                if (logTitle) logTitle.textContent = '📋 消息日志';
                if (apiLogTitle) apiLogTitle.textContent = '📡 API 调用日志';
                if (apiLogSubtitle) apiLogSubtitle.textContent = '实时监控前端API调用';
                addMessage('system', '🔄 已切换到聊天测试模式');
                console.log('Switched to chat mode');
            } else {
                console.log('Switching to notice mode...');
                if (chatMode) {
                    chatMode.style.display = 'none';
                    console.log('Chat mode hidden');
                }
                if (noticeMode) {
                    noticeMode.style.display = 'block';
                    console.log('Notice mode shown, display style:', noticeMode.style.display);
                    console.log('Notice mode computed style:', window.getComputedStyle(noticeMode).display);
                }
                if (chatBtn) chatBtn.style.backgroundColor = '#666';
                if (noticeBtn) noticeBtn.style.backgroundColor = '#1976d2';
                if (logTitle) logTitle.textContent = '🔔 通知日志';
                if (apiLogTitle) apiLogTitle.textContent = '📡 通知API日志';
                if (apiLogSubtitle) apiLogSubtitle.textContent = '实时监控通知API调用';
                addMessage('system', '🔄 已切换到通知测试模式');
                console.log('Notice mode switch completed');
                
                // 自动复制Token
                copyTokenFromChat();
            }
        }
        
        // 从聊天模式复制Token
        function copyTokenFromChat() {
            const chatToken = document.getElementById('jwtToken').value.trim();
            if (chatToken) {
                document.getElementById('noticeJwtToken').value = chatToken;
                addMessage('system', '✅ 已从聊天模式复制Token');
            } else {
                addMessage('system', '💡 聊天模式中没有Token，请先在聊天模式获取Token');
            }
        }
        
        // 切换通知WebSocket连接
        function toggleNoticeConnection() {
            if (noticeWs && noticeWs.readyState === WebSocket.OPEN) {
                noticeWs.close();
            } else {
                connectNotice();
            }
        }
        
        // 连接通知WebSocket
        function connectNotice() {
            const url = document.getElementById('noticeWsUrl').value;
            updateNoticeStatus('connecting', '连接中...');
            
            try {
                noticeWs = new WebSocket(url);
                
                noticeWs.onopen = function() {
                    updateNoticeStatus('connected', '已连接');
                    document.getElementById('noticeConnectBtn').textContent = '断开连接';
                    addMessage('system', '✅ 通知WebSocket连接成功');
                };
                
                noticeWs.onmessage = function(event) {
                    try {
                        const data = JSON.parse(event.data);
                        addMessage('received', '🔔 收到通知: ' + JSON.stringify(data, null, 2));
                        
                        if (data.type === 'notice') {
                            showNotificationPopup(data.data);
                        } else if (data.type === 'authenticated') {
                            noticeAuthenticated = true;
                            addMessage('system', '✅ 通知系统认证成功');
                        } else if (data.type === 'pong') {
                            addMessage('system', '🏓 收到pong响应');
                        }
                    } catch (e) {
                        addMessage('received', '🔔 ' + event.data);
                    }
                };
                
                noticeWs.onclose = function() {
                    updateNoticeStatus('disconnected', '未连接');
                    document.getElementById('noticeConnectBtn').textContent = '连接通知系统';
                    noticeAuthenticated = false;
                    addMessage('system', '🔌 通知WebSocket连接已关闭');
                };
                
                noticeWs.onerror = function(error) {
                    addMessage('error', '❌ 通知连接错误: ' + error);
                };
                
            } catch (error) {
                updateNoticeStatus('disconnected', '连接失败');
                addMessage('error', '❌ 通知连接失败: ' + error.message);
            }
        }
        
        // 更新通知连接状态
        function updateNoticeStatus(status, message) {
            const statusEl = document.getElementById('noticeConnectionStatus');
            statusEl.className = 'status ' + status;
            statusEl.textContent = message;
        }
        
        // 认证通知连接
        function authenticateNotice() {
            if (!noticeWs || noticeWs.readyState !== WebSocket.OPEN) {
                addMessage('error', '❌ 请先建立通知WebSocket连接');
                return;
            }
            
            const userId = document.getElementById('noticeUserId').value.trim();
            if (!userId) {
                addMessage('error', '❌ 请输入用户ID');
                return;
            }
            
            const message = {
                event: 'authenticate',
                data: { userId: parseInt(userId) }
            };
            
            noticeWs.send(JSON.stringify(message));
            addMessage('sent', '📤 发送认证: ' + JSON.stringify(message, null, 2));
        }
        
        // 通过API发送通知
        async function sendNoticeViaAPI() {
            const title = document.getElementById('noticeTitle').value.trim();
            const content = document.getElementById('noticeContent').value.trim();
            const type = document.getElementById('noticeType').value;
            const targetUserId = document.getElementById('targetUserId').value.trim();
            const scheduledTime = document.getElementById('scheduledTime').value;
            const token = document.getElementById('noticeJwtToken').value.trim();
            
            if (!title || !content) {
                addMessage('error', '❌ 请输入通知标题和内容');
                return;
            }
            
            if (!token) {
                addMessage('error', '❌ 请输入JWT Token');
                return;
            }
            
            const payload = {
                title,
                content,
                type,
                userId: targetUserId ? parseInt(targetUserId) : undefined,
                scheduledAt: scheduledTime || undefined
            };
            
            try {
                let endpoint = '/api/notices';
                if (type === 'system') {
                    endpoint = '/api/notices/system';
                } else if (type === 'broadcast') {
                    endpoint = '/api/notices/broadcast';
                }
                
                const response = await fetch(endpoint, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': 'Bearer ' + token
                    },
                    body: JSON.stringify(payload)
                });
                
                const result = await response.json();
                
                if (response.ok) {
                    addMessage('system', '✅ 通知发送成功: ' + JSON.stringify(result, null, 2));
                    clearNoticeForm();
                } else {
                    addMessage('error', '❌ 通知发送失败: ' + (result.message || '未知错误'));
                }
            } catch (error) {
                addMessage('error', '❌ 请求失败: ' + error.message);
            }
        }
        
        // 通过WebSocket发送通知 (这里只是演示，实际通知应该通过API发送)
        function sendNoticeViaWS() {
            if (!noticeWs || noticeWs.readyState !== WebSocket.OPEN) {
                addMessage('error', '❌ 请先建立通知WebSocket连接');
                return;
            }
            
            if (!noticeAuthenticated) {
                addMessage('error', '❌ 请先认证通知连接');
                return;
            }
            
            const message = {
                event: 'ping'
            };
            
            noticeWs.send(JSON.stringify(message));
            addMessage('sent', '📤 发送ping: ' + JSON.stringify(message, null, 2));
        }
        
        // 发送快速通知
        function sendQuickNotice(title, content) {
            document.getElementById('noticeTitle').value = title;
            document.getElementById('noticeContent').value = content;
            document.getElementById('noticeType').value = 'system';
            sendNoticeViaAPI();
        }
        
        // 加载通知列表
        async function loadNoticeList() {
            const token = document.getElementById('noticeJwtToken').value.trim();
            
            if (!token) {
                addMessage('error', '❌ 请输入JWT Token');
                return;
            }
            
            try {
                const response = await fetch('/api/notices', {
                    headers: {
                        'Authorization': 'Bearer ' + token
                    }
                });
                
                const notices = await response.json();
                
                if (response.ok) {
                    displayNoticeList(notices);
                    addMessage('system', '✅ 通知列表加载成功，共 ' + notices.length + ' 条');
                } else {
                    addMessage('error', '❌ 加载通知列表失败: ' + (notices.message || '未知错误'));
                }
            } catch (error) {
                addMessage('error', '❌ 请求失败: ' + error.message);
            }
        }
        
        // 获取未读通知数量
        async function getUnreadCount() {
            const token = document.getElementById('noticeJwtToken').value.trim();
            
            if (!token) {
                addMessage('error', '❌ 请输入JWT Token');
                return;
            }
            
            try {
                const response = await fetch('/api/notices/unread-count', {
                    headers: {
                        'Authorization': 'Bearer ' + token
                    }
                });
                
                const result = await response.json();
                
                if (response.ok) {
                    addMessage('system', '📊 未读通知数量: ' + result.count);
                } else {
                    addMessage('error', '❌ 获取未读数量失败: ' + (result.message || '未知错误'));
                }
            } catch (error) {
                addMessage('error', '❌ 请求失败: ' + error.message);
            }
        }
        
        // 显示通知列表
        function displayNoticeList(notices) {
            const listEl = document.getElementById('noticeList');
            listEl.innerHTML = '';
            
            if (notices.length === 0) {
                listEl.innerHTML = '<div style="text-align: center; color: #666;">暂无通知</div>';
                return;
            }
            
            notices.forEach(notice => {
                const noticeEl = document.createElement('div');
                noticeEl.style.cssText = 'border: 1px solid #ddd; padding: 8px; margin-bottom: 8px; border-radius: 4px; background: white;';
                
                const statusColor = notice.status === 'read' ? '#666' : '#1976d2';
                const statusText = notice.status === 'read' ? '已读' : '未读';
                
                noticeEl.innerHTML = \`
                    <div style="font-weight: bold; margin-bottom: 4px;">\${notice.title}</div>
                    <div style="margin-bottom: 4px;">\${notice.content}</div>
                    <div style="font-size: 12px; color: #666;">
                        类型: \${notice.type} | 
                        状态: <span style="color: \${statusColor};">\${statusText}</span> | 
                        时间: \${new Date(notice.createdAt).toLocaleString()}
                        \${notice.status !== 'read' ? 
                            \`<button onclick="markNoticeAsRead(\${notice.id})" style="margin-left: 10px; padding: 2px 6px; font-size: 11px; background-color: #4caf50; color: white; border: none; border-radius: 2px; cursor: pointer;">标记已读</button>\` : 
                            ''
                        }
                    </div>
                \`;
                
                listEl.appendChild(noticeEl);
            });
        }
        
        // 标记通知为已读
        async function markNoticeAsRead(noticeId) {
            const token = document.getElementById('noticeJwtToken').value.trim();
            
            if (!token) {
                addMessage('error', '❌ 请输入JWT Token');
                return;
            }
            
            try {
                const response = await fetch(\`/api/notices/\${noticeId}/read\`, {
                    method: 'PATCH',
                    headers: {
                        'Authorization': 'Bearer ' + token
                    }
                });
                
                const result = await response.json();
                
                if (response.ok) {
                    addMessage('system', '✅ 通知已标记为已读');
                    loadNoticeList(); // 刷新列表
                } else {
                    addMessage('error', '❌ 标记失败: ' + (result.message || '未知错误'));
                }
            } catch (error) {
                addMessage('error', '❌ 请求失败: ' + error.message);
            }
        }
        
        // 显示通知弹窗
        function showNotificationPopup(notice) {
            // 使用浏览器通知API
            if (Notification.permission === 'granted') {
                new Notification(notice.title, {
                    body: notice.content,
                    icon: '/favicon.ico'
                });
            }
            
            // 在页面上显示
            addMessage('system', \`🔔 新通知: \${notice.title} - \${notice.content}\`);
        }
        
        // 清空通知表单
        function clearNoticeForm() {
            document.getElementById('noticeTitle').value = '';
            document.getElementById('noticeContent').value = '';
            document.getElementById('targetUserId').value = '';
            document.getElementById('scheduledTime').value = '';
        }
        
        // 清空通知日志
        function clearNoticeLog() {
            if (currentMode === 'notice') {
                clearLog();
                addMessage('system', '🗑️ 通知日志已清空');
            }
        }
    </script>
</body>
</html>
    `;
    
    res.setHeader('Content-Type', 'text/html; charset=utf-8');
    res.send(html);
  }
}