🏆 LINUX DO OAuth 极简助手 - 面板集成版(无自动点击)

🎯 专为LINUX DO OAuth设计的三主题UI助手 - 简约白/紫色渐变/彩虹华丽 + 条形图统计(已移除自动点击功能)

// ==UserScript==
// @name         🏆 LINUX DO OAuth 极简助手 - 面板集成版(无自动点击)
// @namespace    https://github.com/TechnologyStar/linuxdo-oauth-helper
// @version      3.4.1
// @description  🎯 专为LINUX DO OAuth设计的三主题UI助手 - 简约白/紫色渐变/彩虹华丽 + 条形图统计(已移除自动点击功能)
// @author       Premium UI Designer
// @match        https://connect.linux.do/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_notification
// @grant        GM_openInTab
// @grant        GM_download
// @license      MIT
// @icon         data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQiIGhlaWdodD0iNjQiIHZpZXdCb3g9IjAgMCA2NCA2NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iNjQiIGhlaWdodD0iNjQiIHJ4PSIyMCIgZmlsbD0iI0ZGRkZGRiIgc3Ryb2tlPSIjRTVFN0VCIiBzdHJva2Utd2lkdGg9IjIiLz48dGV4dCB4PSIzMiIgeT0iNDAiIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWkiIGZvbnQtc2l6ZT0iMjQiIGZpbGw9IiM2QjdCODAiIHRleHQtYW5jaG9yPSJtaWRkbGUiPvCfkpA8L3RleHQ+PC9zdmc+
// ==/UserScript==

