Greasy Fork

Greasy Fork is available in English.

TMDB 影视资源查询

获取页面影视名称,查询TMDB ID并获取资源链接

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         TMDB 影视资源查询
// @namespace    http://tampermonkey.net/
// @version      0.0.5
// @description  获取页面影视名称,查询TMDB ID并获取资源链接
// @author       goukey
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @connect      api.themoviedb.org
// @connect      api.nullbr.com
// @license MIT
// ==/UserScript==

(function () {
    'use strict';

    // 用户设置,使用GM_getValue获取存储的设置,如果没有则使用默认值
    const userSettings = {
        enableSelectionSearch: GM_getValue('enableSelectionSearch', true),
        enableTgSearch: GM_getValue('enableTgSearch', true),
        tmdbApiKey: GM_getValue('tmdbApiKey', ''),
        appId: GM_getValue('appId', ''),
        apiKey: GM_getValue('apiKey', '')
    };

    // 获取API密钥(兼容旧配置)
    function getTmdbApiKey() {
        return userSettings.tmdbApiKey || '';
    }
    function getAppId() {
        return userSettings.appId || '';
    }
    function getApiKey() {
        return userSettings.apiKey || '';
    }

    // 保存设置
    function saveSettings() {
        GM_setValue('enableSelectionSearch', userSettings.enableSelectionSearch);
        GM_setValue('enableTgSearch', userSettings.enableTgSearch);
        GM_setValue('tmdbApiKey', userSettings.tmdbApiKey);
        GM_setValue('appId', userSettings.appId);
        GM_setValue('apiKey', userSettings.apiKey);
    }

    // 添加样式
    GM_addStyle(`
        :root {
            --primary-color: #3b82f6;
            --primary-hover: #2563eb;
            --bg-color: #ffffff;
            --text-color: #1f2937;
            --text-secondary: #6b7280;
            --border-color: #e5e7eb;
            --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
            --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
            --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
            --radius-md: 0.5rem;
            --radius-lg: 0.75rem;
        }

        #tmdb-magnet-container {
            position: fixed;
            top: 20px;
            right: 20px;
            width: 380px;
            background-color: var(--bg-color);
            border-radius: var(--radius-lg);
            box-shadow: var(--shadow-lg);
            z-index: 10000;
            font-family: 'Inter', system-ui, -apple-system, sans-serif;
            display: none;
            overflow: hidden;
            border: 1px solid var(--border-color);
            transition: all 0.3s ease;
        }

        /* 顶部 Tab 栏 */
        .tmdb-tabs {
            display: flex;
            border-bottom: 1px solid var(--border-color);
            background: #f9fafb;
        }

        .tmdb-tab {
            flex: 1;
            padding: 12px;
            text-align: center;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            color: var(--text-secondary);
            transition: all 0.2s;
            border-bottom: 2px solid transparent;
        }

        .tmdb-tab:hover {
            color: var(--primary-color);
            background: #f3f4f6;
        }

        .tmdb-tab.active {
            color: var(--primary-color);
            border-bottom-color: var(--primary-color);
            background: #fff;
        }

        .tmdb-close-btn {
            position: absolute;
            top: 8px;
            right: 8px;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            cursor: pointer;
            color: #9ca3af;
            font-size: 18px;
            line-height: 1;
            z-index: 10;
        }

        .tmdb-close-btn:hover {
            background: #e5e7eb;
            color: #4b5563;
        }

        /* 内容区域 */
        .tmdb-content-area {
            padding: 16px;
            height: 500px;
            overflow-y: auto;
            display: none;
        }

        .tmdb-content-area.active {
            display: block;
        }

        /* 输入框组 */
        .input-group {
            display: flex;
            gap: 8px;
            margin-bottom: 16px;
        }

        #tmdb-magnet-input {
            flex: 1;
            padding: 8px 12px;
            border: 1px solid var(--border-color);
            border-radius: var(--radius-md);
            font-size: 14px;
            outline: none;
            transition: border-color 0.2s;
        }

        #tmdb-magnet-input:focus {
            border-color: var(--primary-color);
            box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
        }

        .search-btn {
            padding: 8px 16px;
            background-color: var(--primary-color);
            color: white;
            border: none;
            border-radius: var(--radius-md);
            font-size: 14px;
            font-weight: 500;
            cursor: pointer;
            transition: background-color 0.2s;
        }

        .search-btn:hover {
            background-color: var(--primary-hover);
        }

        /* 筛选按钮 */
        .filter-group {
            display: flex;
            gap: 8px;
            margin-bottom: 12px;
            flex-wrap: wrap;
        }

        .filter-btn {
            padding: 4px 10px;
            background: #f3f4f6;
            border: 1px solid transparent;
            border-radius: 100px;
            font-size: 12px;
            color: var(--text-secondary);
            cursor: pointer;
            transition: all 0.2s;
        }

        .filter-btn:hover {
            background: #e5e7eb;
            color: var(--text-color);
        }

        .filter-btn.active {
            background: #eff6ff;
            color: var(--primary-color);
            border-color: var(--primary-color);
        }

        /* 结果列表 */
        .media-item {
            background: white;
            border: 1px solid var(--border-color);
            border-radius: var(--radius-md);
            padding: 12px;
            margin-bottom: 12px;
            display: flex;
            gap: 12px;
            transition: transform 0.2s, box-shadow 0.2s;
        }

        .media-item:hover {
            transform: translateY(-2px);
            box-shadow: var(--shadow-md);
            border-color: #bfdbfe;
        }

        .media-poster {
            width: 68px;
            height: 102px;
            border-radius: 4px;
            object-fit: cover;
            background-color: #f3f4f6;
            flex-shrink: 0;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }

        .media-details {
            flex: 1;
            min-width: 0;
        }

        .media-title {
            font-size: 15px;
            font-weight: 600;
            color: var(--text-color);
            margin-bottom: 6px;
            display: inline-block;
            text-decoration: none;
        }

        .media-title:hover {
            color: var(--primary-color);
        }

        .media-info {
            display: flex;
            gap: 6px;
            flex-wrap: wrap;
            margin-bottom: 10px;
        }

        .media-tag {
            font-size: 11px;
            padding: 2px 6px;
            border-radius: 4px;
            background: #f3f4f6;
            color: var(--text-secondary);
        }

        .media-tag.movie { background: #e0f2fe; color: #0284c7; }
        .media-tag.tv { background: #f0f9ff; color: #0369a1; }
        .media-tag.tg { background: #e1f5fe; color: #0288d1; }
        .media-tag.link { 
            cursor: pointer;
            text-decoration: none;
            transition: all 0.2s;
        }
        .media-tag.link { 
            cursor: pointer;
            text-decoration: none;
            transition: all 0.2s;
        }
        .media-tag.link:hover {
            background: var(--primary-color);
            color: white;
        }

        /* 链接列表 */
        .magnet-list {
            border-top: 1px dashed var(--border-color);
            padding-top: 8px;
            margin-top: 8px;
        }

        .magnet-link {
            display: block;
            padding: 8px;
            background: #f9fafb;
            border-radius: var(--radius-md);
            margin-bottom: 6px;
            font-size: 12px;
            text-decoration: none;
            color: var(--text-color);
            transition: all 0.2s;
            border: 1px solid transparent;
        }

        .magnet-link:hover {
            background: #fff;
            border-color: var(--primary-color);
            box-shadow: var(--shadow-sm);
        }

        .magnet-link a {
            color: var(--text-color);
            text-decoration: none;
            font-weight: 500;
            display: block;
            margin-bottom: 2px;
        }

        .magnet-link a:hover {
            color: var(--primary-color);
        }

        .loading, .no-results, .error {
            text-align: center;
            padding: 20px;
            font-size: 13px;
            color: var(--text-secondary);
        }
        
        .error { color: #ef4444; }

        /* 设置页样式 */
        .setting-item {
            margin-bottom: 16px;
        }

        .setting-label {
            font-size: 13px;
            font-weight: 500;
            color: var(--text-color);
            margin-bottom: 6px;
            display: block;
        }

        .setting-input {
            width: 100%;
            padding: 8px 12px;
            border: 1px solid var(--border-color);
            border-radius: var(--radius-md);
            font-size: 13px;
            outline: none;
            box-sizing: border-box;
            transition: border-color 0.2s;
        }

        .setting-input:focus {
            border-color: var(--primary-color);
        }

        .toggle-switch {
            position: relative;
            display: inline-block;
            width: 40px;
            height: 22px;
        }

        .toggle-switch input { opacity: 0; width: 0; height: 0; }

        .toggle-slider {
            position: absolute;
            cursor: pointer;
            top: 0; left: 0; right: 0; bottom: 0;
            background-color: #e5e7eb;
            transition: .4s;
            border-radius: 22px;
        }

        .toggle-slider:before {
            position: absolute;
            content: "";
            height: 16px;
            width: 16px;
            left: 3px;
            bottom: 3px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
            box-shadow: 0 1px 2px rgba(0,0,0,0.1);
        }

        input:checked + .toggle-slider {
            background-color: var(--primary-color);
        }

        input:checked + .toggle-slider:before {
            transform: translateX(18px);
        }

        .save-btn {
            width: 100%;
            padding: 10px;
            background-color: var(--primary-color);
            color: white;
            border: none;
            border-radius: var(--radius-md);
            font-weight: 500;
            cursor: pointer;
            margin-top: 12px;
            transition: opacity 0.2s;
        }

        .save-btn:hover { opacity: 0.9; }

        /* 悬浮球美化 */
        .tmdb-icon {
            position: fixed;
            bottom: 30px;
            right: 30px;
            width: 48px;
            height: 48px;
            background: linear-gradient(135deg, #3b82f6, #2563eb);
            border-radius: 50%;
            display: flex;
            justify-content: center;
            align-items: center;
            color: white;
            font-weight: 700;
            cursor: pointer;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
            z-index: 9998;
            transition: transform 0.2s;
            font-size: 14px;
        }

        .tmdb-icon:hover {
            transform: scale(1.1);
        }
        
        /* 滚动条 */
        .tmdb-content-area::-webkit-scrollbar {
            width: 5px;
        }
        .tmdb-content-area::-webkit-scrollbar-thumb {
            background: #d1d5db;
            border-radius: 10px;
        }
        .tmdb-content-area::-webkit-scrollbar-thumb:hover {
            background: #9ca3af;
        }

        /* TG 搜索按钮 */
        .tg-search-btn {
            display: inline-flex;
            align-items: center;
            gap: 4px;
            padding: 5px 12px;
            background: linear-gradient(135deg, #0088cc, #00aaff);
            color: white;
            border-radius: 6px;
            font-size: 11px;
            cursor: pointer;
            margin-top: 8px;
            border: none;
            transition: all 0.2s;
            font-weight: 500;
            text-decoration: none;
        }
        .tg-search-btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 4px 12px rgba(0, 136, 204, 0.3);
            filter: brightness(1.1);
        }

        /* Toast 提示 */
        .tmdb-toast {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(0, 0, 0, 0.75);
            color: white;
            padding: 10px 20px;
            border-radius: 8px;
            font-size: 14px;
            z-index: 11000;
            pointer-events: none;
            backdrop-filter: blur(4px);
            opacity: 0;
            transition: opacity 0.3s;
        }
        .tmdb-toast.show {
            opacity: 1;
        }
    `);

    // 创建设置项输入框
    function createApiKeyInput(label, key, value, placeholder) {
        const item = document.createElement('div');
        item.style.marginBottom = '12px';

        const labelDiv = document.createElement('div');
        labelDiv.textContent = label;
        labelDiv.style.cssText = 'font-size: 12px; color: #666; margin-bottom: 4px;';

        const input = document.createElement('input');
        input.type = 'text';
        input.value = value || '';
        input.placeholder = placeholder;
        input.style.cssText = 'width: 100%; padding: 8px 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 13px; box-sizing: border-box;';
        input.addEventListener('input', (e) => {
            userSettings[key] = e.target.value.trim();
        });

        item.appendChild(labelDiv);
        item.appendChild(input);
        return item;
    }

    // 创建UI
    function createUI() {
        // 创建主容器
        const container = document.createElement('div');
        container.id = 'tmdb-magnet-container';

        // 1. 关闭按钮
        const closeBtn = document.createElement('div');
        closeBtn.className = 'tmdb-close-btn';
        closeBtn.innerHTML = '×';
        closeBtn.title = '关闭';
        closeBtn.addEventListener('click', () => {
            container.style.display = 'none';
        });
        container.appendChild(closeBtn);

        // 2. Tab 栏
        const tabsContainer = document.createElement('div');
        tabsContainer.className = 'tmdb-tabs';

        const searchTab = document.createElement('div');
        searchTab.className = 'tmdb-tab active';
        searchTab.textContent = '影视搜索';

        const settingsTab = document.createElement('div');
        settingsTab.className = 'tmdb-tab';
        settingsTab.textContent = '配置设置';

        tabsContainer.appendChild(searchTab);
        tabsContainer.appendChild(settingsTab);
        container.appendChild(tabsContainer);

        // 3. 搜索面板
        const searchPanel = document.createElement('div');
        searchPanel.className = 'tmdb-content-area active';
        searchPanel.id = 'tmdb-search-panel';

        // 输入组
        const inputGroup = document.createElement('div');
        inputGroup.className = 'input-group';

        const input = document.createElement('input');
        input.id = 'tmdb-magnet-input';
        input.type = 'text';
        input.placeholder = '输入电影或剧集名称...';

        const searchBtn = document.createElement('button');
        searchBtn.className = 'search-btn';
        searchBtn.textContent = '搜索';

        inputGroup.appendChild(input);
        inputGroup.appendChild(searchBtn);
        searchPanel.appendChild(inputGroup);

        // 资源类型切换
        const sourceGroup = document.createElement('div');
        sourceGroup.className = 'filter-group';

        const sourceTypes = [
            { label: '🌐 115', value: '115' },
            { label: '🧲 磁力', value: 'magnet' },
            { label: '⚡ ED2K', value: 'ed2k' },
            { label: '▶️ 在线', value: 'm3u8' }
        ];

        const sourceBtns = {};
        sourceTypes.forEach(st => {
            const btn = document.createElement('button');
            btn.textContent = st.label;
            btn.className = 'filter-btn';
            if (st.value === '115') btn.classList.add('active');

            btn.addEventListener('click', () => {
                if (currentSource === st.value) return;
                currentSource = st.value;
                Object.values(sourceBtns).forEach(b => b.classList.remove('active'));
                btn.classList.add('active');

                // 重新显示结果
                if (window._tmdbLastResults) {
                    displayResults(window._tmdbLastResults, false);
                }
            });
            sourceBtns[st.value] = btn;
            sourceGroup.appendChild(btn);
        });
        searchPanel.appendChild(sourceGroup);

        // 类型筛选
        const filterGroup = document.createElement('div');
        filterGroup.className = 'filter-group';

        const filterTypes = [
            { label: '全部', value: 'all' },
            { label: '电影', value: 'movie' },
            { label: '剧集', value: 'tv' }
        ];

        const filterBtns = {};
        filterTypes.forEach(ft => {
            const btn = document.createElement('button');
            btn.textContent = ft.label;
            btn.className = 'filter-btn';
            if (ft.value === 'all') btn.classList.add('active');

            btn.addEventListener('click', () => {
                currentFilter = ft.value;
                Object.values(filterBtns).forEach(b => b.classList.remove('active'));
                btn.classList.add('active');

                if (window._tmdbLastResults) {
                    const magnetCache = saveMagnetCache(); // 保存现有磁链
                    displayResults(window._tmdbLastResults, false);
                    restoreMagnetCache(magnetCache); // 恢复磁链
                }
            });
            filterBtns[ft.value] = btn;
            filterGroup.appendChild(btn);
        });
        searchPanel.appendChild(filterGroup);

        // 结果容器
        const resultsContainer = document.createElement('div');
        resultsContainer.id = 'tmdb-magnet-results';
        searchPanel.appendChild(resultsContainer);

        container.appendChild(searchPanel);

        // 4. 设置面板
        const settingsPanel = document.createElement('div');
        settingsPanel.className = 'tmdb-content-area';
        settingsPanel.id = 'tmdb-settings-panel';

        // 选中搜索开关
        const selectionSearchSetting = document.createElement('div');
        selectionSearchSetting.className = 'setting-item';

        const selectionLabel = document.createElement('span');
        selectionLabel.className = 'setting-label';
        selectionLabel.textContent = '启用划词搜索 (选中文字弹出搜索按钮)';
        selectionLabel.style.marginBottom = '8px';
        selectionLabel.style.display = 'inline-block';

        const toggleWrapper = document.createElement('div');
        const selectionToggle = document.createElement('label');
        selectionToggle.className = 'toggle-switch';

        const selectionInput = document.createElement('input');
        selectionInput.type = 'checkbox';
        selectionInput.checked = userSettings.enableSelectionSearch;
        selectionInput.addEventListener('change', function () {
            userSettings.enableSelectionSearch = this.checked;
            saveSettings();
        });

        const slider = document.createElement('span');
        slider.className = 'toggle-slider';

        selectionToggle.appendChild(selectionInput);
        selectionToggle.appendChild(slider);
        toggleWrapper.appendChild(selectionToggle);

        selectionSearchSetting.appendChild(selectionLabel);
        selectionSearchSetting.appendChild(toggleWrapper);
        settingsPanel.appendChild(selectionSearchSetting);

        // TG 搜索助手开关
        const tgSearchSetting = document.createElement('div');
        tgSearchSetting.className = 'setting-item';

        const tgLabel = document.createElement('span');
        tgLabel.className = 'setting-label';
        tgLabel.textContent = '启用 Telegram 115 搜索助手 (复制指令并跳转)';
        tgLabel.style.marginBottom = '8px';
        tgLabel.style.display = 'inline-block';

        const tgToggleWrapper = document.createElement('div');
        const tgToggle = document.createElement('label');
        tgToggle.className = 'toggle-switch';

        const tgInput = document.createElement('input');
        tgInput.type = 'checkbox';
        tgInput.checked = userSettings.enableTgSearch;
        tgInput.addEventListener('change', function () {
            userSettings.enableTgSearch = this.checked;
            saveSettings();
        });

        const tgSlider = document.createElement('span');
        tgSlider.className = 'toggle-slider';

        tgToggle.appendChild(tgInput);
        tgToggle.appendChild(tgSlider);
        tgToggleWrapper.appendChild(tgToggle);

        tgSearchSetting.appendChild(tgLabel);
        tgSearchSetting.appendChild(tgToggleWrapper);
        settingsPanel.appendChild(tgSearchSetting);

        // 分隔线
        const divider = document.createElement('hr');
        divider.style.cssText = 'border: 0; border-top: 1px solid #e5e7eb; margin: 20px 0;';
        settingsPanel.appendChild(divider);

        // API 设置
        settingsPanel.appendChild(createApiKeyInput('TMDB API Key', 'tmdbApiKey', userSettings.tmdbApiKey, '请输入 TMDB API Key'));
        settingsPanel.appendChild(createApiKeyInput('nullbr APP ID', 'appId', userSettings.appId, '请输入 APP ID'));
        settingsPanel.appendChild(createApiKeyInput('nullbr API Key', 'apiKey', userSettings.apiKey, '请输入 API Key'));

        // 保存按钮
        const saveBtn = document.createElement('button');
        saveBtn.className = 'save-btn';
        saveBtn.textContent = '保存配置';
        saveBtn.addEventListener('click', () => {
            saveSettings();
            const originalText = saveBtn.textContent;
            saveBtn.textContent = '已保存!';
            saveBtn.style.backgroundColor = '#10b981';
            setTimeout(() => {
                saveBtn.textContent = originalText;
                saveBtn.style.backgroundColor = '';
            }, 2000);
        });
        settingsPanel.appendChild(saveBtn);

        container.appendChild(settingsPanel);

        // 5. Tab 切换逻辑
        searchTab.addEventListener('click', () => {
            searchTab.classList.add('active');
            settingsTab.classList.remove('active');
            searchPanel.classList.add('active');
            settingsPanel.classList.remove('active');
        });

        settingsTab.addEventListener('click', () => {
            settingsTab.classList.add('active');
            searchTab.classList.remove('active');
            settingsPanel.classList.add('active');
            searchPanel.classList.remove('active');
        });

        // 6. 添加到页面
        document.body.appendChild(container);

        // 悬浮球
        const iconBtn = document.createElement('div');
        iconBtn.className = 'tmdb-icon';
        iconBtn.textContent = '搜源';
        iconBtn.title = '打开资源搜索';
        iconBtn.addEventListener('click', () => {
            const display = container.style.display;
            container.style.display = (display === 'none' || !display) ? 'block' : 'none';
        });
        document.body.appendChild(iconBtn);

        // 初始化 Toast
        const toast = document.createElement('div');
        toast.className = 'tmdb-toast';
        toast.id = 'tmdb-toast';
        document.body.appendChild(toast);

        // 搜索事件绑定
        const triggerSearch = () => {
            const val = input.value.trim();
            if (val) searchTmdb(val);
        };
        searchBtn.addEventListener('click', triggerSearch);
        input.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') triggerSearch();
        });
    }



    // 保存当前已获取的磁链信息
    function saveMagnetCache() {
        const cache = {};
        const movieItems = document.querySelectorAll('.media-item');
        movieItems.forEach(item => {
            const info = item.querySelector('.media-info');
            if (info) {
                const infoText = info.textContent;
                const idMatch = infoText.match(/TMDB ID: (\d+)/);
                if (idMatch && idMatch[1]) {
                    const id = idMatch[1];
                    const type = infoText.includes('电影') ? 'movie' : 'tv';
                    const magnetList = item.querySelector('.magnet-list');
                    if (magnetList && !magnetList.querySelector('.loading')) {
                        // 区分来源缓存
                        const key = `${type}-${id}-${currentSource}`;
                        cache[key] = magnetList.innerHTML;
                    }
                }
            }
        });
        return cache;
    }

    // 恢复之前已获取的磁链信息
    function restoreMagnetCache(cache) {
        const movieItems = document.querySelectorAll('.media-item');
        movieItems.forEach(item => {
            const info = item.querySelector('.media-info');
            if (info) {
                const infoText = info.textContent;
                const idMatch = infoText.match(/TMDB ID: (\d+)/);
                if (idMatch && idMatch[1]) {
                    const id = idMatch[1];
                    const type = infoText.includes('电影') ? 'movie' : 'tv';
                    const magnetList = item.querySelector('.magnet-list'); // 获取 magnetList
                    const key = `${type}-${id}-${currentSource}`; // 构建缓存key
                    if (magnetList && cache[key]) {
                        magnetList.innerHTML = cache[key];
                    } else if (magnetList) {
                        // 如果没有缓存内容或者是新的来源,重新请求
                        if (currentSource === '115') {
                            get115Links(id, type, magnetList);
                        } else if (currentSource === 'ed2k') {
                            getEd2kLinks(id, type, magnetList);
                        } else if (currentSource === 'm3u8') {
                            getM3u8Links(id, type, magnetList);
                        } else {
                            getMagnetLinks(id, type, magnetList);
                        }
                    }
                }
            }
        });
    }

    // 搜索TMDB API
    function searchTmdb(query) {
        const resultsContainer = document.getElementById('tmdb-magnet-results');
        resultsContainer.innerHTML = '<div class="loading">正在搜索TMDB...</div>';

        // 构建URL,搜索电影和电视剧
        const tmdbKey = getTmdbApiKey();
        const movieUrl = `https://api.themoviedb.org/3/search/movie?api_key=${tmdbKey}&query=${encodeURIComponent(query)}&language=zh-CN`;
        const tvUrl = `https://api.themoviedb.org/3/search/tv?api_key=${tmdbKey}&query=${encodeURIComponent(query)}&language=zh-CN`;

        // 先搜索电影
        GM_xmlhttpRequest({
            method: 'GET',
            url: movieUrl,
            headers: {
                'Accept': 'application/json'
            },
            onload: function (response) {
                try {
                    const movieData = JSON.parse(response.responseText);

                    // 然后搜索电视剧
                    GM_xmlhttpRequest({
                        method: 'GET',
                        url: tvUrl,
                        headers: {
                            'Accept': 'application/json'
                        },
                        onload: function (tvResponse) {
                            try {
                                const tvData = JSON.parse(tvResponse.responseText);

                                // 合并结果
                                const results = [
                                    ...movieData.results.map(item => ({ ...item, type: 'movie' })),
                                    ...tvData.results.map(item => ({ ...item, type: 'tv' }))
                                ];

                                // 显示结果
                                displayResults(results);
                            } catch (error) {
                                showError('解析电视剧数据失败: ' + error.message);
                            }
                        },
                        onerror: function () {
                            showError('获取电视剧数据失败');
                        }
                    });
                } catch (error) {
                    showError('解析电影数据失败: ' + error.message);
                }
            },
            onerror: function () {
                showError('获取电影数据失败');
            }
        });
    }

    // 显示搜索结果
    function displayResults(results, skipMagnet) {
        const resultsContainer = document.getElementById('tmdb-magnet-results');
        window._tmdbLastResults = results; // 用于筛选切换时重渲染
        if (!results || results.length === 0) {
            resultsContainer.innerHTML = '<div class="no-results">未找到相关影视作品</div>';
            return;
        }
        // 清空容器
        resultsContainer.innerHTML = '';
        // 根据筛选类型过滤
        let filteredResults = results;
        if (typeof currentFilter !== 'undefined' && currentFilter !== 'all') {
            filteredResults = results.filter(item => item.type === currentFilter);
        }
        if (filteredResults.length === 0) {
            resultsContainer.innerHTML = '<div class="no-results">筛选后无结果</div>';
            return;
        }
        // 展示全部结果(不再限制5条)
        for (const item of filteredResults) {
            const resultItem = document.createElement('div');
            resultItem.className = 'media-item';

            // TMDB 详情链接基础 URL
            const tmdbDetailUrl = `https://www.themoviedb.org/${item.type}/${item.id}`;

            // 左侧封面图
            const posterLink = document.createElement('a');
            posterLink.href = tmdbDetailUrl;
            posterLink.target = '_blank';

            const poster = document.createElement('img');
            poster.className = 'media-poster';
            poster.src = item.poster_path ? `https://image.tmdb.org/t/p/w92${item.poster_path}` : 'https://via.placeholder.com/68x102?text=No+Poster';
            poster.alt = item.type === 'movie' ? item.title : item.name;

            posterLink.appendChild(poster);
            resultItem.appendChild(posterLink);

            // 右侧详情区
            const details = document.createElement('div');
            details.className = 'media-details';

            // 标题 (也是链接)
            const title = document.createElement('a');
            title.className = 'media-title';
            title.href = tmdbDetailUrl;
            title.target = '_blank';
            title.textContent = item.type === 'movie' ? item.title : item.name;

            // 信息
            const info = document.createElement('div');
            info.className = 'media-info';

            // 添加年份
            let year = '';
            if (item.type === 'movie' && item.release_date) {
                year = new Date(item.release_date).getFullYear();
            } else if (item.type === 'tv' && item.first_air_date) {
                year = new Date(item.first_air_date).getFullYear();
            }

            // 创建类型标签
            const typeSpan = document.createElement('span');
            typeSpan.textContent = item.type === 'movie' ? '电影' : '剧集';
            typeSpan.className = `media-tag ${item.type}`;

            // 创建年份标签
            const yearSpan = document.createElement('span');
            yearSpan.textContent = year || '未知年份';
            yearSpan.className = 'media-tag';
            yearSpan.style.background = '#f3f4f6';

            // 创建TMDB ID标签 (也是链接)
            const idLink = document.createElement('a');
            idLink.href = tmdbDetailUrl;
            idLink.target = '_blank';
            idLink.className = 'media-tag link';
            idLink.textContent = `TMDB ID: ${item.id}`;
            idLink.style.background = '#f3f4f6';

            // 添加标签到信息区
            info.appendChild(typeSpan);
            info.appendChild(yearSpan);
            info.appendChild(idLink);

            // 磁力链接区域
            const magnetList = document.createElement('div');
            magnetList.className = 'magnet-list';
            magnetList.innerHTML = `<div class="loading">获取${getSourceName(currentSource)}中...</div>`;

            // 组装内容到详情区
            details.appendChild(title);
            details.appendChild(info);

            // TG 搜索按钮 (仅在 115 标签下显示,且需开启开关)
            if (currentSource === '115' && userSettings.enableTgSearch) {
                const tgBtn = document.createElement('button');
                tgBtn.className = 'tg-search-btn';
                tgBtn.innerHTML = '<span>✈️</span> TG 机器人搜索';
                tgBtn.title = '此结果由网友投稿分享到 Telegram 机器人';
                tgBtn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    const name = item.type === 'movie' ? item.title : item.name;
                    handleTelegramSearch(name);
                });
                details.appendChild(tgBtn);
            }

            details.appendChild(magnetList);

            // 添加详情区到主容器
            resultItem.appendChild(details);

            // 添加到结果容器
            resultsContainer.appendChild(resultItem);

            // 获取资源
            if (!skipMagnet) {
                if (currentSource === '115') {
                    get115Links(item.id, item.type, magnetList);
                } else if (currentSource === 'ed2k') {
                    getEd2kLinks(item.id, item.type, magnetList);
                } else if (currentSource === 'm3u8') {
                    getM3u8Links(item.id, item.type, magnetList);
                } else {
                    getMagnetLinks(item.id, item.type, magnetList);
                }
            }
        }
    }

    // 获取磁力链接
    function getMagnetLinks(tmdbId, type, container) {
        if (type === 'movie') {
            // 电影:用movie接口
            const url = `https://api.nullbr.com/movie/${tmdbId}`;
            GM_xmlhttpRequest({
                method: 'GET',
                url: url,
                headers: {
                    'Accept': 'application/json',
                    'X-APP-ID': getAppId()
                },
                onload: function (response) {
                    try {
                        const data = JSON.parse(response.responseText);
                        if (data['magnet-flg'] === 1) {
                            getMovieMagnets(tmdbId, container);
                        } else {
                            container.innerHTML = '<div class="no-results">未找到磁力链接</div>';
                        }
                    } catch (error) {
                        container.innerHTML = `<div class="error">解析电影信息失败: ${error.message}`;
                    }
                },
                onerror: function () {
                    container.innerHTML = '<div class="error">获取电影信息失败</div>';
                }
            });
        } else if (type === 'tv') {
            // 剧集:用tv接口,自动获取所有季和集的magnet标志
            const url = `https://api.nullbr.com/tv/${tmdbId}`;
            GM_xmlhttpRequest({
                method: 'GET',
                url: url,
                headers: {
                    'Accept': 'application/json',
                    'X-APP-ID': getAppId()
                },
                onload: function (response) {
                    try {
                        const data = JSON.parse(response.responseText);
                        if (!data.number_of_seasons || data.number_of_seasons < 1) {
                            container.innerHTML = '<div class="no-results">未找到季信息</div>';
                            return;
                        }
                        // 展示所有季
                        container.innerHTML = '';
                        for (let season = 1; season <= data.number_of_seasons; season++) {
                            getSeasonMagnets(tmdbId, season, container);
                        }
                    } catch (error) {
                        container.innerHTML = `<div class="error">解析剧集信息失败: ${error.message}`;
                    }
                },
                onerror: function () {
                    container.innerHTML = '<div class="error">获取剧集信息失败</div>';
                }
            });
        }
    }

    // 获取115网盘资源
    function get115Links(tmdbId, type, container) {
        const url = `https://api.nullbr.com/${type}/${tmdbId}/115`;
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'Accept': 'application/json',
                'X-APP-ID': getAppId(),
                'X-API-KEY': getApiKey()
            },
            onload: function (response) {
                try {
                    const data = JSON.parse(response.responseText);
                    if (data && data['115'] && Array.isArray(data['115']) && data['115'].length > 0) {
                        container.innerHTML = '';
                        data['115'].forEach(item => {
                            const linkItem = document.createElement('div');
                            linkItem.className = 'magnet-link';

                            // 创建链接
                            const link = document.createElement('a');
                            link.href = item.share_link;
                            link.target = '_blank';
                            link.title = item.title;
                            link.textContent = item.title;
                            link.style.color = '#2ecc71'; // 115链接使用绿色区分

                            // 创建信息标签
                            const infoSpan = document.createElement('div');
                            infoSpan.style.fontSize = '12px';
                            infoSpan.style.color = '#888';
                            infoSpan.style.marginTop = '3px';

                            // 添加文件大小
                            if (item.size) {
                                const sizeSpan = document.createElement('span');
                                sizeSpan.textContent = item.size;
                                sizeSpan.style.marginRight = '8px';
                                infoSpan.appendChild(sizeSpan);
                            }

                            // 添加分辨率
                            if (item.resolution) {
                                const resSpan = document.createElement('span');
                                resSpan.textContent = item.resolution;
                                resSpan.style.backgroundColor = '#f0f0f0';
                                resSpan.style.padding = '1px 5px';
                                resSpan.style.borderRadius = '3px';
                                resSpan.style.marginRight = '5px';
                                infoSpan.appendChild(resSpan);
                            }

                            // 添加质量
                            if (item.quality) {
                                const qualitySpan = document.createElement('span');
                                qualitySpan.textContent = item.quality;
                                qualitySpan.style.backgroundColor = '#f0f0f0';
                                qualitySpan.style.padding = '1px 5px';
                                qualitySpan.style.borderRadius = '3px';
                                qualitySpan.style.marginRight = '5px';
                                infoSpan.appendChild(qualitySpan);
                            }

                            // 剧集显示季列表
                            if (item.season_list && Array.isArray(item.season_list) && item.season_list.length > 0) {
                                const seasonSpan = document.createElement('span');
                                seasonSpan.textContent = item.season_list.join(', ');
                                seasonSpan.style.backgroundColor = '#e8f5e9';
                                seasonSpan.style.color = '#2e7d32';
                                seasonSpan.style.padding = '1px 5px';
                                seasonSpan.style.borderRadius = '3px';
                                infoSpan.appendChild(seasonSpan);
                            }

                            linkItem.appendChild(link);
                            linkItem.appendChild(infoSpan);
                            container.appendChild(linkItem);
                        });
                    } else {
                        container.innerHTML = '<div class="no-results">未找到115资源</div>';
                    }
                } catch (error) {
                    container.innerHTML = `<div class="error">解析115资源失败: ${error.message}</div>`;
                }
            },
            onerror: function () {
                container.innerHTML = '<div class="error">获取115资源失败</div>';
            }
        });
    }

    // 获取电影磁力资源
    function getMovieMagnets(tmdbId, container) {
        const url = `https://api.nullbr.com/movie/${tmdbId}/magnet`;
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'Accept': 'application/json',
                'X-APP-ID': getAppId(),
                'X-API-KEY': getApiKey()
            },
            onload: function (response) {
                try {
                    const data = JSON.parse(response.responseText);
                    if (Array.isArray(data.magnet) && data.magnet.length > 0) {
                        container.innerHTML = '';
                        data.magnet.forEach(item => {
                            const magnetItem = document.createElement('div');
                            magnetItem.className = 'magnet-link';

                            // 创建链接
                            const link = document.createElement('a');
                            link.href = item.magnet;
                            link.target = '_blank';
                            link.title = item.magnet;
                            link.textContent = item.name;

                            // 创建信息标签
                            const infoSpan = document.createElement('div');
                            infoSpan.style.fontSize = '12px';
                            infoSpan.style.color = '#888';
                            infoSpan.style.marginTop = '3px';

                            // 添加文件大小
                            const sizeSpan = document.createElement('span');
                            sizeSpan.textContent = item.size;
                            sizeSpan.style.marginRight = '8px';
                            infoSpan.appendChild(sizeSpan);

                            // 添加分辨率
                            if (item.resolution) {
                                const resSpan = document.createElement('span');
                                resSpan.textContent = item.resolution;
                                resSpan.style.backgroundColor = '#f0f0f0';
                                resSpan.style.padding = '1px 5px';
                                resSpan.style.borderRadius = '3px';
                                resSpan.style.marginRight = '5px';
                                infoSpan.appendChild(resSpan);
                            }

                            // 添加来源
                            if (item.source) {
                                const sourceSpan = document.createElement('span');
                                sourceSpan.textContent = item.source;
                                sourceSpan.style.backgroundColor = '#f0f0f0';
                                sourceSpan.style.padding = '1px 5px';
                                sourceSpan.style.borderRadius = '3px';
                                sourceSpan.style.marginRight = '5px';
                                infoSpan.appendChild(sourceSpan);
                            }

                            // 添加质量
                            if (item.quality) {
                                const qualityText = Array.isArray(item.quality) ? item.quality.join(',') : item.quality;
                                if (qualityText) {
                                    const qualitySpan = document.createElement('span');
                                    qualitySpan.textContent = qualityText;
                                    qualitySpan.style.backgroundColor = '#f0f0f0';
                                    qualitySpan.style.padding = '1px 5px';
                                    qualitySpan.style.borderRadius = '3px';
                                    infoSpan.appendChild(qualitySpan);
                                }
                            }

                            // 添加中文字幕标记
                            if (item.zh_sub === 1) {
                                const zhSpan = document.createElement('span');
                                zhSpan.textContent = '中字';
                                zhSpan.style.backgroundColor = '#4caf50';
                                zhSpan.style.color = 'white';
                                zhSpan.style.padding = '1px 5px';
                                zhSpan.style.borderRadius = '3px';
                                zhSpan.style.marginLeft = '5px';
                                infoSpan.appendChild(zhSpan);
                            }

                            // 组装磁力项
                            magnetItem.appendChild(link);
                            magnetItem.appendChild(infoSpan);
                            container.appendChild(magnetItem);
                        });
                    } else {
                        container.innerHTML = '<div class="no-results">未找到磁力资源</div>';
                    }
                } catch (error) {
                    container.innerHTML = `<div class="error">解析磁力资源失败: ${error.message}</div>`;
                }
            },
            onerror: function () {
                container.innerHTML = '<div class="error">获取磁力资源失败</div>';
            }
        });
    }

    // 获取某一季的磁力资源(不再请求单集磁力)
    function getSeasonMagnets(tmdbId, season, container) {
        const url = `https://api.nullbr.com/tv/${tmdbId}/season/${season}/magnet`;
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'Accept': 'application/json',
                'X-APP-ID': getAppId(),
                'X-API-KEY': getApiKey()
            },
            onload: function (response) {
                try {
                    const data = JSON.parse(response.responseText);

                    // 创建季标题
                    const seasonHeader = document.createElement('div');
                    seasonHeader.style.marginTop = '12px';
                    seasonHeader.style.marginBottom = '8px';
                    seasonHeader.style.fontWeight = '600';
                    seasonHeader.style.display = 'flex';
                    seasonHeader.style.alignItems = 'center';

                    const seasonBadge = document.createElement('span');
                    seasonBadge.textContent = `第${season}季`;
                    seasonBadge.style.backgroundColor = '#0d253f';
                    seasonBadge.style.color = 'white';
                    seasonBadge.style.padding = '2px 8px';
                    seasonBadge.style.borderRadius = '4px';
                    seasonBadge.style.fontSize = '13px';

                    seasonHeader.appendChild(seasonBadge);
                    container.appendChild(seasonHeader);

                    // 创建磁力链接列表
                    const magnetContainer = document.createElement('div');
                    magnetContainer.style.marginLeft = '10px';

                    if (Array.isArray(data.magnet) && data.magnet.length > 0) {
                        data.magnet.forEach(item => {
                            const magnetItem = document.createElement('div');
                            magnetItem.className = 'magnet-link';

                            // 创建链接
                            const link = document.createElement('a');
                            link.href = item.magnet;
                            link.target = '_blank';
                            link.title = item.magnet;
                            link.textContent = item.name;

                            // 创建信息标签
                            const infoSpan = document.createElement('div');
                            infoSpan.style.fontSize = '12px';
                            infoSpan.style.color = '#888';
                            infoSpan.style.marginTop = '3px';

                            // 添加文件大小
                            const sizeSpan = document.createElement('span');
                            sizeSpan.textContent = item.size;
                            sizeSpan.style.marginRight = '8px';
                            infoSpan.appendChild(sizeSpan);

                            // 添加分辨率
                            if (item.resolution) {
                                const resSpan = document.createElement('span');
                                resSpan.textContent = item.resolution;
                                resSpan.style.backgroundColor = '#f0f0f0';
                                resSpan.style.padding = '1px 5px';
                                resSpan.style.borderRadius = '3px';
                                resSpan.style.marginRight = '5px';
                                infoSpan.appendChild(resSpan);
                            }

                            // 添加来源
                            if (item.source) {
                                const sourceSpan = document.createElement('span');
                                sourceSpan.textContent = item.source;
                                sourceSpan.style.backgroundColor = '#f0f0f0';
                                sourceSpan.style.padding = '1px 5px';
                                sourceSpan.style.borderRadius = '3px';
                                sourceSpan.style.marginRight = '5px';
                                infoSpan.appendChild(sourceSpan);
                            }

                            // 添加质量
                            if (item.quality) {
                                const qualityText = Array.isArray(item.quality) ? item.quality.join(',') : item.quality;
                                if (qualityText) {
                                    const qualitySpan = document.createElement('span');
                                    qualitySpan.textContent = qualityText;
                                    qualitySpan.style.backgroundColor = '#f0f0f0';
                                    qualitySpan.style.padding = '1px 5px';
                                    qualitySpan.style.borderRadius = '3px';
                                    infoSpan.appendChild(qualitySpan);
                                }
                            }

                            // 添加中文字幕标记
                            if (item.zh_sub === 1) {
                                const zhSpan = document.createElement('span');
                                zhSpan.textContent = '中字';
                                zhSpan.style.backgroundColor = '#4caf50';
                                zhSpan.style.color = 'white';
                                zhSpan.style.padding = '1px 5px';
                                zhSpan.style.borderRadius = '3px';
                                zhSpan.style.marginLeft = '5px';
                                infoSpan.appendChild(zhSpan);
                            }

                            // 组装磁力项
                            magnetItem.appendChild(link);
                            magnetItem.appendChild(infoSpan);
                            magnetContainer.appendChild(magnetItem);
                        });
                    } else {
                        const noResults = document.createElement('div');
                        noResults.className = 'no-results';
                        noResults.style.margin = '5px 0';
                        noResults.textContent = '未找到磁力资源';
                        magnetContainer.appendChild(noResults);
                    }

                    container.appendChild(magnetContainer);
                } catch (error) {
                    const errDiv = document.createElement('div');
                    errDiv.className = 'error';
                    errDiv.textContent = `解析第${season}季磁力资源失败: ${error.message}`;
                    container.appendChild(errDiv);
                }
            },
            onerror: function () {
                const errDiv = document.createElement('div');
                errDiv.className = 'error';
                errDiv.textContent = `获取第${season}季磁力资源失败`;
                container.appendChild(errDiv);
            }
        });
    }

    // 获取ED2K资源
    function getEd2kLinks(tmdbId, type, container) {
        if (type === 'tv') {
            container.innerHTML = '<div class="no-results">剧集暂不支持ED2K批量获取,请使用磁力或115</div>';
            return;
        }

        const url = `https://api.nullbr.com/${type}/${tmdbId}/ed2k`;
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'Accept': 'application/json',
                'X-APP-ID': getAppId(),
                'X-API-KEY': getApiKey()
            },
            onload: function (response) {
                try {
                    const data = JSON.parse(response.responseText);
                    if (data && data.ed2k && Array.isArray(data.ed2k) && data.ed2k.length > 0) {
                        container.innerHTML = '';
                        // 排序:有中文字幕的优先
                        data.ed2k.sort((a, b) => (b.zh_sub || 0) - (a.zh_sub || 0));

                        data.ed2k.forEach(item => {
                            const linkItem = document.createElement('div');
                            linkItem.className = 'magnet-link';

                            const link = document.createElement('a');
                            link.href = item.ed2k;
                            link.textContent = item.name;
                            link.style.color = '#e67e22'; // ED2K使用橙色

                            const infoSpan = document.createElement('div');
                            infoSpan.style.fontSize = '12px';
                            infoSpan.style.color = '#888';
                            infoSpan.style.marginTop = '3px';

                            if (item.size) {
                                const sizeSpan = document.createElement('span');
                                sizeSpan.textContent = item.size;
                                sizeSpan.style.marginRight = '8px';
                                infoSpan.appendChild(sizeSpan);
                            }

                            if (item.resolution) {
                                const resSpan = document.createElement('span');
                                resSpan.textContent = item.resolution;
                                resSpan.style.backgroundColor = '#f0f0f0';
                                resSpan.style.padding = '1px 5px';
                                resSpan.style.borderRadius = '3px';
                                resSpan.style.marginRight = '5px';
                                infoSpan.appendChild(resSpan);
                            }

                            if (item.zh_sub === 1) {
                                const zhSpan = document.createElement('span');
                                zhSpan.textContent = '中字';
                                zhSpan.style.backgroundColor = '#4caf50';
                                zhSpan.style.color = 'white';
                                zhSpan.style.padding = '1px 5px';
                                zhSpan.style.borderRadius = '3px';
                                infoSpan.appendChild(zhSpan);
                            }

                            linkItem.appendChild(link);
                            linkItem.appendChild(infoSpan);
                            container.appendChild(linkItem);
                        });
                    } else {
                        container.innerHTML = '<div class="no-results">未找到ED2K资源</div>';
                    }
                } catch (error) {
                    container.innerHTML = `<div class="error">解析ED2K失败: ${error.message}</div>`;
                }
            },
            onerror: function () {
                container.innerHTML = '<div class="error">获取ED2K资源失败</div>';
            }
        });
    }

    // 获取M3U8/在线资源
    function getM3u8Links(tmdbId, type, container) {
        if (type === 'tv') {
            container.innerHTML = '<div class="no-results">剧集暂不支持在线资源批量获取,请使用磁力或115</div>';
            return;
        }

        const url = `https://api.nullbr.com/${type}/${tmdbId}/video`;
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            headers: {
                'Accept': 'application/json',
                'X-APP-ID': getAppId(),
                'X-API-KEY': getApiKey()
            },
            onload: function (response) {
                try {
                    const data = JSON.parse(response.responseText);
                    if (data && data.video && Array.isArray(data.video) && data.video.length > 0) {
                        container.innerHTML = '';
                        data.video.forEach(item => {
                            const linkItem = document.createElement('div');
                            linkItem.className = 'magnet-link';

                            const link = document.createElement('a');
                            link.href = item.link;
                            link.target = '_blank';
                            link.textContent = `[${item.name}] ${item.source}`;
                            link.style.color = '#e74c3c'; // M3U8使用红色

                            const infoSpan = document.createElement('div');
                            infoSpan.style.fontSize = '12px';
                            infoSpan.style.color = '#888';
                            infoSpan.style.marginTop = '3px';

                            const typeSpan = document.createElement('span');
                            typeSpan.textContent = item.type.toUpperCase();
                            typeSpan.style.backgroundColor = '#f0f0f0';
                            typeSpan.style.padding = '1px 5px';
                            typeSpan.style.borderRadius = '3px';
                            infoSpan.appendChild(typeSpan);

                            linkItem.appendChild(link);
                            linkItem.appendChild(infoSpan);
                            container.appendChild(linkItem);
                        });
                    } else {
                        container.innerHTML = '<div class="no-results">未找到在线资源</div>';
                    }
                } catch (error) {
                    container.innerHTML = `<div class="error">解析在线资源失败: ${error.message}</div>`;
                }
            },
            onerror: function () {
                container.innerHTML = '<div class="error">获取在线资源失败</div>';
            }
        });
    }

    // 获取资源名称辅助函数
    function getSourceName(source) {
        switch (source) {
            case '115': return '115资源';
            case 'ed2k': return 'ED2K资源';
            case 'm3u8': return '在线资源';
            case 'telegram': return 'Telegram机器人';
            default: return '磁力链接';
        }
    }

    // 显示错误信息
    function showError(message) {
        const resultsContainer = document.getElementById('tmdb-magnet-results');
        resultsContainer.innerHTML = `<div class="error">${message}</div>`;
    }

    // 提示信息
    function showToast(message) {
        const toast = document.getElementById('tmdb-toast');
        if (!toast) return;
        toast.textContent = message;
        toast.classList.add('show');
        setTimeout(() => {
            toast.classList.remove('show');
        }, 2500);
    }

    // 复制到剪贴板
    function copyToClipboard(text) {
        const tempInput = document.createElement('textarea');
        tempInput.value = text;
        document.body.appendChild(tempInput);
        tempInput.select();
        document.execCommand('copy');
        document.body.removeChild(tempInput);
    }

    // 处理 Telegram 搜索跳转
    function handleTelegramSearch(name) {
        const command = `/ss ${name}`;
        copyToClipboard(command);
        showToast('指令已复制!请在即将打开的 TG 对话框中粘贴并发送。');
        setTimeout(() => {
            window.open('tg://resolve?domain=nullbr_search_bot', '_blank');
        }, 800);
    }

    // 当页面加载完成后创建UI
    window.addEventListener('load', function () {
        // 延迟1秒加载UI,确保页面已完全加载
        setTimeout(createUI, 1000);
    });

    // 选中弹出悬浮搜索按钮
    let searchBtn = null;
    let lastSelection = '';
    let currentFilter = 'all'; // 提升为全局变量
    let currentSource = '115'; // 当前资源来源,设为 115 优先

    function removeSearchBtn() {
        if (searchBtn && searchBtn.parentNode) {
            searchBtn.parentNode.removeChild(searchBtn);
            searchBtn = null;
        }
    }

    document.addEventListener('selectionchange', function () {
        // 如果用户关闭了选中搜索功能,则不显示搜索按钮
        if (!userSettings.enableSelectionSearch) {
            removeSearchBtn();
            return;
        }

        removeSearchBtn();
        const sel = window.getSelection();
        if (!sel || sel.isCollapsed) return;
        const text = sel.toString().trim();
        if (!text) return;
        lastSelection = text;
        const range = sel.getRangeAt(0);
        const rect = range.getBoundingClientRect();
        // 创建按钮
        searchBtn = document.createElement('button');
        searchBtn.textContent = '🔍 搜索资源';
        searchBtn.style.position = 'fixed';
        searchBtn.style.zIndex = 99999;
        searchBtn.style.left = (rect.right + 10) + 'px';
        searchBtn.style.top = (rect.top - 10) + 'px';
        searchBtn.style.background = 'linear-gradient(120deg, #00C6FF 0%, #0072FF 100%)';
        searchBtn.style.color = '#fff';
        searchBtn.style.border = 'none';
        searchBtn.style.borderRadius = '50px';
        searchBtn.style.padding = '8px 16px';
        searchBtn.style.cursor = 'pointer';
        searchBtn.style.boxShadow = '0 4px 15px rgba(0, 114, 255, 0.4)';
        searchBtn.style.fontSize = '14px';
        searchBtn.style.fontWeight = '600';
        searchBtn.style.transition = 'all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1)';
        searchBtn.style.backdropFilter = 'blur(4px)';
        searchBtn.onmousedown = e => e.preventDefault(); // 防止失去选区

        searchBtn.onmouseover = function () {
            this.style.transform = 'scale(1.05)';
            this.style.boxShadow = '0 4px 12px rgba(0,0,0,0.25)';
        };
        searchBtn.onmouseout = function () {
            this.style.transform = 'scale(1)';
            this.style.boxShadow = '0 2px 8px rgba(0,0,0,0.2)';
        };
        searchBtn.onclick = function (e) {
            e.stopPropagation();
            removeSearchBtn();
            showTmdbPanelWithText(lastSelection);
        };
        document.body.appendChild(searchBtn);
    });

    document.addEventListener('mousedown', function (e) {
        if (searchBtn && !searchBtn.contains(e.target)) {
            removeSearchBtn();
        }
    });

    // 自动填入并弹出面板
    function showTmdbPanelWithText(text) {
        const container = document.getElementById('tmdb-magnet-container');
        if (container) container.style.display = 'block';
        const input = document.getElementById('tmdb-magnet-input');
        if (input) {
            input.value = text;
            // 自动搜索
            searchTmdb(text);
        }
    }
})();