(function() {
    'use strict';

    // ================== 配置 ==================
    const CONFIG = {
        version: '3.4.0',
        github: 'https://github.com/TechnologyStar/linuxdo-oauth-helper',
        defaultSettings: {
            // 核心功能 - 移除自动点击相关
            saveLoginHistory: true,
            showNotifications: true,

            // UI设置
            autoHidePanel: false,
            enablePageStyling: true,
            theme: 'auto',
            uiTheme: 'minimal-white',

            // 高级功能
            autoExportData: false,
            checkForUpdates: true,
            enableAdvancedStats: false,
            enableDebugMode: false,
            showChartStats: true,
            showHourlyChart: false,
            showWebsiteStats: false,
            enableRealTimeStats: true,

            // 时间设置
            notificationDuration: 3000,
            panelPosition: 'top-right'
        },
        selectors: {
            approveButton: 'a.bg-red-500[href*="/oauth2/approve/"]',
            declineButton: 'a.bg-blue-500[href*="/oauth2/decline/"]',
            userInfo: 'h1.text-2xl'
        },
        themes: {
            light: {
                primary: '#ffffff',
                secondary: '#f9fafb',
                accent: '#10b981',
                text: '#111827',
                border: '#e5e7eb',
                textMuted: '#6b7280'
            },
            dark: {
                primary: '#1f2937',
                secondary: '#111827',
                accent: '#34d399',
                text: '#f9fafb',
                border: '#374151',
                textMuted: '#9ca3af'
            }
        },
        uiThemes: {
            'minimal-white': {
                name: '简约白',
                description: '极简白色设计,清爽简洁',
                icon: '⚪',
                light: {
                    panelBg: '#ffffff',
                    panelBorder: '#e5e7eb',
                    triggerBg: '#ffffff',
                    accent: '#10b981',
                    text: '#111827',
                    textMuted: '#6b7280',
                    cardBg: '#f9fafb',
                    switchBg: '#e5e7eb'
                },
                dark: {
                    panelBg: '#1f2937',
                    panelBorder: '#374151',
                    triggerBg: '#1f2937',
                    accent: '#34d399',
                    text: '#f9fafb',
                    textMuted: '#9ca3af',
                    cardBg: '#111827',
                    switchBg: '#374151'
                }
            },
            'purple-gradient': {
                name: '紫色渐变',
                description: '基于OAuth页面的紫色渐变设计',
                icon: '🟣',
                light: {
                    panelBg: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
                    panelBorder: 'rgba(255,255,255,0.2)',
                    triggerBg: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
                    accent: '#4c51bf',
                    text: '#ffffff',
                    textMuted: 'rgba(255,255,255,0.8)',
                    cardBg: 'rgba(255,255,255,0.1)',
                    switchBg: 'rgba(255,255,255,0.2)'
                },
                dark: {
                    panelBg: 'linear-gradient(135deg, #4c1d95 0%, #581c87 100%)',
                    panelBorder: 'rgba(255,255,255,0.15)',
                    triggerBg: 'linear-gradient(135deg, #4c1d95 0%, #581c87 100%)',
                    accent: '#a855f7',
                    text: '#ffffff',
                    textMuted: 'rgba(255,255,255,0.7)',
                    cardBg: 'rgba(255,255,255,0.08)',
                    switchBg: 'rgba(255,255,255,0.15)'
                }
            },
            'rainbow-fancy': {
                name: '彩虹华丽',
                description: '炫酷多彩动画设计,视觉冲击',
                icon: '🌈',
                light: {
                    panelBg: 'linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab)',
                    panelBorder: 'rgba(255,255,255,0.3)',
                    triggerBg: 'linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab)',
                    accent: '#ff6b6b',
                    text: '#ffffff',
                    textMuted: 'rgba(255,255,255,0.9)',
                    cardBg: 'rgba(255,255,255,0.1)',
                    switchBg: 'rgba(255,255,255,0.2)'
                },
                dark: {
                    panelBg: 'linear-gradient(-45deg, #b91c1c, #be185d, #1e40af, #059669)',
                    panelBorder: 'rgba(255,255,255,0.2)',
                    triggerBg: 'linear-gradient(-45deg, #b91c1c, #be185d, #1e40af, #059669)',
                    accent: '#ef4444',
                    text: '#ffffff',
                    textMuted: 'rgba(255,255,255,0.8)',
                    cardBg: 'rgba(255,255,255,0.08)',
                    switchBg: 'rgba(255,255,255,0.15)'
                }
            }
        }
    };

    // ================== 工具函数 ==================
    class Utils {
        static log(message, type = 'info') {
            const settings = window.oauthHelper?.storage?.getSettings() || {};
            if (settings.enableDebugMode || type === 'error') {
                console.log(`%c[OAuth Helper] ${message}`,
                            type === 'error' ? 'color: red' : 'color: #10B981',
                            new Date().toLocaleTimeString()
                           );
            }
        }

        static formatDate(date) {
            return new Date(date).toLocaleString('zh-CN');
        }

        static generateId() {
            return Date.now() + '-' + Math.random().toString(36).substr(2, 6);
        }

        static debounce(func, wait) {
            let timeout;
            return function(...args) {
                clearTimeout(timeout);
                timeout = setTimeout(() => func.apply(this, args), wait);
            };
        }

        static formatBytes(bytes) {
            if (bytes === 0) return '0 Bytes';
            const k = 1024;
            const sizes = ['Bytes', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }

        static normalizeHost(input = '') {
            if (!input) return '';
            let s = String(input).trim();
            s = s.replace(/^https?:\/\//i, '').replace(/\/+$/g, '');
            s = s.split('/')[0];
            return s.toLowerCase();
        }

        static fetchText(url) {
            return new Promise((resolve, reject) => {
                if (typeof GM_xmlhttpRequest === 'function') {
                    GM_xmlhttpRequest({
                        method: 'GET',
                        url,
                        headers: { 'Cache-Control': 'no-cache' },
                        timeout: 15000,
                        onload: r => resolve(r.responseText),
                        onerror: e => reject(e && e.error || 'GM_xmlhttpRequest error'),
                        ontimeout: () => reject('GM_xmlhttpRequest timeout')
                    });
                } else {
                    fetch(url, { cache: 'no-store' })
                        .then(res => res.text())
                        .then(resolve)
                        .catch(err => reject(err?.message || 'fetch error'));
                }
            });
        }

        static exportToJSON(data, filename) {
            const blob = new Blob([JSON.stringify(data, null, 2)], {
                type: 'application/json'
            });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = filename;
            a.click();
            URL.revokeObjectURL(url);
        }

        static async importFromJSON(file) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();
                reader.onload = (e) => {
                    try {
                        const data = JSON.parse(e.target.result);
                        resolve(data);
                    } catch (error) {
                        reject(error);
                    }
                };
                reader.onerror = reject;
                reader.readAsText(file);
            });
        }

        static isDarkMode() {
            const settings = window.oauthHelper?.storage?.getSettings() || CONFIG.defaultSettings;
            if (settings.theme === 'auto') {
                return window.matchMedia('(prefers-color-scheme: dark)').matches;
            }
            return settings.theme === 'dark';
        }

        static getCurrentThemeColors(uiTheme) {
            const isDark = Utils.isDarkMode();
            const theme = CONFIG.uiThemes[uiTheme];
            return isDark ? theme.dark : theme.light;
        }

        // 生成条形图HTML
        static generateBarChart(data, options = {}) {
            const {
                maxHeight = 80,
                barColor = '#10b981',
                backgroundColor = '#f3f4f6',
                showValues = true,
                className = 'oauth-chart-bar'
            } = options;

            const maxValue = Math.max(...Object.values(data));
            if (maxValue === 0) return '<div class="oauth-chart-empty">📊 暂无统计数据</div>';

            return Object.entries(data).map(([label, value]) => {
                const percentage = (value / maxValue) * 100;
                const height = Math.max((percentage / 100) * maxHeight, 4);

                return `
                    <div class="oauth-chart-bar-container">
                        <div class="oauth-chart-bar-wrapper" style="height: ${maxHeight + 5}px;">
                            <div class="${className}"
                                 style="height: ${height}px; background: ${barColor};"
                                 data-value="${value}" data-label="${label}">
                                ${showValues && value > 0 ? `<span class="oauth-chart-value">${value}</span>` : ''}
                            </div>
                        </div>
                        <div class="oauth-chart-label" title="${label}: ${value}次">${label}</div>
                    </div>
                `;
            }).join('');
        }

        static generateTimeSeriesData(history) {
            const now = new Date();
            const last7Days = {};

            for (let i = 6; i >= 0; i--) {
                const date = new Date(now);
                date.setDate(date.getDate() - i);
                const dateKey = date.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' });
                last7Days[dateKey] = 0;
            }

            history.forEach(record => {
                const recordDate = new Date(record.timestamp);
                const dateKey = recordDate.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' });
                if (last7Days.hasOwnProperty(dateKey)) {
                    last7Days[dateKey]++;
                }
            });

            return last7Days;
        }

        static generateHourlyData(history) {
            const today = new Date();
            const todayStr = today.toDateString();
            const hourlyData = {};

            for (let i = 0; i < 24; i++) {
                const hour = i.toString().padStart(2, '0') + ':00';
                hourlyData[hour] = 0;
            }

            history.forEach(record => {
                const recordDate = new Date(record.timestamp);
                if (recordDate.toDateString() === todayStr) {
                    const hour = recordDate.getHours().toString().padStart(2, '0') + ':00';
                    hourlyData[hour]++;
                }
            });

            return hourlyData;
        }

        static generateWebsiteStats(history) {
            const websites = {};

            history.forEach(record => {
                const website = record.website || '未知网站';
                websites[website] = (websites[website] || 0) + 1;
            });

            const sortedWebsites = Object.entries(websites)
            .sort(([,a], [,b]) => b - a)
            .slice(0, 5)
            .reduce((obj, [key, value]) => ({ ...obj, [key]: value }), {});

            return sortedWebsites;
        }

        static generateActionStats(history) {
            const actions = {
                '手动授权': 0,
                '手动拒绝': 0
            };

            history.forEach(record => {
                if (record.action === '手动授权') {
                    actions['手动授权']++;
                } else if (record.action === '手动拒绝') {
                    actions['手动拒绝']++;
                }
            });

            return actions;
        }
    }

    // ================== 存储管理 ==================
    class Storage {
        constructor() {
            this.prefix = 'loh_';
            this.initStorage();
        }

        initStorage() {
            const keys = ['settings', 'stats', 'history', 'metadata'];

            keys.forEach(key => {
                if (this.get(key) === null) {
                    this.set(key, this.getDefaultValue(key));
                }
            });
        }

        getDefaultValue(key) {
            const defaults = {
                settings: CONFIG.defaultSettings,
                stats: {
                    totalLogins: 0,
                    manualClicks: 0,
                    sessionsCount: 0,
                    lastUpdate: null,
                    installDate: new Date().toISOString(),
                    totalUsageTime: 0,
                    declineCount: 0
                },
                history: [],
                metadata: {
                    version: CONFIG.version,
                    lastBackup: null,
                    migrationVersion: 1
                }
            };
            return defaults[key] || {};
        }

        get(key, defaultValue = null) {
            try {
                return GM_getValue(this.prefix + key, defaultValue);
            } catch (error) {
                Utils.log(`读取存储失败: ${key}`, 'error');
                return defaultValue;
            }
        }

        set(key, value) {
            try {
                GM_setValue(this.prefix + key, value);
                Utils.log(`存储成功: ${key}`);
                return true;
            } catch (error) {
                Utils.log(`存储失败: ${key}`, 'error');
                return false;
            }
        }

        getSettings() {
            return { ...CONFIG.defaultSettings, ...this.get('settings', {}) };
        }

        updateSetting(key, value) {
            const settings = this.getSettings();
            settings[key] = value;
            this.set('settings', settings);
            Utils.log(`设置更新: ${key} = ${value}`);
        }

        addHistory(record) {
            const history = this.get('history', []);
            const newRecord = {
                id: Utils.generateId(),
                timestamp: new Date().toISOString(),
                ...record
            };

            history.unshift(newRecord);

            if (history.length > 200) {
                history.splice(200);
            }

            this.set('history', history);
            Utils.log('历史记录已保存');
            return newRecord;
        }

        getHistory() {
            return this.get('history', []);
        }

        clearHistory() {
            this.set('history', []);
            Utils.log('历史记录已清空');
        }

        updateStats(key, value = 1) {
            const stats = this.get('stats', this.getDefaultValue('stats'));

            stats[key] = (stats[key] || 0) + value;
            stats.lastUpdate = new Date().toISOString();

            this.set('stats', stats);
            Utils.log(`统计更新: ${key} +${value}`);
        }

        getStats() {
            return this.get('stats', this.getDefaultValue('stats'));
        }

        exportAllData() {
            const data = {
                settings: this.getSettings(),
                stats: this.getStats(),
                history: this.getHistory(),
                metadata: {
                    version: CONFIG.version,
                    exportDate: new Date().toISOString(),
                    dataSize: this.calculateDataSize()
                }
            };
            return data;
        }

        importAllData(data) {
            try {
                if (data.settings) this.set('settings', data.settings);
                if (data.stats) this.set('stats', data.stats);
                if (data.history) this.set('history', data.history);

                Utils.log('数据导入成功');
                return true;
            } catch (error) {
                Utils.log('数据导入失败: ' + error.message, 'error');
                return false;
            }
        }

        calculateDataSize() {
            let totalSize = 0;
            ['settings', 'stats', 'history', 'metadata'].forEach(key => {
                const data = this.get(key);
                if (data) {
                    totalSize += JSON.stringify(data).length;
                }
            });
            return totalSize;
        }
    }

    // ================== 页面信息提取 ==================
    class PageInfo {
        constructor() {
            this.extract();
        }

        extract() {
            try {
                const userEl = document.querySelector('h1.text-2xl');
                const userText = userEl ? userEl.textContent : '';
                const userMatch = userText.match(/你好,\s*(.+?)\s*(\d+)级用户/);

                const systemEl = this.findTextElement('系统:');
                const system = systemEl ? systemEl.textContent.replace('系统:', '').trim() : '未知系统';

                const websiteEl = this.findTextElement('网站:');
                let website = '未知网站';
                let websiteUrl = '';
                if (websiteEl) {
                    const link = websiteEl.querySelector('a');
                    if (link) {
                        website = (link.textContent || '').trim();
                        websiteUrl = link.getAttribute('href') || '';
                    } else {
                        website = websiteEl.textContent.replace('网站:', '').trim();
                    }
                }
                const websiteHost = Utils.normalizeHost(websiteUrl || website);

                const descEl = this.findTextElement('描述:');
                const description = descEl ? descEl.textContent.replace('描述:', '').trim() : '无描述';

                this.info = {
                    user: {
                        name: userMatch ? userMatch[1] : '未知用户',
                        level: userMatch ? parseInt(userMatch[2]) : 0
                    },
                    system,
                    website,
                    websiteUrl,
                    websiteHost,
                    description,
                    extractTime: new Date().toISOString(),
                    pageType: this.getPageType(),
                    url: window.location.href
                };

                Utils.log('页面信息提取完成');

            } catch (error) {
                Utils.log('页面信息提取失败', 'error');
                this.info = {
                    user: { name: '未知用户', level: 0 },
                    system: '未知系统',
                    website: '未知网站',
                    websiteUrl: '',
                    websiteHost: '',
                    description: '无描述',
                    extractTime: new Date().toISOString(),
                    pageType: this.getPageType(),
                    url: window.location.href
                };
            }
        }

        getPageType() {
            const path = window.location.pathname;
            if (path.includes('/oauth2/approve')) return 'oauth-approve';
            if (path.includes('/oauth2/decline')) return 'oauth-decline';
            if (path.includes('/oauth2/')) return 'oauth-other';
            return 'main';
        }

        findTextElement(text) {
            const elements = document.querySelectorAll('strong');
            for (const el of elements) {
                if (el.textContent.includes(text)) {
                    return el.parentElement;
                }
            }
            return null;
        }

        get() {
            return this.info;
        }
    }

    // ================== 点击跟踪管理器 ==================
    class ClickTracker {
        constructor(storage, settings) {
            this.storage = storage;
            this.settings = settings;
            this.hasTrackedManualClick = false;
            this.pageInfo = new PageInfo();

            Utils.log('点击跟踪管理器初始化');
            this.init();
        }

        async init() {
            await this.waitForButtons();
            this.addManualClickListeners();
        }

        async waitForButtons() {
            return new Promise((resolve) => {
                const checkButtons = () => {
                    const approveBtn = document.querySelector(CONFIG.selectors.approveButton);
                    const declineBtn = document.querySelector(CONFIG.selectors.declineButton);

                    if (approveBtn || declineBtn) {
                        Utils.log('找到授权按钮,准备添加监听器');
                        resolve();
                    } else {
                        setTimeout(checkButtons, 100);
                    }
                };
                checkButtons();
            });
        }

        addManualClickListeners() {
            const approveBtn = document.querySelector(CONFIG.selectors.approveButton);
            if (approveBtn) {
                approveBtn.addEventListener('click', (e) => {
                    Utils.log('检测到手动点击授权按钮');
                    this.recordManualClick('手动授权', 'approve');
                });
            }

            const declineBtn = document.querySelector(CONFIG.selectors.declineButton);
            if (declineBtn) {
                declineBtn.addEventListener('click', (e) => {
                    Utils.log('检测到手动点击拒绝按钮');
                    this.recordManualClick('手动拒绝', 'decline');
                });
            }
        }

        recordManualClick(action, type) {
            if (this.hasTrackedManualClick) {
                Utils.log('已记录过手动点击,跳过');
                return;
            }

            this.hasTrackedManualClick = true;

            if (this.settings.saveLoginHistory) {
                const pageInfo = this.pageInfo.get();
                this.storage.addHistory({
                    action: action,
                    system: pageInfo.system,
                    website: pageInfo.website,
                    description: pageInfo.description,
                    user: pageInfo.user,
                    clickType: 'manual',
                    buttonType: type,
                    pageType: pageInfo.pageType,
                    url: pageInfo.url
                });
                Utils.log(`手动点击历史已记录: ${action}`);
            }

            this.storage.updateStats('manualClicks');
            this.storage.updateStats('totalLogins');

            if (type === 'decline') {
                this.storage.updateStats('declineCount');
            }

            Utils.log(`手动点击统计已更新: ${action}`);

            if (this.settings.showNotifications) {
                this.showNotification(`${action}已记录`);
            }
        }

        showNotification(message) {
            if (typeof GM_notification === 'function') {
                GM_notification({
                    title: '🏆 OAuth助手',
                    text: message,
                    timeout: this.settings.notificationDuration
                });
            }
        }

        updateSettings(settings) {
            this.settings = settings;
        }
    }

    // ================== UI管理器 ==================
    class UIManager {
        constructor(storage) {
            this.storage = storage;
            this.settings = storage.getSettings();
            this.isVisible = false;
            this.currentTheme = this.settings.theme;
            this.currentUITheme = this.settings.uiTheme || 'minimal-white';
            this.realTimeTimer = null;
            this.init();
        }

        init() {
            this.addStyles();
            this.createUI();
            this.bindEvents();
            this.applyTheme();
            this.startRealTimeUpdates();
            Utils.log('UI管理器初始化完成');
        }

        startRealTimeUpdates() {
            if (this.settings.enableRealTimeStats) {
                this.realTimeTimer = setInterval(() => {
                    if (this.isVisible) {
                        this.refreshStats();
                    }
                }, 30000); // 每30秒更新一次
            }
        }

        refreshStats() {
            const statsSection = this.ui.querySelector('.oauth-section:has(.oauth-stat-grid)');
            if (statsSection) {
                const newStatsHTML = this.generateStatsHTML();
                const tempDiv = document.createElement('div');
                tempDiv.innerHTML = newStatsHTML;
                const newStatsSection = tempDiv.querySelector('.oauth-section:has(.oauth-stat-grid)');
                if (newStatsSection) {
                    statsSection.innerHTML = newStatsSection.innerHTML;
                }
            }
        }

        addStyles() {
            const isOAuthPage = this.isOAuthPage();
            const enableStyling = this.settings.enablePageStyling;
            const isDark = Utils.isDarkMode();
            const uiTheme = Utils.getCurrentThemeColors(this.currentUITheme);

            let css = `
                /* OAuth助手基础样式 */
                .oauth-helper {
                    position: fixed;
                    ${this.getPositionStyles()}
                    z-index: 10000;
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
                }

                .oauth-trigger {
                    width: 48px;
                    height: 48px;
                    background: ${uiTheme.triggerBg};
                    border: 2px solid ${uiTheme.panelBorder};
                    border-radius: 24px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    cursor: pointer;
                    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
                    transition: all 0.3s ease;
                    color: ${uiTheme.text};
                    font-size: 20px;
                    ${this.currentUITheme === 'rainbow-fancy' ? 'animation: rainbow-rotate 4s ease-in-out infinite;' : ''}
                }

                .oauth-trigger:hover {
                    transform: translateY(-2px) scale(1.05);
                    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
                    ${this.currentUITheme === 'rainbow-fancy' ? 'filter: brightness(1.1);' : ''}
                }

                .oauth-trigger.active {
                    transform: translateY(-1px) scale(1.02);
                    box-shadow: 0 8px 12px -2px rgba(0, 0, 0, 0.15);
                }

                .oauth-panel {
                    position: absolute;
                    ${this.getPanelPositionStyles()}
                    width: 400px;
                    background: ${uiTheme.panelBg};
                    border: 2px solid ${uiTheme.panelBorder};
                    border-radius: 16px;
                    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
                    opacity: 0;
                    visibility: hidden;
                    transform: translateY(-12px) scale(0.95);
                    transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
                    overflow: hidden;
                    max-height: 80vh;
                    backdrop-filter: blur(10px);
                    ${this.currentUITheme === 'rainbow-fancy' ? 'animation: rainbow-bg 6s ease-in-out infinite; background-size: 400% 400%;' : ''}
                }

                .oauth-panel.show {
                    opacity: 1;
                    visibility: visible;
                    transform: translateY(0) scale(1);
                }

                .oauth-header {
                    padding: 20px 24px;
                    background: ${this.currentUITheme === 'minimal-white' ? (isDark ? '#111827' : '#fafafa') : 'rgba(255,255,255,0.1)'};
                    border-bottom: 1px solid ${uiTheme.panelBorder};
                    backdrop-filter: blur(5px);
                }

                .oauth-title {
                    font-size: 18px;
                    font-weight: 700;
                    color: ${uiTheme.text};
                    margin: 0;
                    ${this.currentUITheme === 'rainbow-fancy' ? 'background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: rainbow-text 3s ease-in-out infinite;' : ''}
                }

                .oauth-version {
                    font-size: 11px;
                    color: ${uiTheme.textMuted};
                    margin-top: 4px;
                    font-weight: 500;
                }

                .oauth-content {
                    padding: 0;
                    max-height: calc(80vh - 100px);
                    overflow-y: auto;
                    background: ${this.currentUITheme === 'minimal-white' ? 'transparent' : 'rgba(255,255,255,0.05)'};
                }

                .oauth-content::-webkit-scrollbar {
                    width: 6px;
                }

                .oauth-content::-webkit-scrollbar-track {
                    background: transparent;
                }

                .oauth-content::-webkit-scrollbar-thumb {
                    background: ${uiTheme.textMuted};
                    border-radius: 3px;
                    opacity: 0.5;
                }

                .oauth-section {
                    padding: 18px 24px;
                    border-bottom: 1px solid ${uiTheme.panelBorder};
                    backdrop-filter: blur(2px);
                }

                .oauth-section:last-child {
                    border-bottom: none;
                }

                .oauth-section-title {
                    font-size: 14px;
                    font-weight: 700;
                    color: ${uiTheme.text};
                    margin-bottom: 16px;
                    display: flex;
                    align-items: center;
                    gap: 10px;
                    ${this.currentUITheme === 'rainbow-fancy' ? 'text-shadow: 0 0 10px rgba(255,255,255,0.5);' : ''}
                }

                .oauth-switch-item {
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                    padding: 14px 16px;
                    background: ${uiTheme.cardBg};
                    border-radius: 12px;
                    margin-bottom: 10px;
                    transition: all 0.3s ease;
                    backdrop-filter: blur(5px);
                    ${this.currentUITheme === 'rainbow-fancy' ? 'border: 1px solid rgba(255,255,255,0.2);' : ''}
                }

                .oauth-switch-item:hover {
                    background: ${this.currentUITheme === 'minimal-white' ? (isDark ? '#374151' : '#f3f4f6') : 'rgba(255,255,255,0.15)'};
                    transform: translateY(-1px);
                    ${this.currentUITheme === 'rainbow-fancy' ? 'box-shadow: 0 4px 15px rgba(0,0,0,0.1);' : ''}
                }

                .oauth-switch-info {
                    flex: 1;
                }

                .oauth-switch-label {
                    font-size: 14px;
                    color: ${uiTheme.text};
                    font-weight: 600;
                    margin-bottom: 3px;
                }

                .oauth-switch-desc {
                    font-size: 12px;
                    color: ${uiTheme.textMuted};
                    line-height: 1.4;
                }

                .oauth-switch {
                    position: relative;
                    width: 44px;
                    height: 24px;
                    background: ${uiTheme.switchBg};
                    border-radius: 12px;
                    cursor: pointer;
                    transition: all 0.3s ease;
                    flex-shrink: 0;
                }

                .oauth-switch.active {
                    background: ${uiTheme.accent};
                    ${this.currentUITheme === 'rainbow-fancy' ? 'box-shadow: 0 0 20px rgba(255,107,107,0.6);' : ''}
                }

                .oauth-switch-knob {
                    position: absolute;
                    top: 2px;
                    left: 2px;
                    width: 20px;
                    height: 20px;
                    background: white;
                    border-radius: 50%;
                    transition: all 0.3s ease;
                    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
                }

                .oauth-switch.active .oauth-switch-knob {
                    transform: translateX(20px);
                    ${this.currentUITheme === 'rainbow-fancy' ? 'box-shadow: 0 0 15px rgba(255,255,255,0.8);' : ''}
                }

                .oauth-btn {
                    background: ${this.currentUITheme === 'minimal-white' ? (isDark ? '#374151' : 'white') : 'rgba(255,255,255,0.1)'};
                    border: 1px solid ${uiTheme.panelBorder};
                    color: ${uiTheme.text};
                    font-size: 12px;
                    padding: 8px 14px;
                    border-radius: 8px;
                    cursor: pointer;
                    transition: all 0.3s ease;
                    font-weight: 600;
                    margin-right: 8px;
                    margin-bottom: 6px;
                    backdrop-filter: blur(5px);
                    display: inline-block;
                }

                .oauth-btn:hover {
                    background: ${this.currentUITheme === 'minimal-white' ? (isDark ? '#4b5563' : '#f3f4f6') : 'rgba(255,255,255,0.2)'};
                    transform: translateY(-1px);
                    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
                }

                .oauth-btn.primary {
                    background: ${uiTheme.accent};
                    color: ${isDark ? '#000' : 'white'};
                    border-color: ${uiTheme.accent};
                    ${this.currentUITheme === 'rainbow-fancy' ? 'background: linear-gradient(45deg, #ff6b6b, #4ecdc4); border: none;' : ''}
                }

                .oauth-btn.primary:hover {
                    ${this.currentUITheme === 'rainbow-fancy' ? 'filter: brightness(1.1); transform: translateY(-2px);' : 'filter: brightness(0.9);'}
                }

                .oauth-btn.danger {
                    border-color: #ef4444;
                    color: #ef4444;
                }

                .oauth-btn.danger:hover {
                    border-color: #dc2626;
                    color: #dc2626;
                    background: ${this.currentUITheme === 'minimal-white' ? '#fef2f2' : 'rgba(239,68,68,0.1)'};
                }

                .oauth-stat-card {
                    background: ${uiTheme.cardBg};
                    border: 1px solid ${uiTheme.panelBorder};
                    border-radius: 12px;
                    padding: 16px;
                    text-align: center;
                    margin-bottom: 10px;
                    transition: all 0.3s ease;
                    backdrop-filter: blur(5px);
                    ${this.currentUITheme === 'rainbow-fancy' ? 'border: 1px solid rgba(255,255,255,0.2);' : ''}
                }

                .oauth-stat-card:hover {
                    transform: translateY(-2px);
                    ${this.currentUITheme === 'rainbow-fancy' ? 'box-shadow: 0 8px 25px rgba(0,0,0,0.15);' : ''}
                }

                .oauth-stat-value {
                    font-size: 24px;
                    font-weight: 800;
                    color: ${uiTheme.text};
                    margin-bottom: 6px;
                    ${this.currentUITheme === 'rainbow-fancy' ? 'background: linear-gradient(45deg, #ff6b6b, #4ecdc4); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent;' : ''}
                }

                .oauth-stat-label {
                    font-size: 11px;
                    color: ${uiTheme.textMuted};
                    font-weight: 600;
                    text-transform: uppercase;
                    letter-spacing: 0.5px;
                }

                .oauth-stat-grid {
                    display: grid;
                    grid-template-columns: 1fr 1fr;
                    gap: 10px;
                    margin-bottom: 16px;
                }

                .oauth-chart-container {
                    background: ${uiTheme.cardBg};
                    border: 1px solid ${uiTheme.panelBorder};
                    border-radius: 12px;
                    padding: 16px;
                    margin-bottom: 16px;
                    backdrop-filter: blur(5px);
                    ${this.currentUITheme === 'rainbow-fancy' ? 'border: 1px solid rgba(255,255,255,0.2);' : ''}
                }

                .oauth-chart-title {
                    font-size: 13px;
                    font-weight: 600;
                    color: ${uiTheme.text};
                    margin-bottom: 12px;
                    text-align: center;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 6px;
                }

                .oauth-chart-bars {
                    display: flex;
                    align-items: end;
                    gap: 6px;
                    height: 100px;
                    justify-content: space-between;
                    margin-bottom: 4px;
                }

                .oauth-chart-bar-container {
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    flex: 1;
                    min-width: 0;
                }

                .oauth-chart-bar-wrapper {
                    position: relative;
                    display: flex;
                    align-items: end;
                    width: 100%;
                    margin-bottom: 8px;
                }

                .oauth-chart-bar {
                    width: 100%;
                    background: ${uiTheme.accent};
                    border-radius: 4px 4px 0 0;
                    position: relative;
                    transition: all 0.3s ease;
                    min-height: 4px;
                    cursor: pointer;
                    ${this.currentUITheme === 'rainbow-fancy' ? 'background: linear-gradient(45deg, #ff6b6b, #4ecdc4); box-shadow: 0 2px 8px rgba(255,107,107,0.3);' : ''}
                }

                .oauth-chart-bar:hover {
                    ${this.currentUITheme === 'rainbow-fancy' ? 'filter: brightness(1.1); box-shadow: 0 4px 12px rgba(255,107,107,0.4);' : 'filter: brightness(0.9);'}
                    transform: translateY(-1px);
                }

                .oauth-chart-value {
                    position: absolute;
                    top: -20px;
                    left: 50%;
                    transform: translateX(-50%);
                    font-size: 10px;
                    font-weight: 600;
                    color: ${uiTheme.text};
                    background: ${this.currentUITheme === 'minimal-white' ? (isDark ? 'rgba(0,0,0,0.8)' : 'rgba(255,255,255,0.9)') : 'rgba(0,0,0,0.7)'};
                    padding: 2px 6px;
                    border-radius: 4px;
                    white-space: nowrap;
                    opacity: 0;
                    transition: opacity 0.3s ease;
                }

                .oauth-chart-bar:hover .oauth-chart-value {
                    opacity: 1;
                }

                .oauth-chart-label {
                    font-size: 10px;
                    color: ${uiTheme.textMuted};
                    font-weight: 500;
                    text-align: center;
                    white-space: nowrap;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    max-width: 100%;
                }

                .oauth-chart-empty {
                    text-align: center;
                    color: ${uiTheme.textMuted};
                    font-size: 12px;
                    padding: 40px 20px;
                    font-style: italic;
                }

                .oauth-history-item {
                    padding: 16px;
                    border-bottom: 1px solid ${uiTheme.panelBorder};
                    font-size: 13px;
                    transition: all 0.3s ease;
                }

                .oauth-history-item:hover {
                    background: ${uiTheme.cardBg};
                    padding-left: 20px;
                }

                .oauth-history-item:last-child {
                    border-bottom: none;
                }

                .oauth-history-title {
                    font-weight: 700;
                    color: ${uiTheme.text};
                    margin-bottom: 6px;
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                }

                .oauth-history-detail {
                    color: ${uiTheme.textMuted};
                    margin-bottom: 3px;
                    font-size: 12px;
                }

                .oauth-history-time {
                    color: ${uiTheme.textMuted};
                    font-size: 10px;
                    font-weight: 500;
                }

                .oauth-history-badge {
                    font-size: 10px;
                    padding: 3px 8px;
                    border-radius: 12px;
                    font-weight: 700;
                    text-transform: uppercase;
                    letter-spacing: 0.5px;
                }

                .oauth-history-badge.manual {
                    background: ${this.currentUITheme === 'minimal-white' ? (isDark ? 'rgba(34,197,94,0.2)' : '#d1fae5') : 'rgba(34,197,94,0.2)'};
                    color: ${this.currentUITheme === 'minimal-white' ? (isDark ? '#86efac' : '#065f46') : '#86efac'};
                }

                .oauth-empty {
                    text-align: center;
                    padding: 40px 20px;
                    color: ${uiTheme.textMuted};
                    font-style: italic;
                    font-size: 12px;
                }

                .oauth-divider {
                    height: 1px;
                    background: ${uiTheme.panelBorder};
                    margin: 16px 0;
                }

                .oauth-input, .oauth-select {
                    width: 100%;
                    padding: 10px 14px;
                    border: 1px solid ${uiTheme.panelBorder};
                    border-radius: 8px;
                    background: ${this.currentUITheme === 'minimal-white' ? (isDark ? '#374151' : 'white') : 'rgba(255,255,255,0.1)'};
                    color: ${uiTheme.text};
                    font-size: 13px;
                    margin: 6px 0;
                    transition: all 0.3s ease;
                    backdrop-filter: blur(5px);
                }

                .oauth-input:focus, .oauth-select:focus {
                    outline: none;
                    border-color: ${uiTheme.accent};
                    ${this.currentUITheme === 'rainbow-fancy' ? 'box-shadow: 0 0 20px rgba(255,107,107,0.3);' : 'box-shadow: 0 0 0 3px rgba(16,185,129,0.1);'}
                }

                .oauth-ui-theme-selector {
                    display: grid;
                    grid-template-columns: 1fr 1fr 1fr;
                    gap: 8px;
                    margin-top: 12px;
                }

                .oauth-ui-theme-option {
                    padding: 12px 8px;
                    border: 2px solid ${uiTheme.panelBorder};
                    border-radius: 10px;
                    text-align: center;
                    cursor: pointer;
                    transition: all 0.3s ease;
                    background: ${this.currentUITheme === 'minimal-white' ? (isDark ? '#374151' : 'white') : 'rgba(255,255,255,0.1)'};
                    backdrop-filter: blur(5px);
                }

                .oauth-ui-theme-option:hover {
                    transform: translateY(-2px);
                    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
                }

                .oauth-ui-theme-option.active {
                    border-color: ${uiTheme.accent};
                    background: ${this.currentUITheme === 'minimal-white' ? (isDark ? 'rgba(16,185,129,0.1)' : '#f0fdf4') : 'rgba(16,185,129,0.1)'};
                    ${this.currentUITheme === 'rainbow-fancy' ? 'box-shadow: 0 0 20px rgba(255,107,107,0.3);' : ''}
                }

                .oauth-ui-theme-icon {
                    font-size: 18px;
                    margin-bottom: 4px;
                }

                .oauth-ui-theme-name {
                    font-size: 11px;
                    font-weight: 600;
                    color: ${uiTheme.text};
                }

                .oauth-real-time-indicator {
                    display: inline-block;
                    width: 6px;
                    height: 6px;
                    border-radius: 50%;
                    background: #10b981;
                    margin-left: 6px;
                    animation: pulse 2s infinite;
                }

                /* 动画效果 */
                @keyframes rainbow-rotate {
                    0%, 100% { transform: rotate(0deg) scale(1); }
                    50% { transform: rotate(180deg) scale(1.1); }
                }

                @keyframes rainbow-bg {
                    0% { background-position: 0% 50%; }
                    50% { background-position: 100% 50%; }
                    100% { background-position: 0% 50%; }
                }

                @keyframes rainbow-text {
                    0%, 100% { background-position: 0% 50%; }
                    50% { background-position: 100% 50%; }
                }

                @keyframes slideIn {
                    from { transform: translateX(100%); opacity: 0; }
                    to { transform: translateX(0); opacity: 1; }
                }

                @keyframes fadeIn {
                    from { opacity: 0; transform: translateY(10px); }
                    to { opacity: 1; transform: translateY(0); }
                }

                @keyframes pulse {
                    0%, 100% { opacity: 1; }
                    50% { opacity: 0.5; }
                }

                .oauth-highlight {
                    animation: pulse 1s ease-in-out 3;
                }

                .oauth-fade-in {
                    animation: fadeIn 0.5s ease-out;
                }
            `;

            // 只在OAuth页面且启用UI优化时添加页面美化样式
            if (isOAuthPage && enableStyling) {
                css += this.getOAuthPageStyles();
            }

            GM_addStyle(css);
        }

        getOAuthPageStyles() {
            const uiTheme = this.currentUITheme;
            const isDark = Utils.isDarkMode();

            switch (uiTheme) {
                case 'purple-gradient':
                    return `
                        body {
                            background: ${isDark ? 'linear-gradient(135deg, #4c1d95 0%, #581c87 100%)' : 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'} !important;
                            min-height: 100vh;
                        }

                        .bg-white {
                            background: rgba(255,255,255,${isDark ? '0.08' : '0.95'}) !important;
                            backdrop-filter: blur(10px) !important;
                            border-radius: 20px !important;
                            box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
                            border: 1px solid rgba(255,255,255,0.2) !important;
                        }

                        .bg-red-500, .bg-blue-500 {
                            border-radius: 12px !important;
                            font-weight: 600 !important;
                            padding: 12px 24px !important;
                            transition: all 0.3s ease !important;
                            backdrop-filter: blur(5px) !important;
                        }

                        .bg-red-500 {
                            background: linear-gradient(135deg, #10b981, #059669) !important;
                            color: white !important;
                            border: none !important;
                        }

                        .bg-red-500:hover {
                            background: linear-gradient(135deg, #059669, #047857) !important;
                            transform: translateY(-2px) !important;
                            box-shadow: 0 10px 25px rgba(16,185,129,0.4) !important;
                        }

                        .bg-red-500::before {
                            content: '✓ ';
                            color: white;
                            font-weight: bold;
                        }

                        .bg-blue-500 {
                            background: rgba(239,68,68,0.9) !important;
                            color: white !important;
                            border: none !important;
                        }

                        .bg-blue-500:hover {
                            background: rgba(220,38,38,0.9) !important;
                            transform: translateY(-2px) !important;
                            box-shadow: 0 10px 25px rgba(239,68,68,0.4) !important;
                        }

                        .bg-blue-500::before {
                            content: '✕ ';
                            color: white;
                            font-weight: bold;
                        }

                        .bg-white p:has(strong) {
                            background: linear-gradient(135deg, #fef3c7, #fde68a) !important;
                            padding: 16px !important;
                            border-radius: 12px !important;
                            border-left: 4px solid #f59e0b !important;
                            margin: 16px 0 !important;
                        }
                    `;

                case 'rainbow-fancy':
                    return `
                        body {
                            background: ${isDark ? 'linear-gradient(-45deg, #b91c1c, #be185d, #1e40af, #059669)' : 'linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab)'} !important;
                            background-size: 400% 400% !important;
                            animation: rainbow-bg 6s ease-in-out infinite !important;
                            min-height: 100vh !important;
                        }

                        .bg-white {
                            background: rgba(255,255,255,${isDark ? '0.05' : '0.1'}) !important;
                            backdrop-filter: blur(20px) !important;
                            border-radius: 25px !important;
                            box-shadow: 0 30px 60px -12px rgba(0, 0, 0, 0.4) !important;
                            border: 2px solid rgba(255,255,255,0.3) !important;
                            position: relative !important;
                            overflow: hidden !important;
                        }

                        .bg-white::before {
                            content: '';
                            position: absolute;
                            top: 0;
                            left: 0;
                            right: 0;
                            bottom: 0;
                            background: linear-gradient(45deg, transparent 40%, rgba(255,255,255,0.1) 50%, transparent 60%);
                            animation: shine 3s ease-in-out infinite;
                            pointer-events: none;
                        }

                        @keyframes shine {
                            0% { transform: translateX(-100%); }
                            100% { transform: translateX(100%); }
                        }

                        .bg-red-500, .bg-blue-500 {
                            border-radius: 15px !important;
                            font-weight: 700 !important;
                            padding: 14px 28px !important;
                            transition: all 0.4s ease !important;
                            backdrop-filter: blur(10px) !important;
                            position: relative !important;
                            overflow: hidden !important;
                        }

                        .bg-red-500 {
                            background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4) !important;
                            background-size: 300% 300% !important;
                            animation: rainbow-button 4s ease-in-out infinite !important;
                            color: white !important;
                            border: none !important;
                            text-shadow: 0 2px 4px rgba(0,0,0,0.3) !important;
                        }

                        .bg-red-500:hover {
                            transform: translateY(-3px) scale(1.05) !important;
                            box-shadow: 0 15px 35px rgba(255,107,107,0.6) !important;
                            filter: brightness(1.2) !important;
                        }

                        .bg-red-500::before {
                            content: '✨ ';
                            color: white;
                            font-weight: bold;
                        }

                        .bg-blue-500 {
                            background: linear-gradient(45deg, #ff6b6b, #ee5a24, #ff9ff3, #54a0ff) !important;
                            background-size: 300% 300% !important;
                            animation: rainbow-button-reverse 4s ease-in-out infinite !important;
                            color: white !important;
                            border: none !important;
                            text-shadow: 0 2px 4px rgba(0,0,0,0.3) !important;
                        }

                        .bg-blue-500:hover {
                            transform: translateY(-3px) scale(1.05) !important;
                            box-shadow: 0 15px 35px rgba(255,107,107,0.6) !important;
                            filter: brightness(1.2) !important;
                        }

                        .bg-blue-500::before {
                            content: '💫 ';
                            color: white;
                            font-weight: bold;
                        }

                        @keyframes rainbow-button {
                            0%, 100% { background-position: 0% 50%; }
                            50% { background-position: 100% 50%; }
                        }

                        @keyframes rainbow-button-reverse {
                            0%, 100% { background-position: 100% 50%; }
                            50% { background-position: 0% 50%; }
                        }

                        .bg-white p:has(strong) {
                            background: linear-gradient(45deg, rgba(255,215,0,0.3), rgba(255,165,0,0.3)) !important;
                            padding: 20px !important;
                            border-radius: 15px !important;
                            border: 2px solid rgba(255,215,0,0.5) !important;
                            margin: 20px 0 !important;
                            box-shadow: 0 8px 25px rgba(255,215,0,0.3) !important;
                            position: relative !important;
                            overflow: hidden !important;
                        }

                        .bg-white p:has(strong)::before {
                            content: '🔒';
                            position: absolute;
                            top: 10px;
                            right: 15px;
                            font-size: 20px;
                            animation: float 2s ease-in-out infinite;
                        }

                        @keyframes float {
                            0%, 100% { transform: translateY(0px); }
                            50% { transform: translateY(-5px); }
                        }
                    `;

                default: // minimal-white
                    return `
                        body {
                            background: ${isDark ? '#111827' : '#f9fafb'} !important;
                        }

                        .bg-white {
                            background: ${isDark ? '#1f2937' : 'white'} !important;
                            border: 1px solid ${isDark ? '#374151' : '#e5e7eb'} !important;
                        }

                                                .bg-red-500, .bg-blue-500 {
                            background: ${isDark ? '#374151' : 'white'} !important;
                            color: ${isDark ? '#f9fafb' : '#374151'} !important;
                            border: 2px solid ${isDark ? '#4b5563' : '#e5e7eb'} !important;
                            transition: all 0.2s ease !important;
                            position: relative !important;
                        }

                        .bg-red-500:hover, .bg-blue-500:hover {
                            background: ${isDark ? '#4b5563' : '#f9fafb'} !important;
                            border-color: ${isDark ? '#6b7280' : '#d1d5db'} !important;
                            color: ${isDark ? '#ffffff' : '#111827'} !important;
                            transform: translateY(-1px) !important;
                        }

                        .bg-red-500::before {
                            content: '✓ ';
                            color: #10b981;
                            font-weight: bold;
                        }

                        .bg-blue-500::before {
                            content: '✕ ';
                            color: #ef4444;
                            font-weight: bold;
                        }

                        .bg-white p:has(strong) {
                            background: ${isDark ? '#1f2937' : 'white'} !important;
                            padding: 16px !important;
                            border-radius: 8px !important;
                            border: 1px solid ${isDark ? '#374151' : '#e5e7eb'} !important;
                            margin: 16px 0 !important;
                            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
                        }
                    `;
            }
        }

        getPositionStyles() {
            const pos = this.settings.panelPosition;
            switch (pos) {
                case 'top-left': return 'top: 20px; left: 20px;';
                case 'bottom-right': return 'bottom: 20px; right: 20px;';
                case 'bottom-left': return 'bottom: 20px; left: 20px;';
                default: return 'top: 20px; right: 20px;';
            }
        }

        getPanelPositionStyles() {
            const pos = this.settings.panelPosition;
            switch (pos) {
                case 'top-left': return 'top: 56px; left: 0;';
                case 'bottom-right': return 'bottom: 56px; right: 0;';
                case 'bottom-left': return 'bottom: 56px; left: 0;';
                default: return 'top: 56px; right: 0;';
            }
        }

        isOAuthPage() {
            return window.location.pathname.includes('/oauth2/');
        }

        createUI() {
            const ui = document.createElement('div');
            ui.className = 'oauth-helper';
            ui.innerHTML = `
                <div class="oauth-trigger" id="oauthTrigger">
                    🏆
                </div>
                <div class="oauth-panel" id="oauthPanel">
                    <div class="oauth-header">
                        <div class="oauth-title">🏆 OAuth助手</div>
                        <div class="oauth-version">v${CONFIG.version} - 统计版(无自动点击)</div>
                    </div>
                    <div class="oauth-content">
                        ${this.generateContent()}
                    </div>
                </div>
            `;

            document.body.appendChild(ui);
            this.ui = ui;
        }

        generateContent() {
            return `
                ${this.generateUIThemeHTML()}
                ${this.generateSettingsHTML()}
                ${this.generateAdvancedSettingsHTML()}
                ${this.generateStatsHTML()}
                ${this.generateHistoryHTML()}
                ${this.generateToolsHTML()}
            `;
        }

        generateUIThemeHTML() {
            const isDark = Utils.isDarkMode();
            const uiTheme = Utils.getCurrentThemeColors(this.currentUITheme);

            return `
                <div class="oauth-section">
                    <div class="oauth-section-title">
                        <span>🎨</span>
                        <span>UI主题切换</span>
                        ${this.settings.enableRealTimeStats ? '<span class="oauth-real-time-indicator" title="实时更新"></span>' : ''}
                    </div>
                    <div style="margin-bottom: 12px; font-size: 12px; color: ${uiTheme.textMuted};">
                        选择你喜欢的界面风格,即时生效
                    </div>
                    <div class="oauth-ui-theme-selector">
                        ${Object.entries(CONFIG.uiThemes).map(([key, theme]) => `
                            <div class="oauth-ui-theme-option ${this.currentUITheme === key ? 'active' : ''}"
                                 data-theme="${key}">
                                <div class="oauth-ui-theme-icon">${theme.icon}</div>
                                <div class="oauth-ui-theme-name">${theme.name}</div>
                            </div>
                        `).join('')}
                    </div>
                    <div style="margin-top: 8px; font-size: 11px; color: ${uiTheme.textMuted}; text-align: center;">
                        当前:${CONFIG.uiThemes[this.currentUITheme].description} | 模式:${isDark ? '深色' : '浅色'}
                    </div>
                    <div style="margin-top: 12px;">
                        <button class="oauth-btn primary" id="toggleUITheme">🔄 快速切换主题</button>
                        <button class="oauth-btn" id="toggleTheme">🌓 颜色主题</button>
                        <button class="oauth-btn" id="refreshUI">⚡ 刷新界面</button>
                    </div>
                </div>
            `;
        }

        generateSettingsHTML() {
            const settings = this.settings;
            return `
                <div class="oauth-section">
                    <div class="oauth-section-title">
                        <span>⚙️</span>
                        <span>基础设置</span>
                    </div>

                    <div class="oauth-switch-item">
                        <div class="oauth-switch-info">
                            <div class="oauth-switch-label">保存登录(不可用)记录</div>
                            <div class="oauth-switch-desc">记录所有授权操作的详细历史</div>
                        </div>
                        <div class="oauth-switch ${settings.saveLoginHistory ? 'active' : ''}" data-setting="saveLoginHistory">
                            <div class="oauth-switch-knob"></div>
                        </div>
                    </div>

                    <div class="oauth-switch-item">
                        <div class="oauth-switch-info">
                            <div class="oauth-switch-label">显示通知</div>
                            <div class="oauth-switch-desc">操作完成后显示提示通知</div>
                        </div>
                        <div class="oauth-switch ${settings.showNotifications ? 'active' : ''}" data-setting="showNotifications">
                            <div class="oauth-switch-knob"></div>
                        </div>
                    </div>

                    <div class="oauth-switch-item">
                        <div class="oauth-switch-info">
                            <div class="oauth-switch-label">启用UI优化</div>
                            <div class="oauth-switch-desc">美化OAuth页面按钮和样式</div>
                        </div>
                        <div class="oauth-switch ${settings.enablePageStyling ? 'active' : ''}" data-setting="enablePageStyling">
                            <div class="oauth-switch-knob"></div>
                        </div>
                    </div>

                    <div class="oauth-switch-item">
                        <div class="oauth-switch-info">
                            <div class="oauth-switch-label">实时数据更新</div>
                            <div class="oauth-switch-desc">启用30秒自动刷新统计数据</div>
                        </div>
                        <div class="oauth-switch ${settings.enableRealTimeStats ? 'active' : ''}" data-setting="enableRealTimeStats">
                            <div class="oauth-switch-knob"></div>
                        </div>
                    </div>

                    <div style="margin-top: 12px; padding: 12px; background: rgba(255, 193, 7, 0.1); border-radius: 8px; border-left: 4px solid #ffc107;">
                        <div style="font-size: 12px; color: #856404; font-weight: 600;">ℹ️ 功能说明</div>
                        <div style="font-size: 11px; color: #856404; margin-top: 4px;">
                            此版本已移除所有自动点击功能,专注于数据统计和UI美化。需要手动点击"允许"或"拒绝"按钮。
                        </div>
                    </div>
                </div>
            `;
        }

        generateAdvancedSettingsHTML() {
            const settings = this.settings;
            const isDark = Utils.isDarkMode();
            const uiTheme = Utils.getCurrentThemeColors(this.currentUITheme);

            return `
                <div class="oauth-section">
                    <div class="oauth-section-title">
                        <span>🔧</span>
                        <span>高级设置</span>
                    </div>
                    <div class="oauth-switch-item">
                        <div class="oauth-switch-info">
                            <div class="oauth-switch-label">自动隐藏面板</div>
                            <div class="oauth-switch-desc">点击外部区域自动关闭面板</div>
                        </div>
                        <div class="oauth-switch ${settings.autoHidePanel ? 'active' : ''}" data-setting="autoHidePanel">
                            <div class="oauth-switch-knob"></div>
                        </div>
                    </div>
                    <div class="oauth-switch-item">
                        <div class="oauth-switch-info">
                            <div class="oauth-switch-label">显示图表统计</div>
                            <div class="oauth-switch-desc">显示最近7天登录(不可用)趋势条形图</div>
                        </div>
                        <div class="oauth-switch ${settings.showChartStats ? 'active' : ''}" data-setting="showChartStats">
                            <div class="oauth-switch-knob"></div>
                        </div>
                    </div>
                    <div class="oauth-switch-item">
                        <div class="oauth-switch-info">
                            <div class="oauth-switch-label">显示小时统计</div>
                            <div class="oauth-switch-desc">显示今日24小时登录(不可用)分布图</div>
                        </div>
                        <div class="oauth-switch ${settings.showHourlyChart ? 'active' : ''}" data-setting="showHourlyChart">
                            <div class="oauth-switch-knob"></div>
                        </div>
                    </div>
                    <div class="oauth-switch-item">
                        <div class="oauth-switch-info">
                            <div class="oauth-switch-label">显示网站统计</div>
                            <div class="oauth-switch-desc">显示各网站授权次数排行</div>
                        </div>
                        <div class="oauth-switch ${settings.showWebsiteStats ? 'active' : ''}" data-setting="showWebsiteStats">
                            <div class="oauth-switch-knob"></div>
                        </div>
                    </div>
                    <div class="oauth-switch-item">
                        <div class="oauth-switch-info">
                            <div class="oauth-switch-label">调试模式</div>
                            <div class="oauth-switch-desc">在控制台显示详细运行日志</div>
                        </div>
                        <div class="oauth-switch ${settings.enableDebugMode ? 'active' : ''}" data-setting="enableDebugMode">
                            <div class="oauth-switch-knob"></div>
                        </div>
                    </div>
                    <div style="margin-top: 12px;">
                        <label style="font-size: 12px; color: ${uiTheme.textMuted};">颜色主题</label>
                        <select class="oauth-select" id="themeSelect">
                            <option value="light" ${settings.theme === 'light' ? 'selected' : ''}>浅色主题</option>
                            <option value="dark" ${settings.theme === 'dark' ? 'selected' : ''}>深色主题</option>
                            <option value="auto" ${settings.theme === 'auto' ? 'selected' : ''}>自动切换</option>
                        </select>
                    </div>
                    <div style="margin-top: 8px;">
                        <label style="font-size: 12px; color: ${uiTheme.textMuted};">面板位置</label>
                        <select class="oauth-select" id="positionSelect">
                            <option value="top-right" ${settings.panelPosition === 'top-right' ? 'selected' : ''}>右上角</option>
                            <option value="top-left" ${settings.panelPosition === 'top-left' ? 'selected' : ''}>左上角</option>
                            <option value="bottom-right" ${settings.panelPosition === 'bottom-right' ? 'selected' : ''}>右下角</option>
                            <option value="bottom-left" ${settings.panelPosition === 'bottom-left' ? 'selected' : ''}>左下角</option>
                        </select>
                    </div>
                    <div style="margin-top: 8px; font-size: 11px; color: ${uiTheme.textMuted}; text-align: center;">
                        当前模式:${isDark ? '🌙 深色模式' : '☀️ 浅色模式'} | 界面:${CONFIG.uiThemes[this.currentUITheme].name}
                    </div>
                </div>
            `;
        }

        generateStatsHTML() {
            const stats = this.storage.getStats();
            const history = this.storage.getHistory();
            const isOAuth = this.isOAuthPage();
            const uiTheme = Utils.getCurrentThemeColors(this.currentUITheme);

            let chartsHTML = '';

            if (this.settings.showChartStats) {
                const timeSeriesData = Utils.generateTimeSeriesData(history);
                const chartBars = Utils.generateBarChart(timeSeriesData, {
                    maxHeight: 80,
                    barColor: uiTheme.accent,
                    showValues: true,
                    className: 'oauth-chart-bar'
                });

                chartsHTML += `
                    <div class="oauth-chart-container">
                        <div class="oauth-chart-title">📈 最近7天登录(不可用)统计</div>
                        <div class="oauth-chart-bars">
                            ${chartBars}
                        </div>
                    </div>
                `;
            }

            if (this.settings.showHourlyChart) {
                const hourlyData = Utils.generateHourlyData(history);
                const hourlyBars = Utils.generateBarChart(hourlyData, {
                    maxHeight: 60,
                    barColor: '#8b5cf6',
                    showValues: true,
                    className: 'oauth-chart-bar'
                });

                chartsHTML += `
                    <div class="oauth-chart-container">
                        <div class="oauth-chart-title">🕐 今日小时分布</div>
                        <div class="oauth-chart-bars">
                            ${hourlyBars}
                        </div>
                    </div>
                `;
            }

            if (this.settings.showWebsiteStats) {
                const websiteData = Utils.generateWebsiteStats(history);
                const websiteBars = Utils.generateBarChart(websiteData, {
                    maxHeight: 70,
                    barColor: '#f59e0b',
                    showValues: true,
                    className: 'oauth-chart-bar'
                });

                chartsHTML += `
                    <div class="oauth-chart-container">
                        <div class="oauth-chart-title">🌍 网站授权排行 (TOP 5)</div>
                        <div class="oauth-chart-bars">
                            ${websiteBars}
                        </div>
                    </div>
                `;
            }

            return `
                <div class="oauth-section">
                    <div class="oauth-section-title">
                        <span>📊</span>
                        <span>使用统计</span>
                        ${this.settings.enableRealTimeStats ? '<span class="oauth-real-time-indicator" title="实时更新"></span>' : ''}
                    </div>
                    <div class="oauth-stat-grid">
                        <div class="oauth-stat-card">
                            <div class="oauth-stat-value">${stats.totalLogins}</div>
                            <div class="oauth-stat-label">总授权次数</div>
                        </div>
                        <div class="oauth-stat-card">
                            <div class="oauth-stat-value">${stats.sessionsCount || 0}</div>
                            <div class="oauth-stat-label">使用会话</div>
                        </div>
                    </div>
                    <div class="oauth-stat-grid">
                        <div class="oauth-stat-card">
                            <div class="oauth-stat-value">${stats.manualClicks || 0}</div>
                            <div class="oauth-stat-label">手动点击</div>
                        </div>
                        <div class="oauth-stat-card">
                            <div class="oauth-stat-value">${stats.declineCount || 0}</div>
                            <div class="oauth-stat-label">拒绝次数</div>
                        </div>
                    </div>
                    ${chartsHTML}
                    ${isOAuth ? '<div style="text-align: center; margin-top: 8px; color: ' + uiTheme.textMuted + '; font-size: 11px;">🔐 当前页面:OAuth授权模式</div>' : '<div style="text-align: center; margin-top: 8px; color: ' + uiTheme.textMuted + '; font-size: 11px;">🏠 当前页面:主页面模式</div>'}
                </div>
            `;
        }

        generateHistoryHTML() {
            const history = this.storage.getHistory().slice(0, 6);
            let historyHTML = '';

            if (history.length === 0) {
                historyHTML = '<div class="oauth-empty">📋 暂无授权记录<br><small>启用"保存登录(不可用)记录"后将显示历史</small></div>';
            } else {
                historyHTML = history.map(record => `
                    <div class="oauth-history-item">
                        <div class="oauth-history-title">
                            ${record.system || '未知系统'}
                            <span class="oauth-history-badge manual">手动</span>
                        </div>
                        <div class="oauth-history-detail">🌍 网站: ${record.website || '未知网站'}</div>
                        <div class="oauth-history-detail">👤 用户: ${record.user?.name || '未知'} ${record.user?.level ? `(${record.user.level}级)` : ''}</div>
                        <div class="oauth-history-detail">⚡ 操作: ${record.action || '未知操作'}</div>
                        <div class="oauth-history-time">⏰ ${Utils.formatDate(record.timestamp)}</div>
                    </div>
                `).join('');
            }

            return `
                <div class="oauth-section">
                    <div class="oauth-section-title">
                        <span>📋</span>
                        <span>最近记录</span>
                    </div>
                    ${historyHTML}
                    ${history.length > 0 ? `
                        <div style="text-align: center; margin-top: 12px;">
                            <button class="oauth-btn" id="viewAllHistory">📋 查看全部记录 (${this.storage.getHistory().length})</button>
                        </div>
                    ` : ''}
                </div>
            `;
        }

        generateToolsHTML() {
            const dataSize = Utils.formatBytes(this.storage.calculateDataSize());
            const stats = this.storage.getStats();
            const installDays = stats.installDate ?
                  Math.floor((new Date() - new Date(stats.installDate)) / (1000 * 60 * 60 * 24)) : 0;
            const isDark = Utils.isDarkMode();

            return `
                <div class="oauth-section">
                    <div class="oauth-section-title">
                        <span>🛠️</span>
                        <span>工具箱</span>
                    </div>
                    <div style="margin-bottom: 12px;">
                        <button class="oauth-btn primary" id="exportData">💾 导出数据</button>
                        <button class="oauth-btn" id="importData">📂 导入数据</button>
                        <button class="oauth-btn" id="backupData">💿 备份数据</button>
                        <input type="file" id="importFile" accept=".json" style="display: none;">
                    </div>
                    <div style="margin-bottom: 12px;">
                        <button class="oauth-btn" id="clearHistory">🗑️ 清空记录</button>
                        <button class="oauth-btn danger" id="resetSettings">⚠️ 重置设置</button>
                        <button class="oauth-btn" id="testNotification">🔔 测试通知</button>
                    </div>
                    <div style="margin-bottom: 12px;">
                        <button class="oauth-btn" id="showHelp">❓ 显示帮助</button>
                        <button class="oauth-btn" id="aboutScript">ℹ️ 关于脚本</button>
                        <button class="oauth-btn" id="checkThemeSupport">🎨 主题检测</button>
                    </div>
                    <div style="text-align: center; font-size: 10px; color: ${Utils.getCurrentThemeColors(this.currentUITheme).textMuted}; line-height: 1.4;">
                        📊 数据大小: ${dataSize}<br>
                        🎨 当前主题: ${CONFIG.uiThemes[this.currentUITheme].name} (${isDark ? '深色' : '浅色'})<br>
                        📅 使用天数: ${installDays}天 | 版本: v${CONFIG.version}
                    </div>
                </div>
            `;
        }

        bindEvents() {
            const trigger = this.ui.querySelector('#oauthTrigger');

            trigger.addEventListener('click', (e) => {
                e.stopPropagation();
                this.togglePanel();
            });

            this.bindContentEvents();

            document.addEventListener('click', (e) => {
                if (!this.ui.contains(e.target) && this.isVisible) {
                    if (this.settings.autoHidePanel) {
                        this.hidePanel();
                    }
                }
            });

            // 监听系统主题变化
            window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
                if (this.settings.theme === 'auto') {
                    this.recreateUI();
                }
            });
        }

        bindContentEvents() {
            const themeOptions = this.ui.querySelectorAll('.oauth-ui-theme-option');
            themeOptions.forEach(option => {
                option.addEventListener('click', (e) => {
                    const theme = e.currentTarget.dataset.theme;
                    this.changeUITheme(theme);
                });
            });

            const switches = this.ui.querySelectorAll('.oauth-switch');
            switches.forEach(switchEl => {
                switchEl.addEventListener('click', (e) => {
                    const setting = e.currentTarget.dataset.setting;
                    const isActive = e.currentTarget.classList.contains('active');
                    this.toggleSetting(setting, !isActive);
                });
            });

            const themeSelect = this.ui.querySelector('#themeSelect');
            if (themeSelect) {
                themeSelect.addEventListener('change', (e) => {
                    this.updateSetting('theme', e.target.value);
                    this.applyTheme();
                    this.recreateUI();
                });
            }

            const positionSelect = this.ui.querySelector('#positionSelect');
            if (positionSelect) {
                positionSelect.addEventListener('change', (e) => {
                    this.updateSetting('panelPosition', e.target.value);
                    this.updatePosition();
                });
            }

            this.bindButtonEvents();
        }

        bindButtonEvents() {
            const buttons = {
                exportData: () => this.exportData(),
                importData: () => this.ui.querySelector('#importFile').click(),
                backupData: () => this.backupData(),
                clearHistory: () => this.clearHistory(),
                resetSettings: () => this.resetSettings(),
                showHelp: () => this.showHelp(),
                aboutScript: () => this.showAbout(),
                toggleUITheme: () => this.toggleUITheme(),
                toggleTheme: () => this.toggleTheme(),
                refreshUI: () => this.recreateUI(),
                viewAllHistory: () => this.showAllHistory(),
                testNotification: () => this.testNotification(),
                checkThemeSupport: () => this.checkThemeSupport()
            };

            Object.entries(buttons).forEach(([id, handler]) => {
                const btn = this.ui.querySelector(`#${id}`);
                if (btn) {
                    btn.addEventListener('click', handler);
                }
            });

            const importFile = this.ui.querySelector('#importFile');
            if (importFile) {
                importFile.addEventListener('change', (e) => {
                    this.importData(e.target.files[0]);
                    e.target.value = '';
                });
            }
        }

        changeUITheme(themeKey) {
            this.currentUITheme = themeKey;
            this.updateSetting('uiTheme', themeKey);
            this.recreateUI();
            this.showMessage(`UI主题已切换为: ${CONFIG.uiThemes[themeKey].name}`);
        }

        toggleUITheme() {
            const themes = Object.keys(CONFIG.uiThemes);
            const currentIndex = themes.indexOf(this.currentUITheme);
            const nextTheme = themes[(currentIndex + 1) % themes.length];
            this.changeUITheme(nextTheme);
        }

        recreateUI() {
            if (this.ui) {
                this.ui.remove();
            }

            if (this.realTimeTimer) {
                clearInterval(this.realTimeTimer);
            }

            setTimeout(() => {
                this.addStyles();
                this.createUI();
                this.bindEvents();
                this.applyTheme();
                this.startRealTimeUpdates();
            }, 100);
        }

        togglePanel() {
            this.isVisible = !this.isVisible;
            const trigger = this.ui.querySelector('#oauthTrigger');
            const panel = this.ui.querySelector('#oauthPanel');

            trigger.classList.toggle('active', this.isVisible);
            panel.classList.toggle('show', this.isVisible);

            if (this.isVisible) {
                this.refreshUI();
            }
        }

        hidePanel() {
            if (this.isVisible) {
                this.togglePanel();
            }
        }

        toggleSetting(key, value) {
            Utils.log(`切换设置: ${key} = ${value}`);

            this.updateSetting(key, value);

            const switchEl = this.ui.querySelector(`[data-setting="${key}"]`);
            if (switchEl) {
                switchEl.classList.toggle('active', value);
            }

            if (window.oauthHelper) {
                window.oauthHelper.updateSettings();
            }

            if (['enablePageStyling', 'showChartStats', 'showHourlyChart', 'showWebsiteStats', 'enableRealTimeStats'].includes(key)) {
                this.recreateUI();
            }

            this.showMessage(`${this.getSettingLabel(key)} ${value ? '已开启' : '已关闭'}`);
        }

        updateSetting(key, value) {
            this.settings[key] = value;
            this.storage.updateSetting(key, value);
        }

        getSettingLabel(key) {
            const labels = {
                saveLoginHistory: '保存登录(不可用)记录',
                showNotifications: '显示通知',
                autoHidePanel: '自动隐藏面板',
                enablePageStyling: 'UI优化',
                enableDebugMode: '调试模式',
                showChartStats: '图表统计',
                showHourlyChart: '小时统计',
                showWebsiteStats: '网站统计',
                enableRealTimeStats: '实时数据更新'
            };
            return labels[key] || key;
        }

        applyTheme() {
            const theme = this.settings.theme;
            let actualTheme = theme;

            if (theme === 'auto') {
                actualTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
            }

            this.ui.classList.toggle('dark', actualTheme === 'dark');
            this.currentTheme = actualTheme;
        }

        toggleTheme() {
            const themes = ['light', 'dark', 'auto'];
            const currentIndex = themes.indexOf(this.settings.theme);
            const nextTheme = themes[(currentIndex + 1) % themes.length];

            this.updateSetting('theme', nextTheme);
            this.recreateUI();

            const themeNames = { light: '浅色', dark: '深色', auto: '自动' };
            this.showMessage(`主题已切换为: ${themeNames[nextTheme]}`);
        }

        updatePosition() {
            if (this.ui) {
                this.ui.remove();
            }

            setTimeout(() => {
                this.createUI();
                this.bindEvents();
                this.applyTheme();
            }, 100);
        }

        exportData() {
            const data = this.storage.exportAllData();
            const filename = `oauth-helper-backup-${new Date().toISOString().split('T')[0]}.json`;
            Utils.exportToJSON(data, filename);
            this.showMessage('📊 数据导出成功');
        }

        backupData() {
            const data = this.storage.exportAllData();
            const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
            const filename = `oauth-helper-backup-${timestamp}.json`;
            Utils.exportToJSON(data, filename);
            this.showMessage('💿 数据备份完成');
        }

        async importData(file) {
            if (!file) return;

            try {
                const data = await Utils.importFromJSON(file);
                if (confirm('确定要导入数据吗?这将覆盖当前设置和记录。')) {
                    if (this.storage.importAllData(data)) {
                        this.settings = this.storage.getSettings();
                        this.recreateUI();
                        this.showMessage('📂 数据导入成功,请刷新页面');
                    } else {
                        this.showMessage('❌ 数据导入失败');
                    }
                }
            } catch (error) {
                Utils.log('导入数据失败: ' + error.message, 'error');
                this.showMessage('❌ 数据格式错误,导入失败');
            }
        }

        clearHistory() {
            if (confirm('确定要清空所有历史记录吗?此操作不可恢复。')) {
                this.storage.clearHistory();
                this.refreshUI();
                this.showMessage('🗑️ 历史记录已清空');
            }
        }

        resetSettings() {
            if (confirm('确定要重置所有设置吗?此操作不可恢复。')) {
                this.storage.set('settings', CONFIG.defaultSettings);
                this.settings = CONFIG.defaultSettings;
                this.currentUITheme = 'minimal-white';
                this.recreateUI();
                this.showMessage('⚠️ 设置已重置为默认值');
            }
        }

        testNotification() {
            if (typeof GM_notification === 'function') {
                GM_notification({
                    title: '🏆 OAuth助手',
                    text: '通知测试成功!功能正常工作。',
                    timeout: this.settings.notificationDuration
                });
                this.showMessage('🔔 通知测试已发送');
            } else {
                this.showMessage('❌ 通知功能不可用');
            }
        }

        checkThemeSupport() {
            const isDark = Utils.isDarkMode();
            const supportInfo = {
                当前系统主题: isDark ? '深色模式' : '浅色模式',
                脚本主题设置: this.settings.theme,
                UI主题: CONFIG.uiThemes[this.currentUITheme].name,
                CSS变量支持: CSS.supports('color', 'var(--test)'),
                深色模式媒体查询: window.matchMedia('(prefers-color-scheme: dark)').matches
            };

            const infoText = Object.entries(supportInfo)
            .map(([key, value]) => `${key}: ${value}`)
            .join('\n');

            alert(`🎨 主题支持检测结果:\n\n${infoText}`);
        }

        showHelp() {
            const uiTheme = Utils.getCurrentThemeColors(this.currentUITheme);
            const helpContent = `
                <div style="max-width: 500px; line-height: 1.6;">
                    <h3 style="margin-bottom: 16px; color: ${uiTheme.text};">🏆 OAuth助手使用指南</h3>

                    <div style="margin-bottom: 16px;">
                        <h4 style="color: ${uiTheme.accent};">🎨 主题切换</h4>
                        <p>• <strong>简约白</strong>:极简清爽的白色设计,支持深浅色自适应</p>
                        <p>• <strong>紫色渐变</strong>:基于OAuth页面的紫色渐变,深浅色均优化</p>
                        <p>• <strong>彩虹华丽</strong>:炫酷多彩的动态效果,支持深色模式</p>
                    </div>

                    <div style="margin-bottom: 16px;">
                        <h4 style="color: ${uiTheme.accent};">⚙️ 主要功能</h4>
                        <p>• <strong>手动点击统计</strong>:记录所有手动授权操作</p>
                        <p>• <strong>历史记录</strong>:保存所有授权操作记录</p>
                        <p>• <strong>条形图统计</strong>:可视化显示使用数据</p>
                        <p>• <strong>实时更新</strong>:30秒自动刷新统计数据</p>
                        <p>• <strong>数据导入导出</strong>:备份和恢复个人数据</p>
                    </div>

                    <div style="margin-bottom: 16px;">
                        <h4 style="color: ${uiTheme.accent};">📊 统计图表</h4>
                        <p>• <strong>7天趋势</strong>:显示最近一周的登录(不可用)分布</p>
                        <p>• <strong>小时分布</strong>:显示今日24小时使用情况</p>
                        <p>• <strong>网站排行</strong>:显示最常授权的网站TOP5</p>
                    </div>

                    <div style="margin-bottom: 16px;">
                        <h4 style="color: ${uiTheme.accent};">🛠️ 使用技巧</h4>
                        <p>• 点击面板外部可快速关闭设置面板</p>
                        <p>• 启用"自动隐藏面板"提升使用体验</p>
                        <p>• 定期导出数据做备份,防止数据丢失</p>
                        <p>• 启用调试模式可查看详细运行日志</p>
                        <p>• 支持系统深色模式自动切换</p>
                    </div>

                    <div style="text-align: center; margin-top: 20px;">
                        <button class="oauth-btn primary" onclick="this.parentElement.parentElement.parentElement.remove()">关闭帮助</button>
                    </div>
                </div>
            `;

            this.showModal('帮助信息', helpContent);
        }

        showAbout() {
            const stats = this.storage.getStats();
            const isDark = Utils.isDarkMode();
            const uiTheme = Utils.getCurrentThemeColors(this.currentUITheme);

            const aboutContent = `
                <div style="max-width: 450px; text-align: center; line-height: 1.6;">
                    <div style="margin-bottom: 20px;">
                        <h2 style="color: ${uiTheme.text}; margin: 0;">🏆 OAuth助手</h2>
                        <p style="color: ${uiTheme.textMuted}; margin: 8px 0;">专为LINUX DO OAuth设计的统计助手(无自动点击)</p>
                    </div>

                    <div style="margin-bottom: 20px; padding: 16px; background: ${uiTheme.cardBg}; border-radius: 12px; border: 1px solid ${uiTheme.panelBorder};">
                        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px; font-size: 13px;">
                            <div><strong>版本</strong><br>${CONFIG.version}</div>
                            <div><strong>主题</strong><br>${CONFIG.uiThemes[this.currentUITheme].name}</div>
                            <div><strong>模式</strong><br>${isDark ? '深色' : '浅色'}</div>
                            <div><strong>总使用</strong><br>${stats.totalLogins}次</div>
                        </div>
                    </div>

                    <div style="margin-bottom: 20px;">
                        <h4 style="color: ${uiTheme.accent};">✨ 特色功能</h4>
                        <p style="font-size: 13px; color: ${uiTheme.textMuted};">
                            🎨 三种精美UI主题,支持深浅色<br>
                            📊 多维度条形图统计<br>
                            📋 完整历史记录<br>
                            🛠️ 数据导入导出<br>
                            🔧 丰富自定义选项<br>
                            ⚡ 实时数据更新<br>
                            🚫 无自动点击功能
                        </p>
                    </div>

                    <div style="margin-bottom: 20px;">
                        <h4 style="color: ${uiTheme.accent};">💡 设计理念</h4>
                        <p style="font-size: 13px; color: ${uiTheme.textMuted};">
                            简洁而不简单,功能丰富而不臃肿<br>
                            所有功能均集成在设置面板中<br>
                            专注于数据统计和UI美化<br>
                            可视化统计,数据一目了然<br>
                            完美支持系统深色模式
                        </p>
                    </div>

                    <div style="margin-top: 20px;">
                        <button class="oauth-btn primary" onclick="window.open('${CONFIG.github}', '_blank')">🌟 GitHub</button>
                        <button class="oauth-btn" onclick="this.parentElement.parentElement.parentElement.remove()">关闭</button>
                    </div>
                </div>
            `;

            this.showModal('关于脚本', aboutContent);
        }

        showAllHistory() {
            const history = this.storage.getHistory();
            const uiTheme = Utils.getCurrentThemeColors(this.currentUITheme);

            if (history.length === 0) {
                this.showMessage('📋 暂无历史记录');
                return;
            }

            const historyContent = `
                <div style="max-width: 600px; max-height: 500px; overflow-y: auto;">
                    <h3 style="margin-bottom: 16px; color: ${uiTheme.text};">📋 全部历史记录 (${history.length}条)</h3>
                    <div style="margin-bottom: 16px;">
                        <button class="oauth-btn danger" onclick="if(confirm('确定清空所有记录?')) { window.oauthHelper.ui.clearHistory(); this.parentElement.parentElement.parentElement.remove(); }">🗑️ 清空记录</button>
                        <button class="oauth-btn" onclick="window.oauthHelper.ui.exportData()">💾 导出记录</button>
                    </div>
                    <div style="border: 1px solid ${uiTheme.panelBorder}; border-radius: 8px; overflow: hidden;">
                        ${history.map((record, index) => `
                            <div style="padding: 12px; border-bottom: 1px solid ${uiTheme.panelBorder}; ${index % 2 === 0 ? `background: ${uiTheme.cardBg};` : ''}">
                                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px;">
                                    <strong style="color: ${uiTheme.text};">${record.system || '未知系统'}</strong>
                                    <span class="oauth-history-badge manual" style="font-size: 10px; padding: 2px 6px; border-radius: 8px; font-weight: bold;">手动</span>
                                </div>
                                <div style="font-size: 12px; color: ${uiTheme.textMuted}; line-height: 1.4;">
                                    🌍 ${record.website || '未知网站'}<br>
                                    👤 ${record.user?.name || '未知'} ${record.user?.level ? `(${record.user.level}级)` : ''}<br>
                                    ⚡ ${record.action || '未知操作'}<br>
                                    ⏰ ${Utils.formatDate(record.timestamp)}
                                </div>
                            </div>
                        `).join('')}
                    </div>
                    <div style="text-align: center; margin-top: 16px;">
                        <button class="oauth-btn primary" onclick="this.parentElement.parentElement.remove()">关闭</button>
                    </div>
                </div>
            `;

            this.showModal('历史记录', historyContent);
        }

        showModal(title, content) {
            const existingModal = document.querySelector('.oauth-modal');
            if (existingModal) {
                existingModal.remove();
            }

            const uiTheme = Utils.getCurrentThemeColors(this.currentUITheme);
            const modal = document.createElement('div');
            modal.className = 'oauth-modal';
            modal.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(0,0,0,0.5);
                display: flex;
                align-items: center;
                justify-content: center;
                z-index: 99999;
                backdrop-filter: blur(5px);
            `;

            modal.innerHTML = `
                <div style="
                    background: ${uiTheme.panelBg};
                    border: 2px solid ${uiTheme.panelBorder};
                    border-radius: 16px;
                    padding: 24px;
                    margin: 20px;
                    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
                    backdrop-filter: blur(10px);
                    max-width: 90vw;
                    max-height: 90vh;
                    overflow-y: auto;
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
                ">
                    ${content}
                </div>
            `;

            modal.addEventListener('click', (e) => {
                if (e.target === modal) {
                    modal.remove();
                }
            });

            document.body.appendChild(modal);
        }

        showMessage(message, type = 'info', duration = 3000) {
            const messageEl = document.createElement('div');
            messageEl.style.cssText = `
                position: fixed;
                top: 80px;
                right: 20px;
                background: ${type === 'error' ? '#fee2e2' : type === 'warning' ? '#fef3c7' : '#dcfce7'};
                color: ${type === 'error' ? '#dc2626' : type === 'warning' ? '#d97706' : '#16a34a'};
                padding: 12px 16px;
                border-radius: 8px;
                box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
                z-index: 99999;
                font-size: 14px;
                font-weight: 600;
                border: 1px solid ${type === 'error' ? '#fecaca' : type === 'warning' ? '#fed7aa' : '#bbf7d0'};
                backdrop-filter: blur(5px);
                animation: slideIn 0.3s ease-out;
            `;

            messageEl.textContent = message;
            document.body.appendChild(messageEl);

            setTimeout(() => {
                messageEl.style.opacity = '0';
                messageEl.style.transform = 'translateX(100%)';
                setTimeout(() => messageEl.remove(), 300);
            }, duration);
        }

        refreshUI() {
            if (this.isVisible) {
                const content = this.ui.querySelector('.oauth-content');
                if (content) {
                    content.innerHTML = this.generateContent();
                    this.bindContentEvents();
                }
            }
        }

        updateSettings(newSettings) {
            this.settings = { ...this.settings, ...newSettings };
            this.refreshUI();
        }

        destroy() {
            if (this.realTimeTimer) {
                clearInterval(this.realTimeTimer);
            }
            if (this.ui) {
                this.ui.remove();
            }
        }
    }

    // ================== 主入口 ==================
    class OAuthHelper {
        constructor() {
            this.storage = new Storage();
            this.settings = this.storage.getSettings();
            this.ui = null;
            this.clickTracker = null;
            this.sessionStartTime = Date.now();

            Utils.log('OAuth助手初始化中...');
            this.init();
        }

        init() {
            this.storage.updateStats('sessionsCount');
            this.ui = new UIManager(this.storage);
            this.clickTracker = new ClickTracker(this.storage, this.settings);
            this.bindUnloadEvents();

            Utils.log('OAuth助手初始化完成');
            this.showWelcomeMessage();
        }

        showWelcomeMessage() {
            const stats = this.storage.getStats();
            const isFirstRun = stats.totalLogins === 0 && stats.sessionsCount <= 1;

            if (isFirstRun) {
                setTimeout(() => {
                    this.ui.showMessage('🎉 欢迎使用OAuth助手!点击右上角图标开始使用', 'info', 5000);
                }, 1000);
            }
        }

        updateSettings() {
            this.settings = this.storage.getSettings();

            if (this.clickTracker) {
                this.clickTracker.updateSettings(this.settings);
            }

            if (this.ui) {
                this.ui.updateSettings(this.settings);
            }

            Utils.log('设置已更新');
        }

        bindUnloadEvents() {
            window.addEventListener('beforeunload', () => {
                const usageTime = Date.now() - this.sessionStartTime;
                this.storage.updateStats('totalUsageTime', Math.floor(usageTime / 1000));
            });

            document.addEventListener('visibilitychange', () => {
                if (document.hidden) {
                    const usageTime = Date.now() - this.sessionStartTime;
                    this.storage.updateStats('totalUsageTime', Math.floor(usageTime / 1000));
                } else {
                    this.sessionStartTime = Date.now();
                }
            });
        }

        destroy() {
            if (this.ui) {
                this.ui.destroy();
            }
        }
    }

    // ================== 启动脚本 ==================
    function startScript() {
        Utils.log('开始启动OAuth助手...');

        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', () => {
                window.oauthHelper = new OAuthHelper();
            });
        } else {
            window.oauthHelper = new OAuthHelper();
        }
    }

    startScript();

    // 注册(不可用)GM菜单命令
    if (typeof GM_registerMenuCommand === 'function') {
        GM_registerMenuCommand('🏆 打开OAuth助手', () => {
            if (window.oauthHelper && window.oauthHelper.ui) {
                window.oauthHelper.ui.togglePanel();
            }
        });

        GM_registerMenuCommand('📊 导出数据', () => {
            if (window.oauthHelper && window.oauthHelper.ui) {
                window.oauthHelper.ui.exportData();
            }
        });

        GM_registerMenuCommand('🎨 切换主题', () => {
            if (window.oauthHelper && window.oauthHelper.ui) {
                window.oauthHelper.ui.toggleUITheme();
            }
        });

        GM_registerMenuCommand('🌓 切换颜色模式', () => {
            if (window.oauthHelper && window.oauthHelper.ui) {
                window.oauthHelper.ui.toggleTheme();
            }
        });

        GM_registerMenuCommand('❓ 显示帮助', () => {
            if (window.oauthHelper && window.oauthHelper.ui) {
                window.oauthHelper.ui.showHelp();
            }
        });

        GM_registerMenuCommand('ℹ️ 关于脚本', () => {
            if (window.oauthHelper && window.oauthHelper.ui) {
                window.oauthHelper.ui.showAbout();
            }
        });
    }

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址