Greasy Fork镜像 还支持 简体中文。

WayBackTube (Hyper-Optimized + Search Terms)

Travel back in time on YouTube with subscriptions, search terms, AND simple 2011 theme! Complete time travel experience with custom recommendation algorithm and clean vintage styling.

目前為 2025-07-21 提交的版本,檢視 最新版本

// ==UserScript==
// @name         WayBackTube (Hyper-Optimized + Search Terms)
// @namespace    http://tampermonkey.net/
// @license MIT
// @version      68
// @description  Travel back in time on YouTube with subscriptions, search terms, AND simple 2011 theme! Complete time travel experience with custom recommendation algorithm and clean vintage styling.
// @author       You
// @match        https://www.youtube.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_listValues
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @connect      youtube.com
// @connect      googleapis.com
// @connect      worldtimeapi.org
// @connect      ipgeolocation.io
// @connect      worldclockapi.com
// @connect      *
// @connect      httpbin.org
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // === HYPER-OPTIMIZED CONFIG ===
    const CONFIG = {
        updateInterval: 50,
        debugMode: true,
        videosPerChannel: 30,
        maxHomepageVideos: 60,
        maxVideoPageVideos: 30,
        channelPageVideosPerMonth: 50,
        watchNextVideosCount: 30,
        seriesMatchVideosCount: 3,
        cacheExpiry: {
            videos: 7200000, // 2 hours
            channelVideos: 3600000, // 1 hour
            searchResults: 1800000 // 30 minutes
        },
        maxConcurrentRequests: 2,
        batchSize: 3,
        apiCooldown: 200,
        autoLoadOnHomepage: false,
        autoLoadDelay: 1500,
        autoAdvanceDays: true,
        autoRefreshInterval: 21600000, // 6 hours
        refreshVideoPercentage: 0.5,
        homepageLoadMoreSize: 12,
        aggressiveNukingInterval: 10,
        viralVideoPercentage: 0.15,
        viralVideosCount: 20,
        RECOMMENDATION_COUNT: 20,
        SAME_CHANNEL_RATIO: 0.6,
        OTHER_CHANNELS_RATIO: 0.4,
        KEYWORD_RATIO: 0.5,
        FRESH_VIDEOS_COUNT: 15,
        KEYWORD_MATCH_RATIO: 0.5,

        // Video weighting configuration - UPDATED: 60/40 subscription-search split
        searchTermVideoPercentage: 0.40,  // 40% search term videos (user requested more subscriptions)
        sameChannelVideoPercentage: 0.00, // 0% same channel videos - ONLY next episode goes to top
        subscriptionVideoPercentage: 0.60, // 60% subscription videos (user requested increase)



        // Pre-compiled selectors for performance
        SHORTS_SELECTORS: [
            'ytd-reel-shelf-renderer',
            'ytd-rich-shelf-renderer[is-shorts]',
            '[aria-label*="Shorts"]',
            '[title*="Shorts"]',
            'ytd-video-renderer[is-shorts]',
            '.ytd-reel-shelf-renderer',
            '.shorts-shelf',
            '.reel-shelf-renderer',
            '.shortsLockupViewModelHost',
            '.ytGridShelfViewModelHost',
            '[overlay-style="SHORTS"]',
            '[href*="/shorts/"]'
        ],



        CHANNEL_PAGE_SELECTORS: [
            'ytd-browse[page-subtype="channels"] ytd-video-renderer',
            'ytd-browse[page-subtype="channel"] ytd-video-renderer',
            'ytd-browse[page-subtype="channels"] ytd-grid-video-renderer',
            'ytd-browse[page-subtype="channel"] ytd-grid-video-renderer',
            'ytd-browse[page-subtype="channels"] ytd-rich-item-renderer',
            'ytd-browse[page-subtype="channel"] ytd-rich-item-renderer',
            'ytd-c4-tabbed-header-renderer ytd-video-renderer',
            'ytd-channel-video-player-renderer ytd-video-renderer',
            '#contents ytd-video-renderer',
            '#contents ytd-grid-video-renderer',
            '#contents ytd-rich-item-renderer',
            'ytd-browse[page-subtype="channel"] ytd-shelf-renderer',
            'ytd-browse[page-subtype="channel"] ytd-rich-shelf-renderer',
            'ytd-browse[page-subtype="channel"] ytd-item-section-renderer',
            'ytd-browse[page-subtype="channel"] ytd-section-list-renderer',
            'ytd-browse[page-subtype="channel"] ytd-horizontal-card-list-renderer',
            'ytd-browse[page-subtype="channel"] ytd-playlist-renderer',
            'ytd-browse[page-subtype="channel"] ytd-compact-playlist-renderer',
            'ytd-browse[page-subtype="channel"] ytd-grid-playlist-renderer',
            '#contents ytd-shelf-renderer',
            '#contents ytd-rich-shelf-renderer',
            '#contents ytd-item-section-renderer',
            '#contents ytd-section-list-renderer',
            '#contents ytd-horizontal-card-list-renderer',
            '#contents ytd-playlist-renderer',
            '#contents ytd-compact-playlist-renderer',
            '#contents ytd-grid-playlist-renderer',
            'ytd-browse[page-subtype="channel"] #contents > *',
            'ytd-browse[page-subtype="channel"] #primary-inner > *:not(ytd-c4-tabbed-header-renderer)',
            '[data-target-id="browse-feed-tab"]',
            'ytd-browse[page-subtype="channel"] ytd-browse-feed-actions-renderer'
        ],

        // Feed filter chip selectors for hiding "All", "Music", "Gaming", etc.
        FEED_CHIP_SELECTORS: [
            'ytd-feed-filter-chip-bar-renderer',
            'ytd-chip-cloud-renderer',
            'ytd-chip-cloud-chip-renderer',
            'ytd-feed-filter-renderer',
            '#chips',
            '.ytd-feed-filter-chip-bar-renderer',
            '[role="tablist"]',
            'iron-selector[role="tablist"]'
        ]
    };

    // === OPTIMIZED UTILITIES ===
    class OptimizedUtils {
        static cache = new Map();
        static domCache = new WeakMap();
        static selectorCache = new Map();

        static log(message, ...args) {
            if (CONFIG.debugMode) {
                console.log(`[WayBackTube] ${message}`, ...args);
            }
        }

        static memoize(fn, keyFn) {
            const cache = new Map();
            return function(...args) {
                const key = keyFn ? keyFn(...args) : JSON.stringify(args);
                if (cache.has(key)) return cache.get(key);
                const result = fn.apply(this, args);
                cache.set(key, result);
                return result;
            };
        }

        static throttle(func, wait) {
            let timeout;
            let previous = 0;
            return function(...args) {
                const now = Date.now();
                const remaining = wait - (now - previous);

                if (remaining <= 0 || remaining > wait) {
                    if (timeout) {
                        clearTimeout(timeout);
                        timeout = null;
                    }
                    previous = now;
                    return func.apply(this, args);
                } else if (!timeout) {
                    timeout = setTimeout(() => {
                        previous = Date.now();
                        timeout = null;
                        func.apply(this, args);
                    }, remaining);
                }
            };
        }

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

        static $(selector, context = document) {
            const key = `${selector}-${context === document ? 'doc' : 'ctx'}`;
            if (this.selectorCache.has(key)) {
                return this.selectorCache.get(key);
            }
            const element = context.querySelector(selector);
            if (element) this.selectorCache.set(key, element);
            return element;
        }

        static $$(selector, context = document) {
            return Array.from(context.querySelectorAll(selector));
        }

        static parseDate(dateStr) {
            if (!dateStr) return null;
            const formats = [
                /^\d{4}-\d{2}-\d{2}$/,
                /^\d{2}\/\d{2}\/\d{4}$/,
                /^\d{4}\/\d{2}\/\d{2}$/
            ];

            if (formats[0].test(dateStr)) {
                return new Date(dateStr + 'T00:00:00');
            } else if (formats[1].test(dateStr)) {
                const [month, day, year] = dateStr.split('/');
                return new Date(year, month - 1, day);
            } else if (formats[2].test(dateStr)) {
                const [year, month, day] = dateStr.split('/');
                return new Date(year, month - 1, day);
            }
            return new Date(dateStr);
        }

        static formatDate(date, format = 'YYYY-MM-DD') {
            if (!date) return '';
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');

            return format
                .replace('YYYY', year)
                .replace('MM', month)
                .replace('DD', day);
        }

        static addDays(date, days) {
            const result = new Date(date);
            result.setDate(result.getDate() + days);
            return result;
        }

        static getRandomElement(array) {
            return array[Math.floor(Math.random() * array.length)];
        }

        static shuffleArray(array) {
            const shuffled = [...array];
            for (let i = shuffled.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * (i + 1));
                [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
            }
            return shuffled;
        }

        static removeDuplicates(videos) {
            const seenIds = new Set();
            const uniqueVideos = [];

            for (const video of videos) {
                const videoId = video.id?.videoId || video.id || video.snippet?.resourceId?.videoId;
                if (videoId && !seenIds.has(videoId)) {
                    seenIds.add(videoId);
                    uniqueVideos.push(video);
                }
            }

            return uniqueVideos;
        }

        static weightedShuffleByDate(videos, maxDate) {
            if (!videos || videos.length === 0) return [];

            // Sort videos by publish date first - newest to oldest
            const sortedVideos = [...videos].sort((a, b) => {
                const dateA = new Date(a.snippet?.publishedAt || a.publishedAt || '2005-01-01');
                const dateB = new Date(b.snippet?.publishedAt || b.publishedAt || '2005-01-01');
                return dateB - dateA; // Newest first
            });

            // Create weighted array based on video publish dates with HEAVY bias towards recent content
            const weightedVideos = sortedVideos.map((video, index) => {
                const publishDate = new Date(video.snippet?.publishedAt || video.publishedAt || '2005-01-01');
                const hoursDiff = Math.max(1, Math.floor((maxDate - publishDate) / (1000 * 60 * 60)));
                const daysDiff = Math.max(1, Math.floor(hoursDiff / 24));

                // HEAVY weight bias towards very recent content
                let weight;
                if (hoursDiff <= 6) {
                    weight = 100; // Last 6 hours - MAXIMUM priority
                } else if (hoursDiff <= 24) {
                    weight = 50;  // Last 24 hours - VERY high priority
                } else if (daysDiff <= 3) {
                    weight = 25;  // Last 3 days - High priority
                } else if (daysDiff <= 7) {
                    weight = 15;  // Last week - Good priority
                } else if (daysDiff <= 30) {
                    weight = 8;   // Last month - Medium priority
                } else if (daysDiff <= 90) {
                    weight = 4;   // Last 3 months - Lower priority
                } else if (daysDiff <= 365) {
                    weight = 2;   // Last year - Low priority
                } else {
                    weight = 1;   // Older than 1 year - Minimal priority
                }

                // Position bonus: videos already sorted newest first get additional weight
                // This ensures the newest videos stay at the top
                const positionBonus = Math.max(0, 20 - Math.floor(index / 5)); // Top 100 videos get position bonus
                weight += positionBonus;

                return { video, weight, publishDate, hoursDiff };
            });

            // Separate videos into tiers for better control
            const recentVideos = weightedVideos.filter(v => v.hoursDiff <= 24);   // Last 24 hours
            const newVideos = weightedVideos.filter(v => v.hoursDiff > 24 && v.hoursDiff <= 168); // Last week
            const olderVideos = weightedVideos.filter(v => v.hoursDiff > 168);    // Older than a week

            // Create weighted selection with heavy bias towards recent content
            const weightedSelection = [];

            // Add recent videos with maximum representation
            recentVideos.forEach(({ video, weight }) => {
                for (let i = 0; i < weight; i++) {
                    weightedSelection.push(video);
                }
            });

            // Add new videos with good representation
            newVideos.forEach(({ video, weight }) => {
                for (let i = 0; i < weight; i++) {
                    weightedSelection.push(video);
                }
            });

            // Add older videos with minimal representation
            olderVideos.forEach(({ video, weight }) => {
                for (let i = 0; i < weight; i++) {
                    weightedSelection.push(video);
                }
            });

            // Shuffle the weighted array and remove duplicates while preserving heavy recent bias
            const shuffled = this.shuffleArray(weightedSelection);
            const uniqueVideos = [];
            const seenIds = new Set();

            for (const video of shuffled) {
                const videoId = video.id?.videoId || video.id || video.snippet?.resourceId?.videoId;
                if (videoId && !seenIds.has(videoId)) {
                    seenIds.add(videoId);
                    uniqueVideos.push(video);
                }
            }

            return uniqueVideos;
        }

        static waitFor(condition, timeout = 10000, interval = 100) {
            return new Promise((resolve, reject) => {
                const startTime = Date.now();
                const check = () => {
                    if (condition()) {
                        resolve();
                    } else if (Date.now() - startTime >= timeout) {
                        reject(new Error('Timeout waiting for condition'));
                    } else {
                        setTimeout(check, interval);
                    }
                };
                check();
            });
        }

        static sleep(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        static isValidVideoId(videoId) {
            return /^[a-zA-Z0-9_-]{11}$/.test(videoId);
        }

        static extractVideoId(url) {
            if (!url) return null;
            const match = url.match(/(?:v=|\/embed\/|\/watch\?v=|\/v\/|youtu\.be\/)([^&\n?#]+)/);
            return match ? match[1] : null;
        }

        static extractChannelId(url) {
            if (!url) return null;
            const patterns = [
                /\/channel\/([a-zA-Z0-9_-]+)/,
                /\/c\/([a-zA-Z0-9_-]+)/,
                /\/user\/([a-zA-Z0-9_-]+)/,
                /\/@([a-zA-Z0-9_-]+)/
            ];

            for (const pattern of patterns) {
                const match = url.match(pattern);
                if (match) return match[1];
            }
            return null;
        }

        static cleanTitle(title) {
            if (!title) return '';
            return title
                .replace(/[\u200B-\u200D\uFEFF]/g, '')
                .replace(/\s+/g, ' ')
                .trim();
        }

        static extractKeywords(title) {
            if (!title) return [];
            return title
                .toLowerCase()
                .replace(/[^\w\s]/g, '')
                .split(/\s+/)
                .filter(word => word.length > 2)
                .slice(0, 5);
        }

        static getCurrentPage() {
            const path = window.location.pathname;
            if (path === '/') return 'home';
            if (path.startsWith('/watch')) return 'video';
            if (path.startsWith('/channel') || path.startsWith('/c/') || path.startsWith('/user/') || path.startsWith('/@')) return 'channel';
            if (path.startsWith('/results')) return 'search';
            return 'other';
        }

        static getPageContext() {
            return {
                page: this.getCurrentPage(),
                url: window.location.href,
                videoId: this.extractVideoId(window.location.href),
                channelId: this.extractChannelId(window.location.href)
            };
        }

        static calculateRelativeDate(uploadDate, maxDate) {
            if (!uploadDate || !maxDate) return '';

            const upload = new Date(uploadDate);
            const max = new Date(maxDate);

            if (upload > max) return 'In the future';

            // Calculate proper date differences
            let years = max.getFullYear() - upload.getFullYear();
            let months = max.getMonth() - upload.getMonth();
            let days = max.getDate() - upload.getDate();

            // Adjust for negative days
            if (days < 0) {
                months--;
                const prevMonth = new Date(max.getFullYear(), max.getMonth(), 0);
                days += prevMonth.getDate();
            }

            // Adjust for negative months
            if (months < 0) {
                years--;
                months += 12;
            }

            // Calculate total days for smaller units
            const totalMilliseconds = max - upload;
            const totalDays = Math.floor(totalMilliseconds / (1000 * 60 * 60 * 24));
            const totalHours = Math.floor(totalMilliseconds / (1000 * 60 * 60));
            const totalMinutes = Math.floor(totalMilliseconds / (1000 * 60));

            // Return the most appropriate unit
            if (years > 0) {
                return `${years} year${years > 1 ? 's' : ''} ago`;
            }
            if (months > 0) {
                return `${months} month${months > 1 ? 's' : ''} ago`;
            }
            if (totalDays >= 7) {
                const weeks = Math.floor(totalDays / 7);
                return `${weeks} week${weeks > 1 ? 's' : ''} ago`;
            }
            if (totalDays > 0) {
                return `${totalDays} day${totalDays > 1 ? 's' : ''} ago`;
            }
            if (totalHours > 0) {
                return `${totalHours} hour${totalHours > 1 ? 's' : ''} ago`;
            }
            if (totalMinutes > 0) {
                return `${totalMinutes} minute${totalMinutes > 1 ? 's' : ''} ago`;
            }
            return 'Just now';
        }

        // Filter relative date text elements to show time relative to selected date
        static filterRelativeDates(maxDate) {
            if (!maxDate) return;

            const relativePatterns = [
                /(\d+)\s+(second|minute|hour|day|week|month|year)s?\s+ago/gi,
                /(\d+)\s+(sec|min|hr|hrs|d|w|mo|yr)s?\s+ago/gi
            ];

            // Find all text nodes with relative dates in search results ONLY
            const walker = document.createTreeWalker(
                document.body,
                NodeFilter.SHOW_TEXT,
                {
                    acceptNode: function(node) {
                        if (!node.parentElement) return NodeFilter.FILTER_REJECT;

                        // Skip our own UI elements
                        if (node.parentElement.closest('.wayback-container, .yt-time-machine-ui, #wayback-channel-content, .wayback-channel-video-card, .tm-video-card')) {
                            return NodeFilter.FILTER_REJECT;
                        }

                        // Skip homepage content that we've replaced
                        if (node.parentElement.closest('ytd-browse[page-subtype="home"]')) {
                            return NodeFilter.FILTER_REJECT;
                        }

                        // Skip watch next sidebar (our content)
                        if (node.parentElement.closest('#secondary #related')) {
                            return NodeFilter.FILTER_REJECT;
                        }

                        // ONLY process search results - look for search result containers
                        const isInSearchResults = node.parentElement.closest('#contents ytd-search, ytd-search-section-renderer, ytd-video-renderer, ytd-shelf-renderer');
                        if (!isInSearchResults) {
                            return NodeFilter.FILTER_REJECT;
                        }

                        const text = node.textContent.trim();
                        return relativePatterns.some(pattern => pattern.test(text)) ? 
                            NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
                    }
                }
            );

            const textNodes = [];
            let node;
            while (node = walker.nextNode()) {
                textNodes.push(node);
            }

            // Track processed nodes to avoid double-processing
            const processedNodes = new Set();

            // Update each text node with corrected relative date
            textNodes.forEach(textNode => {
                if (processedNodes.has(textNode)) return;
                processedNodes.add(textNode);

                let originalText = textNode.textContent;
                let newText = originalText;

                relativePatterns.forEach(pattern => {
                    newText = newText.replace(pattern, (match, amount, unit) => {
                        // Convert original upload date to be relative to our selected date
                        const normalizedUnit = this.normalizeTimeUnit(unit);
                        const originalUploadDate = this.calculateOriginalDate(amount, normalizedUnit, new Date());

                        // Apply 1-year leniency for future date detection
                        const maxDateWithLeniency = new Date(maxDate);
                        maxDateWithLeniency.setFullYear(maxDateWithLeniency.getFullYear() + 1);

                        if (originalUploadDate <= maxDate) {
                            // Video is within time machine date - update normally
                            const relativeToSelected = this.calculateRelativeDate(originalUploadDate, maxDate);
                            return relativeToSelected || match;
                        } else if (originalUploadDate <= maxDateWithLeniency) {
                            // Video is within 1-year leniency - show random months from 6-11
                            const randomMonths = Math.floor(Math.random() * 6) + 6; // 6-11 months
                            return `${randomMonths} month${randomMonths > 1 ? 's' : ''} ago`;
                        } else {
                            // Video is more than 1 year in the future - mark for removal
                            const videoElement = textNode.parentElement.closest('ytd-video-renderer, ytd-compact-video-renderer, ytd-grid-video-renderer');
                            if (videoElement) {
                                setTimeout(() => {
                                    OptimizedUtils.log(`Removing future video from search: ${match} (uploaded after ${OptimizedUtils.formatDate(maxDateWithLeniency)})`);
                                    videoElement.style.display = 'none';
                                    videoElement.remove();
                                }, 0);
                            }
                            return match; // Return original temporarily before removal
                        }
                    });
                });

                if (newText !== originalText) {
                    textNode.textContent = newText;
                }
            });
        }

        static normalizeTimeUnit(unit) {
            const unitMap = {
                'sec': 'second', 'min': 'minute', 'hr': 'hour', 'hrs': 'hour',
                'd': 'day', 'w': 'week', 'mo': 'month', 'yr': 'year'
            };
            return unitMap[unit.toLowerCase()] || unit.toLowerCase();
        }

        static calculateOriginalDate(amount, unit, fromDate) {
            const date = new Date(fromDate);
            const value = parseInt(amount);

            switch (unit) {
                case 'second':
                    date.setSeconds(date.getSeconds() - value);
                    break;
                case 'minute':
                    date.setMinutes(date.getMinutes() - value);
                    break;
                case 'hour':
                    date.setHours(date.getHours() - value);
                    break;
                case 'day':
                    date.setDate(date.getDate() - value);
                    break;
                case 'week':
                    date.setDate(date.getDate() - (value * 7));
                    break;
                case 'month':
                    date.setMonth(date.getMonth() - value);
                    break;
                case 'year':
                    date.setFullYear(date.getFullYear() - value);
                    break;
            }

            return date;
        }
    }

    // === OPTIMIZED API MANAGER ===
    class OptimizedAPIManager {
        constructor() {
            // Make API keys persistent across versions - use wayback_persistent prefix
            this.keys = GM_getValue('wayback_persistent_api_keys', []);
            this.currentKeyIndex = GM_getValue('wayback_persistent_current_key_index', 0);
            this.keyStats = GM_getValue('wayback_persistent_key_stats', {});
            this.baseUrl = 'https://www.googleapis.com/youtube/v3';
            this.viralVideoCache = new Map();
            this.requestQueue = [];
            this.activeRequests = 0;
            this.rateLimiter = new Map();



            this.init();
        }

        init() {
            const now = Date.now();
            const oneDayAgo = now - 86400000; // 24 hours

            // Reset failed keys older than 24 hours
            Object.keys(this.keyStats).forEach(key => {
                const stats = this.keyStats[key];
                if (stats.lastFailed && stats.lastFailed < oneDayAgo) {
                    stats.failed = false;
                    stats.quotaExceeded = false;
                }
            });

            this.validateKeyIndex();
            OptimizedUtils.log(`API Manager initialized with ${this.keys.length} keys`);
        }

        validateKeyIndex() {
            if (this.currentKeyIndex >= this.keys.length) {
                this.currentKeyIndex = 0;
            }
        }

        get currentKey() {
            return this.keys.length > 0 ? this.keys[this.currentKeyIndex] : null;
        }

        addKey(apiKey) {
            if (!apiKey || apiKey.length < 35 || this.keys.includes(apiKey)) {
                return false;
            }

            this.keys.push(apiKey);
            this.keyStats[apiKey] = {
                failed: false,
                quotaExceeded: false,
                lastUsed: 0,
                requestCount: 0,
                successCount: 0
            };
            this.saveKeys();
            OptimizedUtils.log(`Added API key: ${apiKey.substring(0, 8)}...`);
            return true;
        }

        removeKey(apiKey) {
            const index = this.keys.indexOf(apiKey);
            if (index === -1) return false;

            this.keys.splice(index, 1);
            delete this.keyStats[apiKey];

            // Adjust current index
            if (this.currentKeyIndex >= this.keys.length) {
                this.currentKeyIndex = Math.max(0, this.keys.length - 1);
            } else if (index <= this.currentKeyIndex && this.currentKeyIndex > 0) {
                this.currentKeyIndex--;
            }

            this.saveKeys();
            OptimizedUtils.log(`Removed API key: ${apiKey.substring(0, 8)}...`);
            return true;
        }

        rotateToNextKey() {
            if (this.keys.length <= 1) return false;

            const startIndex = this.currentKeyIndex;
            let attempts = 0;

            while (attempts < this.keys.length) {
                this.currentKeyIndex = (this.currentKeyIndex + 1) % this.keys.length;
                attempts++;

                const currentKey = this.currentKey;
                const stats = this.keyStats[currentKey];

                if (!stats || (!stats.quotaExceeded && !stats.failed)) {
                    this.saveKeys();
                    OptimizedUtils.log(`Rotated to key ${this.currentKeyIndex + 1}/${this.keys.length}`);
                    return true;
                }
            }

            this.currentKeyIndex = 0;
            this.saveKeys();
            OptimizedUtils.log('All keys have issues, reset to first key');
            return false;
        }

        markKeySuccess(apiKey) {
            const stats = this.keyStats[apiKey] || {};
            Object.assign(stats, {
                lastUsed: Date.now(),
                requestCount: (stats.requestCount || 0) + 1,
                successCount: (stats.successCount || 0) + 1,
                failed: false
            });
            this.keyStats[apiKey] = stats;
            this.saveKeys();
        }

        markKeyFailed(apiKey, errorMessage) {
            const stats = this.keyStats[apiKey] || {};
            stats.failed = true;
            stats.lastFailed = Date.now();

            const quotaErrors = ['quota', 'exceeded', 'dailylimitexceeded', 'ratelimitexceeded'];
            if (quotaErrors.some(error => errorMessage.toLowerCase().includes(error))) {
                stats.quotaExceeded = true;
            }

            this.keyStats[apiKey] = stats;
            this.saveKeys();
            OptimizedUtils.log(`Key failed: ${apiKey.substring(0, 8)}... - ${errorMessage}`);
        }

        saveKeys() {
            // Use persistent storage for API keys across versions
            GM_setValue('wayback_persistent_api_keys', this.keys);
            GM_setValue('wayback_persistent_current_key_index', this.currentKeyIndex);
            GM_setValue('wayback_persistent_key_stats', this.keyStats);
        }



        getRandomUserAgent() {
            const userAgents = [
                'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
                'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0'
            ];
            return userAgents[Math.floor(Math.random() * userAgents.length)];
        }

        async testAPIKey(apiKey) {
            try {
                const response = await this.makeRequest(`https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q=test&key=${apiKey}`);
                if (response && response.items) {
                    return { success: true, message: 'Working perfectly' };
                } else {
                    return { success: false, message: 'Invalid response format' };
                }
            } catch (error) {
                const errorMsg = error.message || error.toString();
                if (errorMsg.includes('quotaExceeded') || errorMsg.includes('dailyLimitExceeded')) {
                    return { success: false, message: 'quotaExceeded - Daily quota exceeded' };
                } else if (errorMsg.includes('keyInvalid') || errorMsg.includes('invalid')) {
                    return { success: false, message: 'keyInvalid - API key is invalid' };
                } else if (errorMsg.includes('accessNotConfigured')) {
                    return { success: false, message: 'accessNotConfigured - YouTube Data API not enabled' };
                } else {
                    return { success: false, message: errorMsg };
                }
            }
        }

        async testAllKeys() {
            const results = [];
            for (let i = 0; i < this.keys.length; i++) {
                const key = this.keys[i];
                const result = await this.testAPIKey(key);
                results.push({
                    keyIndex: i,
                    keyPreview: `${key.substring(0, 8)}...`,
                    result: result.success ? 'Working perfectly' : result.message
                });
                // Add delay between requests to avoid rate limiting
                await new Promise(resolve => setTimeout(resolve, 500));
            }
            return results;
        }

        getCache(key, forceRefresh = false) {
            if (forceRefresh) return null;

            const cached = GM_getValue(`cache_${key}`, null);
            if (cached) {
                try {
                    const data = JSON.parse(cached);
                    if (Date.now() - data.timestamp < CONFIG.cacheExpiry.videos) {
                        return data.value;
                    }
                } catch (e) {
                    // Invalid cache entry
                }
            }
            return null;
        }

        setCache(key, value, forceRefresh = false) {
            const cacheData = {
                timestamp: Date.now(),
                value: value
            };
            GM_setValue(`cache_${key}`, JSON.stringify(cacheData));
        }

        clearCache() {
            const keys = GM_listValues();
            keys.forEach(key => {
                if (key.startsWith('cache_')) {
                    GM_deleteValue(key);
                }
            });
        }

        generateRealisticViewCount(publishedAt, referenceDate) {
            const videoDate = new Date(publishedAt);
            const refDate = new Date(referenceDate);
            const daysSinceUpload = Math.floor((refDate - videoDate) / (1000 * 60 * 60 * 24));

            let minViews, maxViews;

            if (daysSinceUpload <= 1) {
                minViews = 50;
                maxViews = 10000;
            } else if (daysSinceUpload <= 7) {
                minViews = 500;
                maxViews = 100000;
            } else if (daysSinceUpload <= 30) {
                minViews = 2000;
                maxViews = 500000;
            } else if (daysSinceUpload <= 365) {
                minViews = 5000;
                maxViews = 2000000;
            } else {
                minViews = 10000;
                maxViews = 5000000;
            }

            const randomViews = Math.floor(Math.random() * (maxViews - minViews) + minViews);
            return this.formatViewCount(randomViews);
        }

        formatViewCount(count) {
            if (count >= 1000000) {
                return (count / 1000000).toFixed(1) + 'M';
            } else if (count >= 1000) {
                return (count / 1000).toFixed(1) + 'K';
            }
            return count.toString();
        }

        async makeRequest(endpoint, params) {
            return new Promise((resolve, reject) => {
                if (this.keys.length === 0) {
                    reject(new Error('No API keys available'));
                    return;
                }

                this.requestQueue.push({ endpoint, params, resolve, reject, attempts: 0 });
                this.processQueue();
            });
        }

        async processQueue() {
            if (this.activeRequests >= CONFIG.maxConcurrentRequests || this.requestQueue.length === 0) {
                return;
            }

            const request = this.requestQueue.shift();
            this.activeRequests++;

            try {
                const result = await this.executeRequest(request);
                request.resolve(result);
            } catch (error) {
                request.reject(error);
            } finally {
                this.activeRequests--;
                setTimeout(() => this.processQueue(), CONFIG.apiCooldown);
            }
        }

        async executeRequest(request) {
            const maxAttempts = Math.min(this.keys.length, 10);

            if (request.attempts >= maxAttempts) {
                throw new Error('All API keys exhausted');
            }

            const currentKey = this.currentKey;
            if (!currentKey) {
                throw new Error('No valid API key');
            }

            // Rate limiting per key
            const now = Date.now();
            const keyRateLimit = this.rateLimiter.get(currentKey) || 0;
            if (now < keyRateLimit) {
                await OptimizedUtils.sleep(keyRateLimit - now);
            }

            const urlParams = new URLSearchParams({ ...request.params, key: currentKey });
            const url = `${request.endpoint}?${urlParams}`;

            OptimizedUtils.log(`Request attempt ${request.attempts + 1} with key ${this.currentKeyIndex + 1}`);

            return new Promise((resolve, reject) => {
                // Get proxy configuration if enabled
                const requestConfig = {
                    method: 'GET',
                    url: url,
                    timeout: 10000,
                    headers: { 
                        'Accept': 'application/json',
                        'User-Agent': this.getRandomUserAgent()
                    }
                };



                GM_xmlhttpRequest({
                    ...requestConfig,
                    onload: (response) => {
                        this.rateLimiter.set(currentKey, Date.now() + 100); // 100ms rate limit per key

                        // Debug logging for API responses
                        OptimizedUtils.log(`📥 API Response: ${response.status} for ${url.split('?')[0]}`);
                        if (requestConfig.proxy) {
                            OptimizedUtils.log(`🔄 Response came through proxy: ${requestConfig.proxy.host}:${requestConfig.proxy.port}`);
                        }

                        if (response.status === 200) {
                            try {
                                const data = JSON.parse(response.responseText);
                                this.markKeySuccess(currentKey);

                                // Log success stats
                                const itemCount = data.items ? data.items.length : 0;
                                OptimizedUtils.log(`✅ API Success: Retrieved ${itemCount} items`);

                                resolve(data);
                            } catch (e) {
                                OptimizedUtils.log(`❌ JSON Parse Error: ${e.message}`);
                                reject(new Error('Invalid JSON response'));
                            }
                        } else if (response.status === 403) {
                            // Specific handling for quota exceeded
                            let errorMessage = `HTTP ${response.status}`;
                            try {
                                const errorData = JSON.parse(response.responseText);
                                if (errorData.error?.message) {
                                    errorMessage = errorData.error.message;
                                    if (errorMessage.includes('quota') || errorMessage.includes('limit')) {
                                        OptimizedUtils.log(`🚫 Quota exceeded for key ${this.currentKeyIndex + 1}: ${errorMessage}`);
                                        this.keyStats[currentKey].quotaExceeded = true;
                                    }
                                }
                            } catch (e) {
                                // Use default error message
                            }

                            this.markKeyFailed(currentKey, errorMessage);

                            if (this.rotateToNextKey()) {
                                request.attempts++;
                                OptimizedUtils.log(`🔄 Rotating to next key after quota error, attempt ${request.attempts}`);
                                setTimeout(() => {
                                    this.executeRequest(request).then(resolve).catch(reject);
                                }, 500);
                            } else {
                                reject(new Error(`API Error: ${errorMessage}`));
                            }
                        } else {
                            let errorMessage = `HTTP ${response.status}`;
                            try {
                                const errorData = JSON.parse(response.responseText);
                                if (errorData.error?.message) {
                                    errorMessage = errorData.error.message;
                                }
                            } catch (e) {
                                // Use default error message
                            }

                            OptimizedUtils.log(`❌ API Error ${response.status}: ${errorMessage}`);
                            this.markKeyFailed(currentKey, errorMessage);

                            if (this.rotateToNextKey()) {
                                request.attempts++;
                                setTimeout(() => {
                                    this.executeRequest(request).then(resolve).catch(reject);
                                }, 500);
                            } else {
                                reject(new Error(`API Error: ${errorMessage}`));
                            }
                        }
                    },
                    onerror: (error) => {
                        OptimizedUtils.log(`🔥 Network Error for ${url.split('?')[0]}:`, error);



                        this.markKeyFailed(currentKey, 'Network error');
                        if (this.rotateToNextKey()) {
                            request.attempts++;
                            OptimizedUtils.log(`🔄 Retrying after network error, attempt ${request.attempts}`);
                            setTimeout(() => {
                                this.executeRequest(request).then(resolve).catch(reject);
                            }, 1000);
                        } else {
                            reject(new Error(`Network error: ${error.error || 'Connection failed'}`));
                        }
                    }
                });
            });
        }

        async searchVideos(query, options = {}) {
            const params = {
                part: 'snippet',
                type: 'video',
                order: options.order || 'relevance',
                maxResults: options.maxResults || 50,
                q: query,
                ...options.additionalParams
            };

            if (options.publishedAfter) {
                params.publishedAfter = options.publishedAfter.toISOString();
            }
            if (options.publishedBefore) {
                params.publishedBefore = options.publishedBefore.toISOString();
            }

            try {
                const data = await this.makeRequest(`${this.baseUrl}/search`, params);
                // Normalize search results to match video format expected by other parts of the code
                const items = data.items || [];
                return items.map(item => ({
                    id: item.id?.videoId || item.id,
                    snippet: item.snippet
                }));
            } catch (error) {
                OptimizedUtils.log('Search videos error:', error.message);
                return [];
            }
        }

        async getChannelVideos(channelId, options = {}) {
            const params = {
                part: 'snippet',
                channelId: channelId,
                type: 'video',
                order: options.order || 'date',
                maxResults: options.maxResults || CONFIG.videosPerChannel,
                ...options.additionalParams
            };

            if (options.publishedAfter) {
                params.publishedAfter = options.publishedAfter.toISOString();
            }
            if (options.publishedBefore) {
                params.publishedBefore = options.publishedBefore.toISOString();
            }

            try {
                const data = await this.makeRequest(`${this.baseUrl}/search`, params);
                // Normalize search results to match video format expected by other parts of the code
                const items = data.items || [];
                return items.map(item => ({
                    id: item.id?.videoId || item.id,
                    snippet: item.snippet
                }));
            } catch (error) {
                OptimizedUtils.log('Channel videos error:', error.message);
                return [];
            }
        }

        async getVideoDetails(videoIds) {
            if (!Array.isArray(videoIds)) videoIds = [videoIds];

            const params = {
                part: 'snippet,statistics',
                id: videoIds.join(',')
            };

            try {
                const data = await this.makeRequest(`${this.baseUrl}/videos`, params);
                return data.items || [];
            } catch (error) {
                OptimizedUtils.log('Video details error:', error.message);
                return [];
            }
        }

        async getChannelDetails(channelId) {
            const params = {
                part: 'snippet,statistics',
                id: channelId
            };

            try {
                const data = await this.makeRequest(`${this.baseUrl}/channels`, params);
                return data.items?.[0] || null;
            } catch (error) {
                OptimizedUtils.log('Channel details error:', error.message);
                return null;
            }
        }

        async getViralVideos(timeframe) {
            const cacheKey = `viral_${timeframe.start}_${timeframe.end}`;

            if (this.viralVideoCache.has(cacheKey)) {
                const cached = this.viralVideoCache.get(cacheKey);
                if (Date.now() - cached.timestamp < CONFIG.cacheExpiry.videos) {
                    return cached.data;
                }
            }

            try {
                const params = {
                    part: 'snippet,statistics',
                    chart: 'mostPopular',
                    maxResults: CONFIG.viralVideosCount,
                    publishedAfter: timeframe.start.toISOString(),
                    publishedBefore: timeframe.end.toISOString()
                };

                const data = await this.makeRequest(`${this.baseUrl}/videos`, params);
                const videos = data.items || [];

                this.viralVideoCache.set(cacheKey, {
                    data: videos,
                    timestamp: Date.now()
                });

                return videos;
            } catch (error) {
                OptimizedUtils.log('Viral videos error:', error.message);
                return [];
            }
        }

        getKeyStats() {
            return {
                totalKeys: this.keys.length,
                currentKey: this.currentKeyIndex + 1,
                stats: this.keyStats
            };
        }

        clearCache() {
            this.viralVideoCache.clear();
            OptimizedUtils.log('API cache cleared');
        }
    }

    // === PERSISTENT VIDEO CACHE ===
    class PersistentVideoCache {
        constructor() {
            this.prefix = 'wayback_video_cache_';
            this.indexKey = 'wayback_video_cache_index';
            this.loadIndex();
        }

        loadIndex() {
            this.index = GM_getValue(this.indexKey, {});
        }

        saveIndex() {
            GM_setValue(this.indexKey, this.index);
        }

        get(key) {
            const fullKey = this.prefix + key;
            const cached = GM_getValue(fullKey, null);
            
            if (!cached) {
                OptimizedUtils.log(`Cache MISS: ${key}`);
                return null;
            }

            try {
                const data = typeof cached === 'string' ? JSON.parse(cached) : cached;
                
                // Check if cache has expired
                if (data.expiry && Date.now() > data.expiry) {
                    OptimizedUtils.log(`Cache EXPIRED: ${key}`);
                    this.delete(key);
                    return null;
                }
                
                OptimizedUtils.log(`Cache HIT: ${key} - ${data.value ? data.value.length : 0} videos`);
                return data.value;
            } catch (e) {
                OptimizedUtils.log('Cache parse error:', e);
                this.delete(key);
                return null;
            }
        }

        set(key, value, expiryMs = CONFIG.cacheExpiry.videos) {
            const fullKey = this.prefix + key;
            const data = {
                value: value,
                timestamp: Date.now(),
                expiry: Date.now() + expiryMs
            };
            
            GM_setValue(fullKey, JSON.stringify(data));
            
            // Update index
            this.index[key] = {
                timestamp: data.timestamp,
                expiry: data.expiry,
                size: value ? value.length : 0
            };
            this.saveIndex();
            
            OptimizedUtils.log(`Cache SET: ${key} - ${value ? value.length : 0} videos (expires in ${Math.round(expiryMs/1000/60)} minutes)`);
        }

        has(key) {
            return this.get(key) !== null;
        }

        delete(key) {
            const fullKey = this.prefix + key;
            GM_deleteValue(fullKey);
            delete this.index[key];
            this.saveIndex();
            OptimizedUtils.log(`Cache DELETE: ${key}`);
        }

        clear() {
            // Clear all cached entries
            Object.keys(this.index).forEach(key => {
                const fullKey = this.prefix + key;
                GM_deleteValue(fullKey);
            });
            
            // Clear index
            this.index = {};
            this.saveIndex();
            OptimizedUtils.log('Video cache CLEARED');
        }

        size() {
            return Object.keys(this.index).length;
        }

        // For debugging - show all cache entries
        debug() {
            console.log('=== Video Cache Debug ===');
            console.log(`Total entries: ${this.size()}`);
            Object.entries(this.index).forEach(([key, info]) => {
                const remaining = info.expiry - Date.now();
                const minutes = Math.round(remaining / 1000 / 60);
                console.log(`${key}: ${info.size} videos, expires in ${minutes} minutes`);
            });
        }
    }

    // === OPTIMIZED CACHE MANAGER ===
    class OptimizedCacheManager {
        constructor() {
            this.prefix = 'ytCache_';
            this.memoryCache = new Map();
            this.maxMemoryCacheSize = 1000;
            this.cacheHitCount = 0;
            this.cacheMissCount = 0;
        }

        generateKey(type, ...params) {
            return `${this.prefix}${type}_${params.join('_')}`;
        }

        set(type, data, expiry = CONFIG.cacheExpiry.videos, ...params) {
            const key = this.generateKey(type, ...params);
            const cacheData = {
                data,
                timestamp: Date.now(),
                expiry
            };

            // Store in memory cache with size limit
            if (this.memoryCache.size >= this.maxMemoryCacheSize) {
                const firstKey = this.memoryCache.keys().next().value;
                this.memoryCache.delete(firstKey);
            }

            this.memoryCache.set(key, cacheData);

            // Store in GM storage for persistence
            try {
                GM_setValue(key, JSON.stringify(cacheData));
            } catch (error) {
                OptimizedUtils.log('Cache set error:', error.message);
            }
        }

        get(type, ...params) {
            const key = this.generateKey(type, ...params);

            // Check memory cache first
            if (this.memoryCache.has(key)) {
                const cached = this.memoryCache.get(key);
                if (Date.now() - cached.timestamp < cached.expiry) {
                    this.cacheHitCount++;
                    return cached.data;
                } else {
                    this.memoryCache.delete(key);
                }
            }

            // Check GM storage
            try {
                const cached = GM_getValue(key);
                if (cached) {
                    const parsedCache = JSON.parse(cached);
                    if (Date.now() - parsedCache.timestamp < parsedCache.expiry) {
                        // Add back to memory cache
                        this.memoryCache.set(key, parsedCache);
                        this.cacheHitCount++;
                        return parsedCache.data;
                    } else {
                        GM_deleteValue(key);
                    }
                }
            } catch (error) {
                OptimizedUtils.log('Cache get error:', error.message);
            }

            this.cacheMissCount++;
            return null;
        }

        delete(type, ...params) {
            const key = this.generateKey(type, ...params);
            this.memoryCache.delete(key);
            try {
                GM_deleteValue(key);
            } catch (error) {
                OptimizedUtils.log('Cache delete error:', error.message);
            }
        }

        clear(pattern = null) {
            if (!pattern) {
                this.memoryCache.clear();
                try {
                    const keys = GM_listValues().filter(key => key.startsWith(this.prefix));
                    keys.forEach(key => GM_deleteValue(key));
                    OptimizedUtils.log('All cache cleared');
                } catch (error) {
                    OptimizedUtils.log('Cache clear error:', error.message);
                }
                return;
            }

            // Clear by pattern
            const keysToDelete = [];
            for (const [key] of this.memoryCache) {
                if (key.includes(pattern)) {
                    keysToDelete.push(key);
                }
            }

            keysToDelete.forEach(key => {
                this.memoryCache.delete(key);
                try {
                    GM_deleteValue(key);
                } catch (error) {
                    OptimizedUtils.log('Cache pattern delete error:', error.message);
                }
            });

            OptimizedUtils.log(`Cache cleared for pattern: ${pattern}`);
        }

        getStats() {
            const hitRate = this.cacheHitCount + this.cacheMissCount > 0 
                ? (this.cacheHitCount / (this.cacheHitCount + this.cacheMissCount) * 100).toFixed(2)
                : 0;

            return {
                memorySize: this.memoryCache.size,
                hitRate: `${hitRate}%`,
                hits: this.cacheHitCount,
                misses: this.cacheMissCount
            };
        }

        cleanup() {
            const now = Date.now();
            const expiredKeys = [];

            for (const [key, cached] of this.memoryCache) {
                if (now - cached.timestamp >= cached.expiry) {
                    expiredKeys.push(key);
                }
            }

            expiredKeys.forEach(key => {
                this.memoryCache.delete(key);
                try {
                    GM_deleteValue(key);
                } catch (error) {
                    OptimizedUtils.log('Cache cleanup error:', error.message);
                }
            });

            if (expiredKeys.length > 0) {
                OptimizedUtils.log(`Cleaned up ${expiredKeys.length} expired cache entries`);
            }
        }
    }

    // === OPTIMIZED VIDEO MANAGER ===
    class OptimizedVideoManager {
        constructor(apiManager, cacheManager) {
            this.api = apiManager;
            this.cache = cacheManager;
            this.currentTimeframe = this.getCurrentTimeframe();
            this.processingQueue = [];
            this.isProcessing = false;
            this.videoPool = new Map();
            this.channelVideoCache = new Map();
        }

        getCurrentTimeframe() {
            const selectedDate = GM_getValue('ytSelectedDate', this.getDefaultDate());
            const date = OptimizedUtils.parseDate(selectedDate);

            return {
                start: new Date(date.getFullYear(), date.getMonth(), 1),
                end: new Date(date.getFullYear(), date.getMonth() + 1, 0),
                selectedDate: date
            };
        }

        getDefaultDate() {
            const now = new Date();
            return OptimizedUtils.formatDate(new Date(now.getFullYear() - 10, now.getMonth(), now.getDate()));
        }

        setTimeframe(dateStr) {
            const date = OptimizedUtils.parseDate(dateStr);
            if (!date) return false;

            this.currentTimeframe = {
                start: new Date(date.getFullYear(), date.getMonth(), 1),
                end: new Date(date.getFullYear(), date.getMonth() + 1, 0),
                selectedDate: date
            };

            GM_setValue('ytSelectedDate', OptimizedUtils.formatDate(date));
            OptimizedUtils.log(`Timeframe set to: ${OptimizedUtils.formatDate(date)}`);
            return true;
        }

        async getVideosForChannel(channelId, count = CONFIG.videosPerChannel) {
            const cacheKey = `channel_${channelId}_${this.currentTimeframe.start.getTime()}`;

            // Check cache first
            let videos = this.cache.get('channelVideos', cacheKey);
            if (videos) {
                return OptimizedUtils.shuffleArray(videos).slice(0, count);
            }

            // Check memory pool
            if (this.channelVideoCache.has(channelId)) {
                const cached = this.channelVideoCache.get(channelId);
                if (Date.now() - cached.timestamp < CONFIG.cacheExpiry.channelVideos) {
                    return OptimizedUtils.shuffleArray(cached.videos).slice(0, count);
                }
            }

            try {
                videos = await this.api.getChannelVideos(channelId, {
                    publishedAfter: this.currentTimeframe.start,
                    publishedBefore: this.currentTimeframe.end,
                    maxResults: count * 2, // Get more for better randomization
                    order: 'relevance'
                });

                if (videos.length > 0) {
                    this.cache.set('channelVideos', videos, CONFIG.cacheExpiry.channelVideos, cacheKey);
                    this.channelVideoCache.set(channelId, {
                        videos,
                        timestamp: Date.now()
                    });
                }

                return OptimizedUtils.shuffleArray(videos).slice(0, count);
            } catch (error) {
                OptimizedUtils.log(`Error getting videos for channel ${channelId}:`, error.message);
                return [];
            }
        }

        async getHomepageVideos(count = CONFIG.maxHomepageVideos) {
            const cacheKey = `homepage_${this.currentTimeframe.selectedDate.getTime()}`;

            // Check cache
            let videos = this.cache.get('homepage', cacheKey);
            if (videos && videos.length >= count) {
                return OptimizedUtils.shuffleArray(videos).slice(0, count);
            }

            try {
                // Combine multiple search strategies
                const searchTerms = [
                    '', // General popular videos
                    'music', 'gaming', 'sports', 'news', 'entertainment',
                    'tutorial', 'review', 'funny', 'technology', 'science'
                ];

                const videoBatches = await Promise.allSettled(
                    searchTerms.slice(0, 5).map(term => 
                        this.api.searchVideos(term, {
                            publishedAfter: this.currentTimeframe.start,
                            publishedBefore: this.currentTimeframe.end,
                            order: 'relevance',
                            maxResults: Math.ceil(count / 5)
                        })
                    )
                );

                videos = videoBatches
                    .filter(result => result.status === 'fulfilled')
                    .flatMap(result => result.value)
                    .filter(video => this.isValidVideo(video));

                // Add some viral videos for the period
                const viralVideos = await this.api.getViralVideos(this.currentTimeframe);
                const viralCount = Math.floor(count * CONFIG.viralVideoPercentage);
                videos = videos.concat(viralVideos.slice(0, viralCount));

                // Remove duplicates and cache
                videos = this.removeDuplicateVideos(videos);

                if (videos.length > 0) {
                    this.cache.set('homepage', videos, CONFIG.cacheExpiry.videos, cacheKey);
                }

                return OptimizedUtils.shuffleArray(videos).slice(0, count);
            } catch (error) {
                OptimizedUtils.log('Error getting homepage videos:', error.message);
                return [];
            }
        }

        async getRecommendationVideos(currentVideoId, count = CONFIG.RECOMMENDATION_COUNT) {
            const cacheKey = `recommendations_${currentVideoId}_${this.currentTimeframe.selectedDate.getTime()}`;

            // Check cache
            let videos = this.cache.get('recommendations', cacheKey);
            if (videos && videos.length >= count) {
                return OptimizedUtils.shuffleArray(videos).slice(0, count);
            }

            try {
                const currentVideo = (await this.api.getVideoDetails([currentVideoId]))[0];
                if (!currentVideo) return [];

                const channelId = currentVideo.snippet.channelId;
                const title = currentVideo.snippet.title;
                const keywords = OptimizedUtils.extractKeywords(title);

                // Get videos from same channel
                const sameChannelCount = Math.floor(count * CONFIG.SAME_CHANNEL_RATIO);
                const sameChannelVideos = await this.getVideosForChannel(channelId, sameChannelCount);

                // Get videos from other channels using keywords
                const otherChannelCount = count - sameChannelCount;
                const keywordVideos = await this.getKeywordBasedVideos(keywords, otherChannelCount, channelId);

                videos = [...sameChannelVideos, ...keywordVideos];
                videos = this.removeDuplicateVideos(videos);

                if (videos.length > 0) {
                    this.cache.set('recommendations', videos, CONFIG.cacheExpiry.videos, cacheKey);
                }

                return OptimizedUtils.shuffleArray(videos).slice(0, count);
            } catch (error) {
                OptimizedUtils.log('Error getting recommendation videos:', error.message);
                return [];
            }
        }

        async getKeywordBasedVideos(keywords, count, excludeChannelId = null) {
            if (!keywords.length) return [];

            const searchPromises = keywords.slice(0, 3).map(keyword =>
                this.api.searchVideos(keyword, {
                    publishedAfter: this.currentTimeframe.start,
                    publishedBefore: this.currentTimeframe.end,
                    maxResults: Math.ceil(count / 3),
                    order: 'relevance'
                })
            );

            try {
                const results = await Promise.allSettled(searchPromises);
                let videos = results
                    .filter(result => result.status === 'fulfilled')
                    .flatMap(result => result.value)
                    .filter(video => this.isValidVideo(video));

                if (excludeChannelId) {
                    videos = videos.filter(video => video.snippet.channelId !== excludeChannelId);
                }

                return this.removeDuplicateVideos(videos).slice(0, count);
            } catch (error) {
                OptimizedUtils.log('Error getting keyword-based videos:', error.message);
                return [];
            }
        }

        async getChannelPageVideos(channelId, count = CONFIG.channelPageVideosPerMonth) {
            const cacheKey = `channelPage_${channelId}_${this.currentTimeframe.selectedDate.getTime()}`;

            let videos = this.cache.get('channelPage', cacheKey);
            if (videos && videos.length >= count) {
                return videos.slice(0, count);
            }

            try {
                videos = await this.api.getChannelVideos(channelId, {
                    publishedAfter: this.currentTimeframe.start,
                    publishedBefore: this.currentTimeframe.end,
                    maxResults: count,
                    order: 'date'
                });

                videos = videos.filter(video => this.isValidVideo(video));

                if (videos.length > 0) {
                    this.cache.set('channelPage', videos, CONFIG.cacheExpiry.channelVideos, cacheKey);
                }

                return videos;
            } catch (error) {
                OptimizedUtils.log(`Error getting channel page videos for ${channelId}:`, error.message);
                return [];
            }
        }

        async searchVideos(query, count = 50) {
            const cacheKey = `search_${query}_${this.currentTimeframe.selectedDate.getTime()}`;

            let videos = this.cache.get('search', cacheKey);
            if (videos && videos.length >= count) {
                return videos.slice(0, count);
            }

            try {
                videos = await this.api.searchVideos(query, {
                    publishedAfter: this.currentTimeframe.start,
                    publishedBefore: this.currentTimeframe.end,
                    maxResults: count,
                    order: 'relevance'
                });

                videos = videos.filter(video => this.isValidVideo(video));

                if (videos.length > 0) {
                    this.cache.set('search', videos, CONFIG.cacheExpiry.searchResults, cacheKey);
                }

                return videos;
            } catch (error) {
                OptimizedUtils.log(`Error searching videos for "${query}":`, error.message);
                return [];
            }
        }

        isValidVideo(video) {
            if (!video || !video.snippet) return false;

            const publishedAt = new Date(video.snippet.publishedAt);

            // Check if video is within timeframe
            if (publishedAt < this.currentTimeframe.start || publishedAt > this.currentTimeframe.end) {
                return false;
            }

            return true;
        }

        removeDuplicateVideos(videos) {
            const seen = new Set();
            return videos.filter(video => {
                const id = video.id?.videoId || video.id;
                if (seen.has(id)) return false;
                seen.add(id);
                return true;
            });
        }

        addToProcessingQueue(task) {
            this.processingQueue.push(task);
            if (!this.isProcessing) {
                this.processQueue();
            }
        }

        async processQueue() {
            if (this.processingQueue.length === 0) {
                this.isProcessing = false;
                return;
            }

            this.isProcessing = true;

            const batch = this.processingQueue.splice(0, CONFIG.batchSize);
            const promises = batch.map(task => this.executeTask(task));

            try {
                await Promise.allSettled(promises);
                await OptimizedUtils.sleep(CONFIG.apiCooldown);
                this.processQueue(); // Process next batch
            } catch (error) {
                OptimizedUtils.log('Queue processing error:', error.message);
                this.isProcessing = false;
            }
        }

        async executeTask(task) {
            try {
                const result = await task.execute();
                if (task.callback) {
                    task.callback(result);
                }
                return result;
            } catch (error) {
                OptimizedUtils.log('Task execution error:', error.message);
                if (task.errorCallback) {
                    task.errorCallback(error);
                }
                throw error;
            }
        }

        clearCache() {
            this.cache.clear('homepage');
            this.cache.clear('channelPage');
            this.cache.clear('recommendations');
            this.cache.clear('search');
            this.channelVideoCache.clear();
            this.videoPool.clear();
            OptimizedUtils.log('Video manager cache cleared');
        }

        getStats() {
            return {
                currentTimeframe: this.currentTimeframe,
                queueSize: this.processingQueue.length,
                isProcessing: this.isProcessing,
                videoPoolSize: this.videoPool.size,
                channelCacheSize: this.channelVideoCache.size
            };
        }
    }

    // === OPTIMIZED UI MANAGER ===
    class OptimizedUIManager {
        constructor(videoManager, apiManager, cacheManager) {
            this.videoManager = videoManager;
            this.apiManager = apiManager;
            this.cacheManager = cacheManager;
            this.elements = new Map();
            this.observers = new Map();
            this.eventListeners = new Map();
            this.isInitialized = false;
            this.cssInjected = false;
        }

        async init() {
            if (this.isInitialized) return;

            await this.waitForPageLoad();
            this.injectStyles();
            this.createMainInterface();
            this.setupEventListeners();
            this.startObservers();

            this.isInitialized = true;
            OptimizedUtils.log('UI Manager initialized');
        }

        async waitForPageLoad() {
            await OptimizedUtils.waitFor(() => document.body && document.head, 10000);
            await OptimizedUtils.sleep(100); // Small delay for page stabilization
        }

        injectStyles() {
            if (this.cssInjected) return;

            const styles = `
                /* WayBackTube Optimized Styles */
                #wayback-interface {
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    z-index: 10000;
                    background: rgba(0, 0, 0, 0.9);
                    border-radius: 8px;
                    padding: 15px;
                    color: white;
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
                    font-size: 14px;
                    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
                    backdrop-filter: blur(10px);
                    border: 1px solid rgba(255, 255, 255, 0.1);
                    min-width: 280px;
                    transition: all 0.3s ease;
                }

                #wayback-interface.minimized {
                    padding: 10px;
                    min-width: auto;
                }

                #wayback-header {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-bottom: 15px;
                    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
                    padding-bottom: 10px;
                }

                #wayback-title {
                    font-weight: bold;
                    font-size: 16px;
                    color: #ff6b6b;
                }

                .wayback-controls {
                    display: grid;
                    grid-template-columns: 1fr auto;
                    gap: 10px;
                    align-items: center;
                    margin-bottom: 10px;
                }

                .wayback-input {
                    background: rgba(255, 255, 255, 0.1);
                    border: 1px solid rgba(255, 255, 255, 0.3);
                    border-radius: 4px;
                    padding: 8px;
                    color: white;
                    font-size: 13px;
                    transition: all 0.2s ease;
                }

                .wayback-input:focus {
                    outline: none;
                    border-color: #ff6b6b;
                    background: rgba(255, 255, 255, 0.15);
                }

                .wayback-button {
                    background: linear-gradient(135deg, #ff6b6b, #ee5a52);
                    border: none;
                    border-radius: 4px;
                    color: white;
                    padding: 8px 12px;
                    font-size: 12px;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    font-weight: 500;
                }

                .wayback-button:hover {
                    background: linear-gradient(135deg, #ee5a52, #dd4a41);
                    transform: translateY(-1px);
                    box-shadow: 0 4px 8px rgba(255, 107, 107, 0.3);
                }

                .wayback-button:active {
                    transform: translateY(0);
                }

                .wayback-button.small {
                    padding: 6px 10px;
                    font-size: 11px;
                }

                .wayback-stats {
                    margin-top: 15px;
                    padding-top: 10px;
                    border-top: 1px solid rgba(255, 255, 255, 0.2);
                    font-size: 11px;
                    line-height: 1.4;
                }

                .wayback-stat-row {
                    display: flex;
                    justify-content: space-between;
                    margin-bottom: 4px;
                }

                .wayback-status {
                    display: inline-block;
                    padding: 2px 6px;
                    border-radius: 10px;
                    font-size: 10px;
                    font-weight: bold;
                    text-transform: uppercase;
                }

                .wayback-status.active {
                    background: rgba(76, 175, 80, 0.3);
                    color: #4CAF50;
                }

                .wayback-status.loading {
                    background: rgba(255, 193, 7, 0.3);
                    color: #FFC107;
                }

                .wayback-status.error {
                    background: rgba(244, 67, 54, 0.3);
                    color: #F44336;
                }

                .wayback-hidden {
                    display: none !important;
                }

                .wayback-loading {
                    opacity: 0.7;
                    position: relative;
                }

                .wayback-loading::after {
                    content: '';
                    position: absolute;
                    top: 0;
                    left: 0;
                    right: 0;
                    bottom: 0;
                    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
                    animation: wayback-shimmer 1.5s infinite;
                }

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

                /* Hide modern YouTube elements */
                ${CONFIG.SHORTS_SELECTORS.map(selector => `${selector}`).join(', ')} {
                    display: none !important;
                }

                ${CONFIG.CHANNEL_PAGE_SELECTORS.map(selector => `${selector}`).join(', ')} {
                    visibility: hidden !important;
                    height: 0 !important;
                    overflow: hidden !important;
                }

                /* Modern content warning */
                .wayback-warning {
                    background: rgba(255, 152, 0, 0.1);
                    border: 1px solid rgba(255, 152, 0, 0.3);
                    border-radius: 4px;
                    padding: 8px;
                    margin-top: 10px;
                    font-size: 11px;
                    color: #FF9800;
                }

                /* New sections styles */
                .wayback-section {
                    margin-top: 15px;
                    padding-top: 15px;
                    border-top: 1px solid rgba(255, 255, 255, 0.2);
                }

                .wayback-section-header {
                    margin-bottom: 10px;
                }

                .wayback-section-header h4 {
                    margin: 0 0 4px 0;
                    font-size: 14px;
                    color: #ff6b6b;
                    font-weight: bold;
                }

                .wayback-section-desc {
                    font-size: 11px;
                    color: rgba(255, 255, 255, 0.7);
                    line-height: 1.3;
                }

                .wayback-list {
                    max-height: 120px;
                    overflow-y: auto;
                    background: rgba(255, 255, 255, 0.05);
                    border: 1px solid rgba(255, 255, 255, 0.1);
                    border-radius: 4px;
                    margin: 8px 0;
                    padding: 4px;
                }

                .wayback-list::-webkit-scrollbar {
                    width: 6px;
                }

                .wayback-list::-webkit-scrollbar-track {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 3px;
                }

                .wayback-list::-webkit-scrollbar-thumb {
                    background: rgba(255, 255, 255, 0.3);
                    border-radius: 3px;
                }

                .wayback-list-item {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    padding: 6px 8px;
                    margin: 2px 0;
                    background: rgba(255, 255, 255, 0.05);
                    border-radius: 3px;
                    font-size: 12px;
                }

                .wayback-list-item:hover {
                    background: rgba(255, 255, 255, 0.1);
                }

                .wayback-item-text {
                    flex: 1;
                    color: white;
                    text-overflow: ellipsis;
                    overflow: hidden;
                    white-space: nowrap;
                    margin-right: 8px;
                }

                .wayback-remove-btn {
                    background: rgba(244, 67, 54, 0.8);
                    border: none;
                    border-radius: 50%;
                    color: white;
                    width: 20px;
                    height: 20px;
                    cursor: pointer;
                    font-size: 12px;
                    font-weight: bold;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    transition: all 0.2s ease;
                }

                .wayback-remove-btn:hover {
                    background: rgba(244, 67, 54, 1);
                    transform: scale(1.1);
                }

                .wayback-button.secondary {
                    background: rgba(255, 255, 255, 0.1);
                    border: 1px solid rgba(255, 255, 255, 0.3);
                    color: rgba(255, 255, 255, 0.9);
                }

                .wayback-button.secondary:hover {
                    background: rgba(255, 255, 255, 0.2);
                    border-color: rgba(255, 255, 255, 0.5);
                    transform: translateY(-1px);
                }

                /* Responsive design */
                @media (max-width: 768px) {
                    #wayback-interface {
                        position: fixed;
                        top: auto;
                        bottom: 20px;
                        right: 20px;
                        left: 20px;
                        min-width: auto;
                    }
                }
            `;

            // Simple 2011 Theme: Blue text + Square corners
            const vintage2011CSS = `
                /* Simple 2011 Theme - VERY VISIBLE TEST */
                body.wayback-2011-theme {
                    /* Blue text for all links and video titles */
                    --yt-spec-text-primary: #0066cc !important;
                    --yt-spec-text-secondary: #0066cc !important;
                    /* Normal background - remove testing colors */
                }

                /* Video titles - blue text with more specific selectors */
                body.wayback-2011-theme h3 a,
                body.wayback-2011-theme #video-title,
                body.wayback-2011-theme ytd-video-renderer h3 a,
                body.wayback-2011-theme .ytd-video-renderer h3 a,
                body.wayback-2011-theme a[id="video-title-link"],
                body.wayback-2011-theme ytd-video-primary-info-renderer h1 a {
                    color: #0066cc !important;
                }

                /* Channel names - blue text */
                body.wayback-2011-theme ytd-channel-name a,
                body.wayback-2011-theme .ytd-channel-name a,
                body.wayback-2011-theme #channel-name a,
                body.wayback-2011-theme .ytd-video-secondary-info-renderer a {
                    color: #0066cc !important;
                }

                /* All links should be blue */
                body.wayback-2011-theme a {
                    color: #0066cc !important;
                }

                /* Remove ALL rounded corners - make everything square */
                body.wayback-2011-theme *,
                body.wayback-2011-theme *:before,
                body.wayback-2011-theme *:after {
                    border-radius: 0 !important;
                    -webkit-border-radius: 0 !important;
                    -moz-border-radius: 0 !important;
                }

                /* Square thumbnails */
                body.wayback-2011-theme ytd-thumbnail img,
                body.wayback-2011-theme .ytd-thumbnail img,
                body.wayback-2011-theme img {
                    border-radius: 0 !important;
                }

                /* Square buttons */
                body.wayback-2011-theme button,
                body.wayback-2011-theme .yt-spec-button-shape-next,
                body.wayback-2011-theme .yt-spec-button-shape-next__button {
                    border-radius: 0 !important;
                }

                /* Square search box */
                body.wayback-2011-theme input,
                body.wayback-2011-theme #search-form,
                body.wayback-2011-theme ytd-searchbox,
                body.wayback-2011-theme #search-form input {
                    border-radius: 0 !important;
                }

                /* Square video containers */
                body.wayback-2011-theme ytd-video-renderer,
                body.wayback-2011-theme ytd-rich-item-renderer,
                body.wayback-2011-theme .ytd-video-renderer,
                body.wayback-2011-theme .ytd-rich-item-renderer {
                    border-radius: 0 !important;
                }

                /* Remove ALL modern animations and hover effects */
                body.wayback-2011-theme *,
                body.wayback-2011-theme *:before,
                body.wayback-2011-theme *:after {
                    transition: none !important;
                    animation: none !important;
                    transform: none !important;
                    -webkit-transition: none !important;
                    -webkit-animation: none !important;
                    -webkit-transform: none !important;
                    -moz-transition: none !important;
                    -moz-animation: none !important;
                    -moz-transform: none !important;
                }

                /* Disable hover animations on video thumbnails and containers */
                body.wayback-2011-theme ytd-video-renderer:hover,
                body.wayback-2011-theme ytd-rich-item-renderer:hover,
                body.wayback-2011-theme .ytd-video-renderer:hover,
                body.wayback-2011-theme .ytd-rich-item-renderer:hover {
                    transform: none !important;
                    box-shadow: none !important;
                    transition: none !important;
                }

                /* Disable thumbnail hover effects */
                body.wayback-2011-theme ytd-thumbnail:hover,
                body.wayback-2011-theme .ytd-thumbnail:hover {
                    transform: none !important;
                    transition: none !important;
                }

                /* Disable button hover animations */
                body.wayback-2011-theme button:hover,
                body.wayback-2011-theme .yt-spec-button-shape-next:hover {
                    transform: none !important;
                    transition: none !important;
                }

                /* Remove elevation/shadow effects */
                body.wayback-2011-theme * {
                    box-shadow: none !important;
                    filter: none !important;
                    backdrop-filter: none !important;
                }
            `;

            // Inject styles into page head for better CSS priority
            const styleElement = document.createElement('style');
            styleElement.textContent = styles + '\n' + vintage2011CSS;
            document.head.appendChild(styleElement);
            
            // Also use GM_addStyle as backup
            GM_addStyle(styles);
            GM_addStyle(vintage2011CSS);
            
            this.cssInjected = true;
            OptimizedUtils.log('Styles injected successfully (including 2011 vintage theme)');
        }

        createMainInterface() {
            if (this.elements.has('main')) return;

            const mainDiv = document.createElement('div');
            mainDiv.id = 'wayback-interface';

            const selectedDate = GM_getValue('ytSelectedDate', this.videoManager.getDefaultDate());
            const isActive = GM_getValue('ytActive', false);

            mainDiv.innerHTML = `
                <div id="wayback-header">
                    <div id="wayback-title">⏰ WayBackTube</div>
                    <button id="wayback-minimize" class="wayback-button small">–</button>
                </div>
                <div id="wayback-content">
                    <div class="wayback-controls">
                        <input type="date" id="wayback-date-input" class="wayback-input" value="${selectedDate}">
                        <button id="wayback-toggle" class="wayback-button">${isActive ? 'Disable' : 'Enable'}</button>
                    </div>

                    <div class="wayback-controls">
                        <button id="wayback-refresh" class="wayback-button">🔄 Refresh</button>
                        <button id="wayback-advance-date" class="wayback-button">📅 Advance Date</button>
                        <button id="wayback-vintage-toggle" class="wayback-button wayback-vintage-toggle">🕰️ 2011 Theme</button>
                        <button id="wayback-settings" class="wayback-button">⚙️</button>
                    </div>

                    <div id="wayback-stats" class="wayback-stats">
                        <div class="wayback-stat-row">
                            <span>Status:</span>
                            <span class="wayback-status ${isActive ? 'active' : 'error'}" id="wayback-status">
                                ${isActive ? 'Active' : 'Inactive'}
                            </span>
                        </div>
                        <div class="wayback-stat-row">
                            <span>Date:</span>
                            <span id="wayback-current-date">${selectedDate}</span>
                        </div>
                        <div class="wayback-stat-row">
                            <span>Page:</span>
                            <span id="wayback-current-page">${OptimizedUtils.getCurrentPage()}</span>
                        </div>
                        <div class="wayback-stat-row">
                            <span>Clock:</span>
                            <span id="wayback-clock-display" style="font-family: monospace; color: #00ff00;">
                                ${GM_getValue('ytTestClockEnabled', false) ? 'Day 0, 00:00:00' : 'Not running'}
                            </span>
                        </div>
                    </div>

                    <div id="wayback-api-section" style="display: none;">
                        <div class="wayback-controls">
                            <input type="password" id="wayback-api-key" class="wayback-input" placeholder="Enter YouTube API Key">
                            <button id="wayback-add-key" class="wayback-button">Add</button>
                        </div>
                        <div class="wayback-controls">
                            <button id="wayback-test-keys" class="wayback-button" style="width: 100%;">Test All API Keys</button>
                        </div>
                        <div id="wayback-key-stats"></div>
                    </div>

                    <!-- Subscriptions Management Section -->
                    <div class="wayback-section">
                        <div class="wayback-section-header">
                            <h4>📺 Channel Subscriptions</h4>
                            <span class="wayback-section-desc">Add channel names to load videos from</span>
                        </div>
                        <div class="wayback-controls">
                            <input type="text" id="wayback-subscription-input" class="wayback-input" placeholder="Enter channel name..." maxlength="50">
                            <button id="wayback-add-subscription" class="wayback-button">Add</button>
                        </div>
                        <div id="wayback-subscriptions-list" class="wayback-list">
                            <!-- Subscriptions will be populated here -->
                        </div>
                        <div class="wayback-controls">
                            <button id="wayback-clear-subscriptions" class="wayback-button secondary">Clear All</button>
                            <button id="wayback-load-homepage" class="wayback-button">Load Videos</button>
                        </div>
                    </div>

                    <!-- Search Terms Management Section -->
                    <div class="wayback-section">
                        <div class="wayback-section-header">
                            <h4>🔍 Search Terms</h4>
                            <span class="wayback-section-desc">Add search terms to discover content (memes, gaming, etc.)</span>
                        </div>
                        <div class="wayback-controls">
                            <input type="text" id="wayback-search-term-input" class="wayback-input" placeholder="Enter search term..." maxlength="50">
                            <button id="wayback-add-search-term" class="wayback-button">Add</button>
                        </div>
                        <div id="wayback-search-terms-list" class="wayback-list">
                            <!-- Search terms will be populated here -->
                        </div>
                        <div class="wayback-controls">
                            <button id="wayback-clear-search-terms" class="wayback-button secondary">Clear All</button>
                            <button id="wayback-load-search-videos" class="wayback-button">Load Videos</button>
                        </div>
                    </div>
                </div>
            `;

            document.body.appendChild(mainDiv);
            this.elements.set('main', mainDiv);

            // Setup element references
            this.elements.set('dateInput', OptimizedUtils.$('#wayback-date-input'));
            this.elements.set('toggleButton', OptimizedUtils.$('#wayback-toggle'));
            this.elements.set('refreshButton', OptimizedUtils.$('#wayback-refresh'));
            this.elements.set('advanceDateButton', OptimizedUtils.$('#wayback-advance-date'));
            this.elements.set('vintageToggleButton', OptimizedUtils.$('#wayback-vintage-toggle'));
            this.elements.set('settingsButton', OptimizedUtils.$('#wayback-settings'));
            this.elements.set('minimizeButton', OptimizedUtils.$('#wayback-minimize'));
            this.elements.set('statusElement', OptimizedUtils.$('#wayback-status'));
            this.elements.set('currentDate', OptimizedUtils.$('#wayback-current-date'));
            this.elements.set('currentPage', OptimizedUtils.$('#wayback-current-page'));
            this.elements.set('apiSection', OptimizedUtils.$('#wayback-api-section'));
            this.elements.set('apiKeyInput', OptimizedUtils.$('#wayback-api-key'));
            this.elements.set('addKeyButton', OptimizedUtils.$('#wayback-add-key'));
            this.elements.set('testKeysButton', OptimizedUtils.$('#wayback-test-keys'));
            this.elements.set('keyStatsDiv', OptimizedUtils.$('#wayback-key-stats'));

            // Subscription management elements
            this.elements.set('subscriptionInput', OptimizedUtils.$('#wayback-subscription-input'));
            this.elements.set('addSubscriptionButton', OptimizedUtils.$('#wayback-add-subscription'));
            this.elements.set('subscriptionsList', OptimizedUtils.$('#wayback-subscriptions-list'));
            this.elements.set('clearSubscriptionsButton', OptimizedUtils.$('#wayback-clear-subscriptions'));
            this.elements.set('loadHomepageButton', OptimizedUtils.$('#wayback-load-homepage'));

            // Search terms management elements
            this.elements.set('searchTermInput', OptimizedUtils.$('#wayback-search-term-input'));
            this.elements.set('addSearchTermButton', OptimizedUtils.$('#wayback-add-search-term'));
            this.elements.set('searchTermsList', OptimizedUtils.$('#wayback-search-terms-list'));
            this.elements.set('clearSearchTermsButton', OptimizedUtils.$('#wayback-clear-search-terms'));
            this.elements.set('loadSearchVideosButton', OptimizedUtils.$('#wayback-load-search-videos'));

            // Initialize the UI with existing data
            this.initializeUI();

            OptimizedUtils.log('Main interface created');
        }

        setupEventListeners() {
            const throttledRefresh = OptimizedUtils.throttle(() => this.handleRefresh(), 1000);
            const debouncedDateChange = OptimizedUtils.debounce((date) => this.handleDateChange(date), 500);

            // Main controls
            this.addEventListenerSafe('dateInput', 'change', (e) => {
                debouncedDateChange(e.target.value);
            });

            this.addEventListenerSafe('toggleButton', 'click', () => this.handleToggle());
            this.addEventListenerSafe('refreshButton', 'click', throttledRefresh);
            this.addEventListenerSafe('advanceDateButton', 'click', () => this.handleAdvanceDate());
            this.addEventListenerSafe('vintageToggleButton', 'click', () => this.handleVintageToggle());
            this.addEventListenerSafe('settingsButton', 'click', () => this.toggleApiSection());
            this.addEventListenerSafe('minimizeButton', 'click', () => this.toggleMinimize());

            // API management
            this.addEventListenerSafe('addKeyButton', 'click', () => this.handleAddApiKey());
            this.addEventListenerSafe('testKeysButton', 'click', () => this.handleTestApiKeys());
            this.addEventListenerSafe('apiKeyInput', 'keypress', (e) => {
                if (e.key === 'Enter') this.handleAddApiKey();
            });

            // Subscription management
            this.addEventListenerSafe('addSubscriptionButton', 'click', () => this.handleAddSubscription());
            this.addEventListenerSafe('subscriptionInput', 'keypress', (e) => {
                if (e.key === 'Enter') this.handleAddSubscription();
            });
            this.addEventListenerSafe('clearSubscriptionsButton', 'click', () => this.handleClearSubscriptions());
            this.addEventListenerSafe('loadHomepageButton', 'click', () => this.handleLoadHomepage());

            // Search terms management
            this.addEventListenerSafe('addSearchTermButton', 'click', () => this.handleAddSearchTerm());
            this.addEventListenerSafe('searchTermInput', 'keypress', (e) => {
                if (e.key === 'Enter') this.handleAddSearchTerm();
            });
            this.addEventListenerSafe('clearSearchTermsButton', 'click', () => this.handleClearSearchTerms());
            this.addEventListenerSafe('loadSearchVideosButton', 'click', () => this.handleLoadSearchVideos());

            // Event delegation for remove buttons
            this.elements.get('main').addEventListener('click', (e) => {
                if (e.target.classList.contains('wayback-remove-btn')) {
                    if (e.target.dataset.subscription) {
                        this.handleRemoveSubscription(e.target.dataset.subscription);
                    } else if (e.target.dataset.searchTerm) {
                        this.handleRemoveSearchTerm(e.target.dataset.searchTerm);
                    }
                }
            });

            // URL change detection
            let lastUrl = location.href;
            const urlObserver = new MutationObserver(() => {
                if (location.href !== lastUrl) {
                    lastUrl = location.href;
                    this.handleUrlChange();
                }
            });

            urlObserver.observe(document, { subtree: true, childList: true });
            this.observers.set('url', urlObserver);

            OptimizedUtils.log('Event listeners setup complete');
        }

        addEventListenerSafe(elementKey, event, handler) {
            const element = this.elements.get(elementKey);
            if (element) {
                element.addEventListener(event, handler);

                // Store for cleanup
                const key = `${elementKey}_${event}`;
                if (!this.eventListeners.has(key)) {
                    this.eventListeners.set(key, []);
                }
                this.eventListeners.get(key).push({ element, event, handler });
            }
        }

        handleDateChange(dateStr) {
            if (this.videoManager.setTimeframe(dateStr)) {
                this.updateInterface();
                this.handleRefresh();
                OptimizedUtils.log(`Date changed to: ${dateStr}`);
            }
        }

        handleToggle() {
            const isActive = GM_getValue('ytActive', false);
            const newState = !isActive;

            GM_setValue('ytActive', newState);
            this.updateInterface();

            if (newState) {
                this.handleRefresh();
            }

            OptimizedUtils.log(`WayBackTube ${newState ? 'enabled' : 'disabled'}`);
        }

        async handleRefresh() {
            if (!GM_getValue('ytActive', false)) return;

            this.setLoadingState(true);

            try {
                // Clear caches
                this.videoManager.clearCache();
                this.cacheManager.cleanup();

                // Wait a bit for page to stabilize
                await OptimizedUtils.sleep(500);

                // Refresh current page content
                await this.refreshCurrentPage();

                this.setLoadingState(false);
                OptimizedUtils.log('Refresh completed');
            } catch (error) {
                this.setLoadingState(false);
                OptimizedUtils.log('Refresh error:', error.message);
                this.showError('Refresh failed. Please try again.');
            }
        }

        handleAdvanceDate() {
            // Force advance date by one day
            const currentDate = new Date(this.videoManager.settings.date);
            currentDate.setDate(currentDate.getDate() + 1);

            const newDateString = currentDate.toISOString().split('T')[0];
            this.videoManager.setDate(newDateString);

            // Update the date input field
            const dateInput = this.elements.get('dateInput');
            if (dateInput) {
                dateInput.value = newDateString;
            }

            // Update last rotation time to now
            this.videoManager.settings.lastDateRotation = Date.now();
            GM_setValue('ytLastDateRotation', Date.now());

            this.showSuccess(`Date advanced to: ${newDateString}`);
            OptimizedUtils.log(`🗓️ Date manually advanced to: ${newDateString}`);

            // Refresh content with new date
            if (GM_getValue('ytActive', false)) {
                setTimeout(() => this.handleRefresh(), 500);
            }
        }

        handleVintageToggle() {
            // Let TimeMachineUI handle all vintage toggle logic to avoid conflicts
            // This method is kept for compatibility but delegates to global function
            if (window.handleGlobalVintageToggle) {
                window.handleGlobalVintageToggle();
            }
        }

        async refreshCurrentPage() {
            const context = OptimizedUtils.getPageContext();

            switch (context.page) {
                case 'home':
                    await this.refreshHomepage();
                    break;
                case 'video':
                    await this.refreshVideoPage(context.videoId);
                    break;
                case 'channel':
                    await this.refreshChannelPage(context.channelId);
                    break;
                case 'search':
                    await this.refreshSearchPage();
                    break;
                default:
                    OptimizedUtils.log('Page type not supported for refresh:', context.page);
            }
        }

        async refreshHomepage() {
            OptimizedUtils.log('Refreshing homepage...');

            // Get new videos
            const videos = await this.videoManager.getHomepageVideos();

            if (videos.length === 0) {
                this.showWarning('No videos found for selected date range');
                return;
            }

            // Replace homepage content
            this.replaceHomepageVideos(videos);
        }

        async refreshVideoPage(videoId) {
            if (!videoId) return;

            OptimizedUtils.log('Refreshing video page recommendations...');

            const videos = await this.videoManager.getRecommendationVideos(videoId);
            this.replaceVideoPageRecommendations(videos);
        }

        async refreshChannelPage(channelId) {
            if (!channelId) return;

            OptimizedUtils.log('Refreshing channel page...');

            // Get all cached videos for this channel, sorted by date
            const videos = this.getAllCachedChannelVideos(channelId);
            this.replaceChannelPageVideos(videos, channelId);
        }

        getAllCachedChannelVideos(channelId) {
            // Get videos from all cached sources for this channel
            const allVideos = [];

            // Get from subscription cache
            const subscriptionVideos = this.videoManager.videoCache.get('subscription_videos_only') || [];
            const channelSubVideos = subscriptionVideos.filter(video => video.channelId === channelId);
            allVideos.push(...channelSubVideos);

            // Get from search term cache
            const searchTermVideos = this.videoManager.videoCache.get('search_term_videos_only') || [];
            const channelSearchVideos = searchTermVideos.filter(video => video.channelId === channelId);
            allVideos.push(...channelSearchVideos);

            // Get from watched videos cache
            const watchedVideos = GM_getValue('wayback_watched_videos_cache', []);
            const channelWatchedVideos = watchedVideos.filter(video => video.channelId === channelId);
            allVideos.push(...channelWatchedVideos);

            // Remove duplicates and sort by upload date (newest first)
            const uniqueVideos = OptimizedUtils.removeDuplicates(allVideos);
            return uniqueVideos.sort((a, b) => {
                const dateA = new Date(a.publishedAt || a.snippet?.publishedAt || '2005-01-01');
                const dateB = new Date(b.publishedAt || b.snippet?.publishedAt || '2005-01-01');
                return dateB - dateA; // Newest first
            });
        }

        async refreshSearchPage() {
            const urlParams = new URLSearchParams(window.location.search);
            const query = urlParams.get('search_query');

            if (!query) return;

            OptimizedUtils.log('Refreshing search results...');

            const videos = await this.videoManager.searchVideos(query);
            this.replaceSearchResults(videos);
        }

        replaceHomepageVideos(videos) {
            // Implementation for replacing homepage videos
            const containers = OptimizedUtils.$$('#contents ytd-rich-item-renderer, #contents ytd-video-renderer');

            let videoIndex = 0;
            containers.forEach((container, index) => {
                if (videoIndex >= videos.length) return;

                const video = videos[videoIndex];
                this.replaceVideoElement(container, video);
                videoIndex++;
            });

            OptimizedUtils.log(`Replaced ${Math.min(videoIndex, videos.length)} homepage videos`);
        }

        replaceVideoPageRecommendations(videos) {
            const containers = OptimizedUtils.$$('#secondary ytd-compact-video-renderer');

            videos.slice(0, containers.length).forEach((video, index) => {
                if (containers[index]) {
                    this.replaceVideoElement(containers[index], video);
                }
            });

            OptimizedUtils.log(`Replaced ${Math.min(videos.length, containers.length)} recommendation videos`);
        }

        replaceChannelPageVideos(videos, channelId) {
            // Hide all channel content first (home and videos sections)
            CONFIG.CHANNEL_PAGE_SELECTORS.forEach(selector => {
                OptimizedUtils.$$(selector).forEach(element => {
                    element.style.display = 'none';
                });
            });

            // Completely replace with our cached videos and search button
            this.showChannelVideosWithSearchButton(videos, channelId);
        }

        showChannelVideosWithSearchButton(videos, channelId) {
            // Create a container for cached videos from all sources
            const channelContent = OptimizedUtils.$('#contents, #primary-inner');
            if (!channelContent) return;

            // Remove existing content
            const existingContent = OptimizedUtils.$('#wayback-channel-content');
            if (existingContent) {
                existingContent.remove();
            }

            // Get channel name from first video or fallback
            const channelName = videos.length > 0 ? (videos[0].channel || videos[0].snippet?.channelTitle || 'This Channel') : 'This Channel';

            // Create new channel content with search button
            const channelContainer = document.createElement('div');
            channelContainer.id = 'wayback-channel-content';
            channelContainer.innerHTML = `
                <div style="padding: 20px; background: #f9f9f9; border-radius: 8px; margin: 20px 0;">
                    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
                        <h3 style="margin: 0; color: #333;">
                            ${channelName} Videos (${videos.length} cached)
                        </h3>
                        <button id="wayback-search-more-channel" class="wayback-button" style="
                            background: #ff4444; color: white; border: none; padding: 8px 16px; 
                            border-radius: 4px; cursor: pointer; font-size: 14px;
                        ">
                            🔍 Search More Videos
                        </button>
                    </div>
                    <div id="channel-video-grid" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 15px;">
                        ${videos.length > 0 ? videos.map(video => this.createChannelVideoCard(video)).join('') : '<p style="color: #666; grid-column: 1/-1; text-align: center;">No cached videos found for this channel.</p>'}
                    </div>
                </div>
            `;

            channelContent.insertBefore(channelContainer, channelContent.firstChild);

            // Add click handler for search button
            const searchButton = OptimizedUtils.$('#wayback-search-more-channel');
            if (searchButton) {
                searchButton.addEventListener('click', () => this.searchMoreChannelVideos(channelId, channelName));
            }
        }

        createChannelVideoCard(video) {
            const videoId = video.id?.videoId || video.id;
            const snippet = video.snippet || video;

            if (!videoId || !snippet) return '';

            const thumbnailUrl = snippet.thumbnails?.medium?.url || snippet.thumbnails?.high?.url || snippet.thumbnails?.default?.url || snippet.thumbnail;
            const publishedDate = new Date(snippet.publishedAt || video.publishedAt || '2005-01-01');
            const title = snippet.title || video.title || 'Unknown Title';
            const description = snippet.description || video.description || '';
            const viewCount = video.statistics?.viewCount || video.viewCount || 'Unknown views';

            return `
                <div class="wayback-channel-video-card" style="background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1); transition: transform 0.2s;" 
                     onmouseover="this.style.transform='translateY(-2px)'" onmouseout="this.style.transform='translateY(0)'">
                    <a href="/watch?v=${videoId}" style="display: block; text-decoration: none; color: inherit;" onclick="window.waybackTubeManager.cacheWatchedVideo('${videoId}')">
                        <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
                            <img src="${thumbnailUrl}" alt="${title}" 
                                 style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;">
                        </div>
                        <div style="padding: 12px;">
                            <h4 style="margin: 0 0 8px 0; font-size: 14px; line-height: 1.3; color: #333; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;">
                                ${OptimizedUtils.cleanTitle(title)}
                            </h4>
                            <div style="font-size: 12px; color: #666; margin-bottom: 4px;">
                                ${this.formatRelativeTime(publishedDate)}
                            </div>
                            <div style="font-size: 11px; color: #888;">
                                ${typeof viewCount === 'number' ? this.formatViewCount(viewCount) : viewCount}
                            </div>
                            ${description ? `<p style="font-size: 11px; color: #999; margin: 8px 0 0 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;">${description.substring(0, 100)}...</p>` : ''}
                        </div>
                    </a>
                </div>
            `;
        }

        async searchMoreChannelVideos(channelId, channelName) {
            const searchButton = OptimizedUtils.$('#wayback-search-more-channel');
            if (searchButton) {
                searchButton.textContent = '🔍 Searching...';
                searchButton.disabled = true;
            }

            try {
                // Search for more videos from this channel using current date constraints
                const maxDate = new Date(this.settings.date);
                const newVideos = await this.apiManager.getChannelVideos(channelId, {
                    publishedBefore: maxDate,
                    maxResults: 50,
                    order: 'date'
                });

                if (newVideos && newVideos.length > 0) {
                    // Cache the new videos for this channel
                    this.cacheChannelVideos(channelId, newVideos);

                    // Refresh the channel page with updated cache
                    const allVideos = this.getAllCachedChannelVideos(channelId);
                    this.showChannelVideosWithSearchButton(allVideos, channelId);

                    this.showSuccess(`Found ${newVideos.length} more videos for ${channelName}!`);
                } else {
                    this.showWarning(`No additional videos found for ${channelName} before ${maxDate.toDateString()}`);
                }

            } catch (error) {
                OptimizedUtils.log('Error searching for more channel videos:', error);
                this.showError('Failed to search for more videos. Check your API keys.');
            }

            if (searchButton) {
                searchButton.textContent = '🔍 Search More Videos';
                searchButton.disabled = false;
            }
        }

        cacheChannelVideos(channelId, videos) {
            // Add videos to watched cache for persistence
            const existingWatchedVideos = GM_getValue('wayback_watched_videos_cache', []);

            const videosToCache = videos.map(video => ({
                id: video.id?.videoId || video.id,
                title: video.snippet?.title || 'Unknown Title',
                channel: video.snippet?.channelTitle || 'Unknown Channel',
                channelId: video.snippet?.channelId || channelId,
                thumbnail: video.snippet?.thumbnails?.medium?.url || video.snippet?.thumbnails?.high?.url || video.snippet?.thumbnails?.default?.url || '',
                publishedAt: video.snippet?.publishedAt || new Date().toISOString(),
                description: video.snippet?.description || '',
                viewCount: video.statistics?.viewCount || 'Unknown',
                cachedAt: new Date().toISOString(),
                source: 'channel_search'
            }));

            // Merge with existing and remove duplicates
            const allVideos = [...existingWatchedVideos, ...videosToCache];
            const uniqueVideos = OptimizedUtils.removeDuplicates(allVideos);

            // Limit cache size to prevent storage issues
            const maxCacheSize = 5000;
            if (uniqueVideos.length > maxCacheSize) {
                uniqueVideos.sort((a, b) => new Date(b.cachedAt) - new Date(a.cachedAt));
                uniqueVideos.splice(maxCacheSize);
            }

            GM_setValue('wayback_watched_videos_cache', uniqueVideos);
            OptimizedUtils.log(`Cached ${videosToCache.length} new videos for channel ${channelId}`);
        }

        replaceSearchResults(videos) {
            const containers = OptimizedUtils.$$('#contents ytd-video-renderer');

            videos.slice(0, containers.length).forEach((video, index) => {
                if (containers[index]) {
                    this.replaceVideoElement(containers[index], video);
                }
            });

            OptimizedUtils.log(`Replaced ${Math.min(videos.length, containers.length)} search results`);
        }

        replaceVideoElement(container, video) {
            try {
                const videoId = video.id?.videoId || video.id;
                const snippet = video.snippet;

                if (!videoId || !snippet) return;

                // Update thumbnail
                const thumbnailImg = container.querySelector('img');
                if (thumbnailImg) {
                    const thumbnailUrl = snippet.thumbnails?.high?.url || 
                                       snippet.thumbnails?.medium?.url || 
                                       snippet.thumbnails?.default?.url;
                    if (thumbnailUrl) {
                        thumbnailImg.src = thumbnailUrl;
                        thumbnailImg.alt = snippet.title;
                    }
                }

                // Update title
                const titleElement = container.querySelector('#video-title, .ytd-video-meta-block #video-title, a[aria-describedby]');
                if (titleElement) {
                    titleElement.textContent = OptimizedUtils.cleanTitle(snippet.title);
                    titleElement.title = snippet.title;

                    // Update href
                    if (titleElement.tagName === 'A') {
                        titleElement.href = `/watch?v=${videoId}`;
                    }
                }

                // Update channel name
                const channelElement = container.querySelector('.ytd-channel-name a, #channel-name a, #text.ytd-channel-name');
                if (channelElement) {
                    channelElement.textContent = snippet.channelTitle;
                    if (channelElement.href) {
                        channelElement.href = `/channel/${snippet.channelId}`;
                    }
                }

                // Update published date
                const dateElement = container.querySelector('#published-time-text, .ytd-video-meta-block #published-time-text');
                if (dateElement) {
                    const publishedDate = new Date(snippet.publishedAt);
                    dateElement.textContent = this.formatRelativeTime(publishedDate);
                }

                // Update view count if available
                const viewCountElement = container.querySelector('#metadata-line span:first-child, .ytd-video-meta-block span:first-child');
                if (viewCountElement && video.statistics?.viewCount) {
                    viewCountElement.textContent = this.formatViewCount(video.statistics.viewCount);
                }

                // Update links
                const linkElements = container.querySelectorAll('a[href*="/watch"]');
                linkElements.forEach(link => {
                    link.href = `/watch?v=${videoId}`;
                });

                // Mark as replaced
                container.setAttribute('data-wayback-replaced', 'true');
                container.setAttribute('data-wayback-video-id', videoId);

            } catch (error) {
                OptimizedUtils.log('Error replacing video element:', error.message);
            }
        }

        showChannelVideosForPeriod(videos) {
            // Create a container for period videos
            const channelContent = OptimizedUtils.$('#contents, #primary-inner');
            if (!channelContent) return;

            // Remove existing period content
            const existingPeriodContent = OptimizedUtils.$('#wayback-period-content');
            if (existingPeriodContent) {
                existingPeriodContent.remove();
            }

            if (videos.length === 0) {
                this.showNoVideosMessage(channelContent);
                return;
            }

            // Create new period content
            const periodContainer = document.createElement('div');
            periodContainer.id = 'wayback-period-content';
            periodContainer.innerHTML = `
                <div style="padding: 20px; background: #f9f9f9; border-radius: 8px; margin: 20px 0;">
                    <h3 style="margin: 0 0 15px 0; color: #333;">
                        Videos from ${OptimizedUtils.formatDate(this.videoManager.currentTimeframe.selectedDate, 'MMMM YYYY')}
                    </h3>
                    <div id="period-video-grid" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 15px;">
                        ${videos.map(video => this.createVideoCard(video)).join('')}
                    </div>
                </div>
            `;

            channelContent.insertBefore(periodContainer, channelContent.firstChild);
        }

        createVideoCard(video) {
            const videoId = video.id?.videoId || video.id;
            const snippet = video.snippet;

            if (!videoId || !snippet) return '';

            const thumbnailUrl = snippet.thumbnails?.medium?.url || snippet.thumbnails?.default?.url;
            const publishedDate = new Date(snippet.publishedAt);

            return `
                <div class="wayback-video-card" style="background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
                    <a href="/watch?v=${videoId}" style="display: block; text-decoration: none; color: inherit;">
                        <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
                            <img src="${thumbnailUrl}" alt="${snippet.title}" 
                                 style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;">
                        </div>
                        <div style="padding: 12px;">
                            <h4 style="margin: 0 0 8px 0; font-size: 14px; line-height: 1.3; color: #333; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;">
                                ${OptimizedUtils.cleanTitle(snippet.title)}
                            </h4>
                            <div style="font-size: 12px; color: #666;">
                                ${this.formatRelativeTime(publishedDate)}
                            </div>
                        </div>
                    </a>
                </div>
            `;
        }

        showNoVideosMessage(container) {
            const messageDiv = document.createElement('div');
            messageDiv.id = 'wayback-period-content';
            messageDiv.innerHTML = `
                <div style="padding: 40px; text-align: center; background: #f9f9f9; border-radius: 8px; margin: 20px 0;">
                    <h3 style="margin: 0 0 10px 0; color: #666;">No Videos Found</h3>
                    <p style="margin: 0; color: #888;">
                        This channel had no videos published in ${OptimizedUtils.formatDate(this.videoManager.currentTimeframe.selectedDate, 'MMMM YYYY')}.
                        <br>Try selecting a different date.
                    </p>
                </div>
            `;
            container.insertBefore(messageDiv, container.firstChild);
        }

        formatRelativeTime(date) {
            const now = new Date();
            const diffMs = now - date;
            const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
            const diffMonths = Math.floor(diffDays / 30);
            const diffYears = Math.floor(diffDays / 365);

            if (diffYears > 0) return `${diffYears} year${diffYears > 1 ? 's' : ''} ago`;
            if (diffMonths > 0) return `${diffMonths} month${diffMonths > 1 ? 's' : ''} ago`;
            if (diffDays > 0) return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;
            return 'Today';
        }

        formatViewCount(count) {
            const num = parseInt(count);
            if (num >= 1000000) return `${(num / 1000000).toFixed(1)}M views`;
            if (num >= 1000) return `${(num / 1000).toFixed(1)}K views`;
            return `${num} views`;
        }

        handleAddApiKey() {
            const input = this.elements.get('apiKeyInput');
            const key = input.value.trim();

            if (this.apiManager.addKey(key)) {
                input.value = '';
                this.updateApiStats();
                this.showSuccess('API key added successfully!');
            } else {
                this.showError('Invalid API key or key already exists');
            }
        }

        async handleTestApiKeys() {
            const testButton = this.elements.get('testKeysButton');
            const keyStatsDiv = this.elements.get('keyStatsDiv');

            if (!testButton || !keyStatsDiv) return;

            if (this.apiManager.keys.length === 0) {
                this.showError('No API keys to test. Add some first.');
                return;
            }

            // Disable button and show loading
            testButton.disabled = true;
            testButton.textContent = 'Testing...';
            keyStatsDiv.innerHTML = '<div style="color: #ffa500;">Testing API keys...</div>';

            try {
                const results = await this.apiManager.testAllKeys();

                // Display results
                let resultHtml = '<div style="margin-top: 10px;"><h4>API Key Test Results:</h4>';
                results.forEach((result, index) => {
                    const statusColor = result.result === 'Working perfectly' ? '#4CAF50' : '#f44336';
                    resultHtml += `
                        <div style="margin: 5px 0; padding: 5px; background: rgba(255,255,255,0.1); border-radius: 4px;">
                            <div style="font-size: 12px;">${result.keyPreview}</div>
                            <div style="color: ${statusColor}; font-size: 11px;">${result.result}</div>
                        </div>
                    `;
                });
                resultHtml += '</div>';

                keyStatsDiv.innerHTML = resultHtml;
                this.showSuccess(`Tested ${results.length} API keys successfully!`);
            } catch (error) {
                keyStatsDiv.innerHTML = `<div style="color: #f44336;">Error testing keys: ${error.message}</div>`;
                this.showError('Failed to test API keys');
            } finally {
                // Re-enable button
                testButton.disabled = false;
                testButton.textContent = 'Test All API Keys';
            }
        }

        toggleApiSection() {
            const section = this.elements.get('apiSection');
            const isVisible = section.style.display !== 'none';

            section.style.display = isVisible ? 'none' : 'block';

            if (!isVisible) {
                this.updateApiStats();
            }
        }

        toggleMinimize() {
            const mainInterface = this.elements.get('main');
            const content = OptimizedUtils.$('#wayback-content');
            const minimizeButton = this.elements.get('minimizeButton');

            const isMinimized = mainInterface.classList.contains('minimized');

            if (isMinimized) {
                mainInterface.classList.remove('minimized');
                content.style.display = 'block';
                minimizeButton.textContent = '–';
            } else {
                mainInterface.classList.add('minimized');
                content.style.display = 'none';
                minimizeButton.textContent = '+';
            }
        }

        updateInterface() {
            const isActive = GM_getValue('ytActive', false);
            const selectedDate = GM_getValue('ytSelectedDate', this.videoManager.getDefaultDate());
            const currentPage = OptimizedUtils.getCurrentPage();

            // Update status
            const statusElement = this.elements.get('statusElement');
            const toggleButton = this.elements.get('toggleButton');

            if (statusElement) {
                statusElement.className = `wayback-status ${isActive ? 'active' : 'error'}`;
                statusElement.textContent = isActive ? 'Active' : 'Inactive';
            }

            if (toggleButton) {
                toggleButton.textContent = isActive ? 'Disable' : 'Enable';
            }

            // Update date display
            const currentDateElement = this.elements.get('currentDate');
            if (currentDateElement) {
                currentDateElement.textContent = selectedDate;
            }

            // Update current page
            const currentPageElement = this.elements.get('currentPage');
            if (currentPageElement) {
                currentPageElement.textContent = currentPage;
            }

            // Update date input
            const dateInput = this.elements.get('dateInput');
            if (dateInput && dateInput.value !== selectedDate) {
                dateInput.value = selectedDate;
            }
        }

        updateApiStats() {
            const statsDiv = this.elements.get('keyStatsDiv');
            if (!statsDiv) return;

            const stats = this.apiManager.getKeyStats();
            const cacheStats = this.cacheManager.getStats();

            statsDiv.innerHTML = `
                <div style="margin-top: 10px; padding-top: 10px; border-top: 1px solid rgba(255,255,255,0.2); font-size: 11px;">
                    <div class="wayback-stat-row">
                        <span>API Keys:</span>
                        <span>${stats.totalKeys} (Current: ${stats.currentKey}/${stats.totalKeys})</span>
                    </div>
                    <div class="wayback-stat-row">
                        <span>Cache Hit Rate:</span>
                        <span>${cacheStats.hitRate}</span>
                    </div>
                    <div class="wayback-stat-row">
                        <span>Memory Cache:</span>
                        <span>${cacheStats.memorySize} items</span>
                    </div>
                </div>
            `;
        }

        setLoadingState(isLoading) {
            const refreshButton = this.elements.get('refreshButton');
            const statusElement = this.elements.get('statusElement');

            if (refreshButton) {
                refreshButton.disabled = isLoading;
                refreshButton.innerHTML = isLoading ? '🔄 Loading...' : '🔄 Refresh';
            }

            if (statusElement && isLoading) {
                statusElement.className = 'wayback-status loading';
                statusElement.textContent = 'Loading';
            } else if (statusElement && !isLoading) {
                const isActive = GM_getValue('ytActive', false);
                statusElement.className = `wayback-status ${isActive ? 'active' : 'error'}`;
                statusElement.textContent = isActive ? 'Active' : 'Inactive';
            }
        }

        showSuccess(message) {
            this.showNotification(message, 'success');
        }

        showError(message) {
            this.showNotification(message, 'error');
        }

        showWarning(message) {
            this.showNotification(message, 'warning');
        }

        showNotification(message, type = 'info') {
            // Create notification element
            const notification = document.createElement('div');
            notification.className = `wayback-notification wayback-notification-${type}`;
            notification.innerHTML = `
                <div style="
                    position: fixed;
                    top: 20px;
                    left: 50%;
                    transform: translateX(-50%);
                    z-index: 10001;
                    background: ${type === 'error' ? '#f44336' : type === 'warning' ? '#ff9800' : '#4caf50'};
                    color: white;
                    padding: 12px 20px;
                    border-radius: 4px;
                    box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
                    font-size: 14px;
                    max-width: 400px;
                    text-align: center;
                    animation: wayback-notification-slide 0.3s ease;
                ">
                    ${message}
                </div>
            `;

            document.body.appendChild(notification);

            // Auto remove after 3 seconds
            setTimeout(() => {
                notification.remove();
            }, 3000);
        }

        startObservers() {
            // Content observer for dynamic page changes
            const contentObserver = new MutationObserver(OptimizedUtils.throttle(() => {
                if (GM_getValue('ytActive', false)) {
                    this.handleContentChange();
                }
            }, 1000));

            const targetNode = document.body;
            if (targetNode) {
                contentObserver.observe(targetNode, {
                    childList: true,
                    subtree: true,
                    attributes: false
                });

                this.observers.set('content', contentObserver);
            }

            OptimizedUtils.log('Content observers started');
        }

        handleContentChange() {
            // Aggressive content blocking
            this.blockModernContent();
            this.updateCurrentPageContent();
        }

        blockModernContent() {
            // Block Shorts
            CONFIG.SHORTS_SELECTORS.forEach(selector => {
                OptimizedUtils.$$(selector).forEach(element => {
                    if (!element.hasAttribute('data-wayback-blocked')) {
                        element.style.display = 'none';
                        element.setAttribute('data-wayback-blocked', 'true');
                    }
                });
            });

            // Block modern channel content and replace with cached videos
            if (OptimizedUtils.getCurrentPage() === 'channel') {
                CONFIG.CHANNEL_PAGE_SELECTORS.forEach(selector => {
                    OptimizedUtils.$$(selector).forEach(element => {
                        if (!element.hasAttribute('data-wayback-blocked')) {
                            element.style.visibility = 'hidden';
                            element.style.height = '0';
                            element.style.overflow = 'hidden';
                            element.setAttribute('data-wayback-blocked', 'true');
                        }
                    });
                });

                // Replace with cached channel videos
                this.replaceChannelPageWithCache();
            }
        }

        async updateCurrentPageContent() {
            const context = OptimizedUtils.getPageContext();

            // Update page info in UI
            const currentPageElement = this.elements.get('currentPage');
            if (currentPageElement) {
                currentPageElement.textContent = context.page;
            }
        }

        handleUrlChange() {
            OptimizedUtils.log('URL changed, updating content...');
            this.updateInterface();

            if (GM_getValue('ytActive', false)) {
                // Small delay to let page load
                setTimeout(() => {
                    this.handleContentChange();
                }, 1000);
            }
        }

        cleanup() {
            // Remove event listeners
            this.eventListeners.forEach((listeners, key) => {
                listeners.forEach(({ element, event, handler }) => {
                    element.removeEventListener(event, handler);
                });
            });
            this.eventListeners.clear();

            // Disconnect observers
            this.observers.forEach(observer => {
                observer.disconnect();
            });
            this.observers.clear();

            // Remove elements
            this.elements.forEach((element, key) => {
                if (element && element.parentNode) {
                    element.parentNode.removeChild(element);
                }
            });
            this.elements.clear();

            OptimizedUtils.log('UI Manager cleaned up');
        }

        // === SUBSCRIPTION MANAGEMENT HANDLERS ===
        handleAddSubscription() {
            const input = this.elements.get('subscriptionInput');
            const channelName = input.value.trim();

            if (!channelName) return;

            const subscriptions = this.loadSubscriptions();
            if (!subscriptions.find(sub => sub.name.toLowerCase() === channelName.toLowerCase())) {
                subscriptions.push({ name: channelName, id: null });
                this.saveSubscriptions(subscriptions);
                this.updateSubscriptionsList();
                input.value = '';
                OptimizedUtils.log(`Added subscription: ${channelName}`);
            } else {
                OptimizedUtils.log(`Subscription already exists: ${channelName}`);
            }
        }

        handleRemoveSubscription(channelName) {
            const subscriptions = this.loadSubscriptions();
            const index = subscriptions.findIndex(sub => sub.name === channelName);
            if (index > -1) {
                subscriptions.splice(index, 1);
                this.saveSubscriptions(subscriptions);
                this.updateSubscriptionsList();
                OptimizedUtils.log(`Removed subscription: ${channelName}`);
            }
        }

        handleClearSubscriptions() {
            this.saveSubscriptions([]);
            this.updateSubscriptionsList();
            OptimizedUtils.log('Cleared all subscriptions');
        }

        async handleLoadHomepage() {
            if (!GM_getValue('ytActive', false)) {
                OptimizedUtils.log('WayBackTube is not active');
                return;
            }

            const subscriptions = this.loadSubscriptions();
            const searchTerms = this.loadSearchTerms();

            if (subscriptions.length === 0 && searchTerms.length === 0) {
                OptimizedUtils.log('No subscriptions or search terms to load from');
                return;
            }

            try {
                this.setLoadingState(true);
                await this.refreshHomepage();
                this.setLoadingState(false);
                OptimizedUtils.log('Homepage videos loaded successfully');
            } catch (error) {
                this.setLoadingState(false);
                OptimizedUtils.log('Failed to load homepage videos:', error);
            }
        }

        // === SEARCH TERMS MANAGEMENT HANDLERS ===
        handleAddSearchTerm() {
            const input = this.elements.get('searchTermInput');
            const searchTerm = input.value.trim();

            if (!searchTerm) return;

            const searchTerms = this.loadSearchTerms();
            if (!searchTerms.includes(searchTerm.toLowerCase())) {
                searchTerms.push(searchTerm.toLowerCase());
                this.saveSearchTerms(searchTerms);
                this.updateSearchTermsList();
                input.value = '';
                OptimizedUtils.log(`Added search term: ${searchTerm}`);
            } else {
                OptimizedUtils.log(`Search term already exists: ${searchTerm}`);
            }
        }

        handleRemoveSearchTerm(searchTerm) {
            const searchTerms = this.loadSearchTerms();
            const index = searchTerms.indexOf(searchTerm);
            if (index > -1) {
                searchTerms.splice(index, 1);
                this.saveSearchTerms(searchTerms);
                this.updateSearchTermsList();
                OptimizedUtils.log(`Removed search term: ${searchTerm}`);
            }
        }

        handleClearSearchTerms() {
            this.saveSearchTerms([]);
            this.updateSearchTermsList();
            OptimizedUtils.log('Cleared all search terms');
        }

        async handleLoadSearchVideos() {
            if (!GM_getValue('ytActive', false)) {
                OptimizedUtils.log('WayBackTube is not active');
                return;
            }

            const searchTerms = this.loadSearchTerms();

            if (searchTerms.length === 0) {
                OptimizedUtils.log('No search terms to load videos from');
                return;
            }

            try {
                this.setLoadingState(true);
                await this.refreshHomepage();
                this.setLoadingState(false);
                OptimizedUtils.log('Search term videos loaded successfully');
            } catch (error) {
                this.setLoadingState(false);
                OptimizedUtils.log('Failed to load search term videos:', error);
            }
        }

        // === DATA MANAGEMENT HELPERS ===
        loadSubscriptions() {
            const saved = GM_getValue('wayback_subscriptions', '[]');
            try {
                const subscriptions = JSON.parse(saved);
                return subscriptions.length > 0 ? subscriptions : this.getDefaultSubscriptions();
            } catch {
                return this.getDefaultSubscriptions();
            }
        }

        saveSubscriptions(subscriptions) {
            GM_setValue('wayback_subscriptions', JSON.stringify(subscriptions));
        }

        getDefaultSubscriptions() {
            return [
                { name: 'PewDiePie', id: 'UC-lHJZR3Gqxm24_Vd_AJ5Yw' },
                { name: 'Markiplier', id: 'UC7_YxT-KID8kRbqZo7MyscQ' },
                { name: 'Jacksepticeye', id: 'UCYzPXprvl5Y-Sf0g4vX-m6g' }
            ];
        }

        loadSearchTerms() {
            const saved = GM_getValue('wayback_search_terms', '[]');
            try {
                const searchTerms = JSON.parse(saved);
                return searchTerms.length > 0 ? searchTerms : this.getDefaultSearchTerms();
            } catch {
                return this.getDefaultSearchTerms();
            }
        }

        saveSearchTerms(searchTerms) {
            GM_setValue('wayback_search_terms', JSON.stringify(searchTerms));
        }

        getDefaultSearchTerms() {
            return ['memes', 'gaming', 'funny', 'music', 'tutorial'];
        }

        // === UI UPDATE HELPERS ===
        updateSubscriptionsList() {
            const container = this.elements.get('subscriptionsList');
            if (!container) return;

            const subscriptions = this.loadSubscriptions();
            container.innerHTML = subscriptions.map(sub => `
                <div class="wayback-list-item">
                    <span class="wayback-item-text">${sub.name}</span>
                    <button class="wayback-remove-btn" data-subscription="${sub.name}">×</button>
                </div>
            `).join('');
        }

        updateSearchTermsList() {
            const container = this.elements.get('searchTermsList');
            if (!container) return;

            const searchTerms = this.loadSearchTerms();
            container.innerHTML = searchTerms.map(term => `
                <div class="wayback-list-item">
                    <span class="wayback-item-text">${term}</span>
                    <button class="wayback-remove-btn" data-search-term="${term}">×</button>
                </div>
            `).join('');
        }

        // Initialize the UI with existing data
        initializeUI() {
            this.updateSubscriptionsList();
            this.updateSearchTermsList();
            this.initializeVintageTheme();
        }

        initializeVintageTheme() {
            const isVintageActive = GM_getValue('ytVintage2011Theme', false);
            const button = this.elements.get('vintageToggleButton');
            
            // Apply saved theme state
            if (isVintageActive) {
                document.body.classList.add('wayback-2011-theme');
            }
            
            // Update button state
            if (button) {
                button.textContent = isVintageActive ? '🕰️ Modern Theme' : '🕰️ 2011 Theme';
                if (isVintageActive) {
                    button.classList.add('wayback-vintage-active');
                }
            }
            
            OptimizedUtils.log(`2011 Vintage Theme initialized: ${isVintageActive ? 'active' : 'inactive'}`);
        }
    }

    // === COMPLETE MAIN APPLICATION CLASS ===
    class WayBackTubeOptimized {
        constructor() {
            // Settings and state MUST be initialized first
            const now = Date.now();
            this.settings = {
                active: GM_getValue('ytActive', false),
                uiVisible: GM_getValue('ytTimeMachineUIVisible', true),
                date: GM_getValue('ytSelectedDate', '2012-01-01'),
                lastDateRotation: GM_getValue('ytLastDateRotation', now - (25 * 60 * 60 * 1000)), // Default to 25 hours ago to trigger rotation
                dateRotationEnabled: GM_getValue('ytDateRotationEnabled', true)
            };

            // Initialize all managers with complete functionality
            this.apiManager = new OptimizedAPIManager();
            this.subscriptionManager = new SubscriptionManager();
            this.feedChipHider = new FeedChipHider();
            this.searchEnhancement = new OptimizedSearchEnhancement(this);
            this.tabHider = new TabHider();

            this.maxDate = new Date(this.settings.date);
            // FIXED: Use persistent cache manager instead of Map()
            this.videoCache = new PersistentVideoCache();
            this.stats = {
                processed: 0,
                filtered: 0,
                apiCalls: 0,
                cacheHits: 0
            };

            // Initialize components
            this.searchManager = new SearchManager(this.apiManager, this.maxDate);
            this.uiManager = new EnhancedUIManager(this);

            this.isInitialized = false;
            this.autoRefreshTimer = null;
            this.filterTimer = null;
            this.isProcessing = false;

            this.init();
        }

        async init() {
            if (this.isInitialized) return;

            try {
                OptimizedUtils.log('Initializing Complete WayBackTube...');

                // Check for date rotation on startup
                this.checkDateRotation();

                // Wait for page to be ready
                await OptimizedUtils.waitFor(() => document.readyState === 'complete', 15000);

                // Set up channel page monitoring
                this.setupChannelPageMonitoring();

                // Start filtering and content replacement
                this.startFiltering();
                this.startHomepageReplacement();
                this.startVideoPageEnhancement();
                this.tabHider.init();

                // Auto-load if enabled and on homepage
                if (CONFIG.autoLoadOnHomepage && this.isHomePage() && this.settings.active) {
                    setTimeout(() => {
                        this.loadAllVideos(false); // Don't refresh, use cache if available
                    }, CONFIG.autoLoadDelay);
                }

                // Setup auto-refresh
                this.setupAutoRefresh();

                // Setup date rotation check (every hour)
                this.setupDateRotationTimer();

                this.isInitialized = true;
                OptimizedUtils.log('Complete WayBackTube initialized successfully');

            } catch (error) {
                OptimizedUtils.log('Initialization error:', error.message);
                console.error('WayBackTube initialization failed:', error);
            }
        }

        // === TIME MACHINE CONTROLS ===
        setDate(dateString) {
            this.settings.date = dateString;
            this.maxDate = new Date(dateString);
            this.searchManager.updateMaxDate(this.maxDate);

            GM_setValue('ytSelectedDate', dateString);
            OptimizedUtils.log(`Date set to: ${dateString}`);

            // Clear caches and reload content
            this.apiManager.clearCache();
            this.videoCache.clear(); // Also clear persistent video cache
            if (this.settings.active) {
                this.loadAllVideos(true); // Force refresh after clearing cache
            }
        }

        checkDateRotation() {
            if (!this.settings.dateRotationEnabled) {
                OptimizedUtils.log('Date rotation is disabled');
                return;
            }

            const now = Date.now();
            const lastRotation = this.settings.lastDateRotation;
            const timeSinceLastRotation = now - lastRotation;
            const oneDayMs = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
            const hoursElapsed = timeSinceLastRotation / (60 * 60 * 1000);

            OptimizedUtils.log(`Date rotation check: ${hoursElapsed.toFixed(1)} hours since last rotation (need 24+)`);

            if (timeSinceLastRotation >= oneDayMs) {
                // Advance the date by one day
                const currentDate = new Date(this.settings.date);
                currentDate.setDate(currentDate.getDate() + 1);

                const newDateString = currentDate.toISOString().split('T')[0];
                this.setDate(newDateString);

                // Update last rotation time
                this.settings.lastDateRotation = now;
                GM_setValue('ytLastDateRotation', now);

                OptimizedUtils.log(`🗓️ Date automatically rotated to: ${newDateString} (simulating daily uploads)`);

                // Clear cache and refresh content to show "new" videos for the day
                this.apiManager.clearCache();
                this.videoCache.clear(); // Also clear persistent video cache
                if (this.settings.active) {
                    setTimeout(() => {
                        this.loadAllVideos(true); // Force refresh for new daily content
                    }, 1000);
                }
            }
        }

        setupDateRotationTimer() {
            // Check for date rotation every hour
            setInterval(() => {
                this.checkDateRotation();
            }, 60 * 60 * 1000); // 1 hour

            // Setup fast test clock that simulates 24 hours in 2 minutes for testing
            this.setupTestClock();
        }

        setupTestClock() {
            // Real-time clock: actual 24 hours = 24 hours, new videos every 4 real hours
            const testClockEnabled = GM_getValue('wayback_persistent_clock_enabled', false);
            if (!testClockEnabled) return;

            // Store clock data with version-independent keys to persist across updates
            const startTime = GM_getValue('wayback_persistent_clock_start', Date.now());
            const lastVideoCheck = GM_getValue('wayback_persistent_last_video_check', 0);

            // Save initial start time to version-independent storage if not already set
            if (!GM_getValue('wayback_persistent_clock_start')) {
                GM_setValue('wayback_persistent_clock_start', startTime);
            }

            this.testClockTimer = setInterval(() => {
                const now = Date.now();
                const timeElapsed = now - startTime;

                // Calculate hours elapsed since start
                const hoursElapsed = timeElapsed / (1000 * 60 * 60); // Real hours
                const currentHour = Math.floor(hoursElapsed % 24); // 0-23 hour format

                // Check for 4-hour intervals for new videos (every 4 real hours)
                const currentInterval = Math.floor(hoursElapsed / 4);
                const lastInterval = GM_getValue('wayback_persistent_last_interval', -1);

                if (currentInterval !== lastInterval && currentInterval > 0) {
                    GM_setValue('wayback_persistent_last_interval', currentInterval);
                    OptimizedUtils.log(`🕐 4-hour mark reached (${hoursElapsed.toFixed(1)}h total) - New videos available!`);

                    // Clear video cache to simulate new uploads - but only when clock advances
                    this.apiManager.clearCache();
                    this.videoCache.clear(); // Clear persistent video cache
                    if (this.settings.active) {
                        OptimizedUtils.log('Clock advanced - reloading videos with fresh API calls');
                        this.loadAllVideos(true); // Force refresh for new content
                    }
                }

                // Check for 24-hour date rotation (every 24 real hours)
                const daysSinceStart = Math.floor(hoursElapsed / 24);
                const lastRotationDay = GM_getValue('wayback_persistent_last_rotation_day', -1);

                if (daysSinceStart > lastRotationDay && daysSinceStart > 0) {
                    GM_setValue('wayback_persistent_last_rotation_day', daysSinceStart);

                    // Advance the date by one day
                    const currentDate = new Date(this.settings.date);
                    currentDate.setDate(currentDate.getDate() + 1);

                    const newDateString = currentDate.toISOString().split('T')[0];
                    this.setDate(newDateString);

                    OptimizedUtils.log(`🗓️ REAL CLOCK: Date advanced to ${newDateString} (Day ${daysSinceStart})`);
                }

                // Update UI with real time
                this.updateTestClockDisplay(hoursElapsed);

            }, 1000); // Update every second for seconds display
        }

        updateTestClockDisplay(totalHours) {
            const days = Math.floor(totalHours / 24);
            const hours = Math.floor(totalHours % 24);
            const minutes = Math.floor((totalHours - Math.floor(totalHours)) * 60);
            const seconds = Math.floor(((totalHours - Math.floor(totalHours)) * 60 - minutes) * 60);

            const timeString = `Day ${days}, ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;

            // Update UI clock display instead of floating overlay
            const clockElement = document.getElementById('wayback-clock-display');
            if (clockElement) {
                clockElement.textContent = timeString;
            }

            // Also update the alternative UI if it exists
            const tmClockElement = document.getElementById('tm-clock-display');
            if (tmClockElement) {
                tmClockElement.textContent = timeString;
            }
        }

        toggleTestClock(enabled) {
            GM_setValue('wayback_persistent_clock_enabled', enabled);

            if (enabled) {
                // Initialize start time if not set
                if (!GM_getValue('wayback_persistent_clock_start')) {
                    GM_setValue('wayback_persistent_clock_start', Date.now());
                }
                this.setupTestClock();
                OptimizedUtils.log('🕐 Real-time clock enabled: 24 real hours = 1 day, new videos every 4 real hours');
            } else {
                if (this.testClockTimer) {
                    clearInterval(this.testClockTimer);
                    this.testClockTimer = null;
                }
                // Clear clock display in UI
                const clockElement = document.getElementById('wayback-clock-display');
                if (clockElement) {
                    clockElement.textContent = 'Clock stopped';
                }
                OptimizedUtils.log('🕐 Real-time clock disabled');
            }
        }

        enableDateRotation(enabled) {
            this.settings.dateRotationEnabled = enabled;
            GM_setValue('ytDateRotationEnabled', enabled);
            OptimizedUtils.log(`Date rotation ${enabled ? 'enabled' : 'disabled'}`);
        }

        setRandomDate() {
            const startDate = new Date('2005-04-23'); // YouTube founded
            const endDate = new Date('2018-12-31');   // Pre-modern era

            const randomTime = startDate.getTime() + Math.random() * (endDate.getTime() - startDate.getTime());
            const randomDate = new Date(randomTime);

            this.setDate(randomDate.toISOString().split('T')[0]);
        }

        getDateString() {
            return this.settings.date;
        }

        toggle() {
            this.settings.active = !this.settings.active;
            GM_setValue('ytActive', this.settings.active);

            OptimizedUtils.log(`Time Machine ${this.settings.active ? 'enabled' : 'disabled'}`);

            if (this.settings.active) {
                // Only load if we don't have cached videos
                const hasSubscriptionCache = (this.videoCache.get('subscription_videos_only') || []).length > 0;
                const hasSearchTermCache = (this.videoCache.get('search_term_videos_only') || []).length > 0;
                const searchTerms = this.uiManager.getSearchTerms();
                const subscriptions = this.subscriptionManager.getSubscriptions();
                
                const needsLoading = (subscriptions.length > 0 && !hasSubscriptionCache) || 
                                   (searchTerms.length > 0 && !hasSearchTermCache);
                
                if (needsLoading) {
                    OptimizedUtils.log('Loading videos for first time activation...');
                    this.loadAllVideos(false); // Don't refresh, use cache if available
                } else {
                    OptimizedUtils.log('Using existing cached videos - no API calls needed');
                }
            }
        }

        // === SERIES ADVANCEMENT FUNCTIONALITY ===
        async findNextEpisodeInSeries(currentVideoTitle, currentChannelName) {
            // Extract episode patterns from current video title
            const episodePatterns = [
                /episode\s*(\d+)/i,
                /ep\.?\s*(\d+)/i,
                /part\s*(\d+)/i,
                /#(\d+)/i,
                /(\d+)(?=\s*[-–—]\s*)/i, // Number followed by dash
                /(\d+)(?=\s*$)/i // Number at end of title
            ];

            let episodeNumber = null;
            let patternUsed = null;
            let baseTitle = currentVideoTitle;

            // Try to find episode number
            for (const pattern of episodePatterns) {
                const match = currentVideoTitle.match(pattern);
                if (match) {
                    episodeNumber = parseInt(match[1]);
                    patternUsed = pattern;
                    // Create base title by removing the episode number
                    baseTitle = currentVideoTitle.replace(pattern, '').trim();
                    break;
                }
            }

            if (!episodeNumber) {
                OptimizedUtils.log('No episode pattern found in:', currentVideoTitle);
                return null;
            }

            const nextEpisodeNumber = episodeNumber + 1;
            OptimizedUtils.log(`Found episode ${episodeNumber}, searching for episode ${nextEpisodeNumber}`);

            // Generate search query for next episode
            const searchQueries = [
                `${currentChannelName} ${baseTitle} episode ${nextEpisodeNumber}`,
                `${currentChannelName} ${baseTitle} ep ${nextEpisodeNumber}`,
                `${currentChannelName} ${baseTitle} part ${nextEpisodeNumber}`,
                `${currentChannelName} ${baseTitle} #${nextEpisodeNumber}`,
                `${currentChannelName} ${baseTitle} ${nextEpisodeNumber}`
            ];

            // Try each search query to find the next episode
            for (const query of searchQueries) {
                try {
                    OptimizedUtils.log(`Searching for next episode: "${query}"`);
                    const results = await this.apiManager.searchVideos(query.trim(), {
                        publishedBefore: this.maxDate,
                        maxResults: 10,
                        order: 'relevance'
                    });

                    if (results && results.length > 0) {
                        // Look for exact episode match in results
                        const nextEpisode = results.find(video => {
                            const title = video.snippet?.title || '';
                            const channel = video.snippet?.channelTitle || '';
                            
                            // Check if it's from same channel and contains next episode number
                            if (channel.toLowerCase() !== currentChannelName.toLowerCase()) {
                                return false;
                            }

                            // Check if title contains the next episode number
                            return episodePatterns.some(pattern => {
                                const match = title.match(pattern);
                                return match && parseInt(match[1]) === nextEpisodeNumber;
                            });
                        });

                        if (nextEpisode) {
                            OptimizedUtils.log(`✓ Found next episode: "${nextEpisode.snippet.title}"`);
                            return {
                                id: nextEpisode.id,
                                title: nextEpisode.snippet?.title || 'Next Episode',
                                channel: nextEpisode.snippet?.channelTitle || currentChannelName,
                                channelId: nextEpisode.snippet?.channelId || '',
                                thumbnail: nextEpisode.snippet?.thumbnails?.medium?.url || 
                                         nextEpisode.snippet?.thumbnails?.high?.url || 
                                         nextEpisode.snippet?.thumbnails?.default?.url || '',
                                publishedAt: nextEpisode.snippet?.publishedAt || new Date().toISOString(),
                                description: nextEpisode.snippet?.description || '',
                                viewCount: this.apiManager.generateRealisticViewCount(
                                    nextEpisode.snippet?.publishedAt || new Date().toISOString(), 
                                    this.maxDate
                                ),
                                relativeDate: OptimizedUtils.calculateRelativeDate(
                                    nextEpisode.snippet?.publishedAt || new Date().toISOString(), 
                                    this.maxDate
                                ),
                                isNextEpisode: true // Mark as series advancement
                            };
                        }
                    }
                } catch (error) {
                    OptimizedUtils.log(`Error searching for "${query}":`, error);
                }
            }

            OptimizedUtils.log('No next episode found');
            return null;
        }

        // === VIDEO LOADING AND MANAGEMENT ===
        async loadVideosFromSearchTerms(isRefresh = false) {
            const searchTerms = this.uiManager.getSearchTerms();

            if (searchTerms.length === 0) {
                return [];
            }

            // Check cache first - same behavior as subscriptions
            const cacheKey = `search_videos_${JSON.stringify(searchTerms.sort())}_${this.maxDate.toDateString()}`;
            const cachedVideos = this.videoCache.get(cacheKey);
            if (cachedVideos && cachedVideos.length > 0 && !isRefresh) {
                OptimizedUtils.log(`✓ Using cached search term videos (${cachedVideos.length} videos) - SAVED API QUOTA`);
                return cachedVideos;
            }
            
            OptimizedUtils.log(`⚠️ Loading search term videos from API (cache miss or refresh) - using API quota`);

            OptimizedUtils.log(`Loading videos from ${searchTerms.length} search terms...`);

            let allVideos = [];
            const videosPerTerm = Math.ceil(CONFIG.maxHomepageVideos / searchTerms.length);

            for (const term of searchTerms) {
                try {
                    const endDate = new Date(this.maxDate);
                    const videos = await this.apiManager.searchVideos(term, {
                        publishedBefore: endDate,
                        maxResults: videosPerTerm,
                        order: 'relevance'
                    });
                    if (videos && videos.length > 0) {
                        // Flatten video structure to match subscription videos format
                        const flattenedVideos = videos.map(video => ({
                            id: video.id,
                            title: video.snippet?.title || 'Unknown Title',
                            channel: video.snippet?.channelTitle || 'Unknown Channel',
                            channelId: video.snippet?.channelId || '',
                            thumbnail: video.snippet?.thumbnails?.medium?.url || 
                                     video.snippet?.thumbnails?.high?.url || 
                                     video.snippet?.thumbnails?.default?.url || '',
                            publishedAt: video.snippet?.publishedAt || new Date().toISOString(),
                            description: video.snippet?.description || '',
                            viewCount: this.apiManager.generateRealisticViewCount(
                                video.snippet?.publishedAt || new Date().toISOString(), 
                                endDate
                            ),
                            relativeDate: OptimizedUtils.calculateRelativeDate(video.snippet?.publishedAt || new Date().toISOString(), endDate)
                        }));

                        OptimizedUtils.log(`Flattened ${flattenedVideos.length} search videos for "${term}"`);
                        allVideos = allVideos.concat(flattenedVideos);
                    }
                    OptimizedUtils.log(`Found ${videos?.length || 0} videos for search term: ${term}`);
                } catch (error) {
                    OptimizedUtils.log(`Error loading videos for search term "${term}":`, error);
                }
            }

            // Remove duplicates and limit total
            const uniqueVideos = OptimizedUtils.removeDuplicates(allVideos);
            const limitedVideos = uniqueVideos.slice(0, CONFIG.maxHomepageVideos);

            // Cache the results with same expiry as subscription videos
            this.videoCache.set(cacheKey, limitedVideos, CONFIG.cacheExpiry.videos);

            OptimizedUtils.log(`Loaded ${limitedVideos.length} unique videos from search terms`);
            return limitedVideos;
        }

        async loadAllVideos(isRefresh = false) {
            const subscriptions = this.uiManager.getSubscriptions(); // FIX: Use uiManager, not subscriptionManager
            const searchTerms = this.uiManager.getSearchTerms();

            OptimizedUtils.log(`🚀 LOADING ALL VIDEOS DEBUG:`);
            OptimizedUtils.log(`   Subscriptions: ${subscriptions.length} (${subscriptions.map(s => s.name).join(', ')})`);
            OptimizedUtils.log(`   Search terms: ${searchTerms.length} (${searchTerms.join(', ')})`);
            OptimizedUtils.log(`   Refresh: ${isRefresh}`);

            if (subscriptions.length === 0 && searchTerms.length === 0) {
                OptimizedUtils.log('❌ No subscriptions or search terms found - cannot load videos');
                throw new Error('No subscriptions or search terms to load from');
            }

            // Use SINGLE unified cache key for all videos
            const cacheKey = `all_videos_unified_${this.maxDate.toDateString()}`;
            let cachedVideos = this.videoCache.get(cacheKey) || [];
            
            if (cachedVideos.length > 0 && !isRefresh) {
                OptimizedUtils.log(`✓ Using ${cachedVideos.length} cached unified videos - NO API CALLS`);
                this.videoCache.set('all_videos', cachedVideos); // Also set legacy cache
                return cachedVideos;
            }

            OptimizedUtils.log('Loading all videos from subscriptions and search terms...');
            
            let allVideos = [];
            
            // Load subscription videos if we have subscriptions
            let subscriptionVideos = [];
            if (subscriptions.length > 0) {
                OptimizedUtils.log(`📥 Loading ${subscriptions.length} subscription channels...`);
                subscriptionVideos = await this.loadVideosFromSubscriptions(isRefresh);
                OptimizedUtils.log(`✓ Loaded ${subscriptionVideos.length} subscription videos`);
                allVideos.push(...subscriptionVideos);
            }
            
            // Load search term videos if we have search terms
            let searchTermVideos = [];
            if (searchTerms.length > 0) {
                OptimizedUtils.log(`🔍 Loading ${searchTerms.length} search terms...`);
                searchTermVideos = await this.loadVideosFromSearchTerms(isRefresh);
                OptimizedUtils.log(`✓ Loaded ${searchTermVideos.length} search term videos`);
                allVideos.push(...searchTermVideos);
            }

            // Apply weighted mixing and remove duplicates
            const uniqueVideos = OptimizedUtils.removeDuplicates(allVideos);
            const finalVideos = this.mixVideosByWeight(
                allVideos.filter(v => subscriptions.some(sub => sub.name === v.channel || sub.id === v.channelId)),
                allVideos.filter(v => !subscriptions.some(sub => sub.name === v.channel || sub.id === v.channelId))
            );

            // Store in SINGLE unified cache
            this.videoCache.set(cacheKey, finalVideos, CONFIG.cacheExpiry.videos);
            this.videoCache.set('all_videos', finalVideos); // Legacy cache for compatibility
            
            OptimizedUtils.log(`✓ Stored ${finalVideos.length} videos in unified cache`);
            const searchInFinal = finalVideos.filter(v => searchTermVideos.some(s => s.id === v.id)).length;
            const subInFinal = finalVideos.filter(v => subscriptionVideos.some(s => s.id === v.id)).length;
            OptimizedUtils.log(`   Final homepage mix: ${searchInFinal} search + ${subInFinal} subscription = ${finalVideos.length} total`);
            return finalVideos;
        }

        mixVideosByWeight(subscriptionVideos, searchTermVideos) {
            // Debug logging to see what's happening
            OptimizedUtils.log(`🎯 HOMEPAGE MIXING DEBUG:`);
            OptimizedUtils.log(`   Subscription videos: ${subscriptionVideos.length}`);
            OptimizedUtils.log(`   Search term videos: ${searchTermVideos.length}`);
            OptimizedUtils.log(`   Search percentage: ${CONFIG.searchTermVideoPercentage * 100}%`);
            OptimizedUtils.log(`   Subscription percentage: ${CONFIG.subscriptionVideoPercentage * 100}%`);

            // Don't limit total count - let users load more via pagination
            const totalVideos = subscriptionVideos.length + searchTermVideos.length;
            const searchCount = Math.floor(totalVideos * CONFIG.searchTermVideoPercentage);
            const subscriptionCount = totalVideos - searchCount;

            OptimizedUtils.log(`   Target search videos: ${searchCount}`);
            OptimizedUtils.log(`   Target subscription videos: ${subscriptionCount}`);

            const selectedSearch = OptimizedUtils.shuffleArray([...searchTermVideos]).slice(0, searchCount);
            const selectedSubscription = OptimizedUtils.shuffleArray([...subscriptionVideos]).slice(0, subscriptionCount);

            OptimizedUtils.log(`   Actually selected search: ${selectedSearch.length}`);
            OptimizedUtils.log(`   Actually selected subscription: ${selectedSubscription.length}`);

            const combined = [...selectedSearch, ...selectedSubscription];
            const uniqueVideos = OptimizedUtils.removeDuplicates(combined);

            // Apply heavy recent bias to the mixed results
            const recentlyBiasedVideos = OptimizedUtils.weightedShuffleByDate(uniqueVideos, this.maxDate);

            OptimizedUtils.log(`Video weighting: ${selectedSearch.length} search (${CONFIG.searchTermVideoPercentage * 100}%) + ${selectedSubscription.length} subscription = ${recentlyBiasedVideos.length} total with HEAVY recent bias`);
            return recentlyBiasedVideos;
        }

        getCurrentVideoId() {
            const url = window.location.href;
            const match = url.match(/[?&]v=([^&]+)/);
            return match ? match[1] : null;
        }

        async getCurrentChannelId(videoId) {
            if (!videoId) return null;

            try {
                const videoDetails = await this.apiManager.getVideoDetails([videoId]);
                if (videoDetails && videoDetails.length > 0) {
                    return videoDetails[0].snippet?.channelId;
                }
            } catch (error) {
                OptimizedUtils.log('Error getting current channel ID:', error);
            }
            return null;
        }

        getCurrentVideoTitle() {
            // Try multiple selectors to get the video title
            const titleSelectors = [
                'h1.title.style-scope.ytd-video-primary-info-renderer',
                'h1.ytd-video-primary-info-renderer',
                'h1[class*="title"]',
                '.title.style-scope.ytd-video-primary-info-renderer',
                'ytd-video-primary-info-renderer h1',
                '#container h1'
            ];

            for (const selector of titleSelectors) {
                const titleElement = document.querySelector(selector);
                if (titleElement && titleElement.textContent.trim()) {
                    const title = titleElement.textContent.trim();
                    OptimizedUtils.log(`Found video title: "${title}"`);
                    return title;
                }
            }

            OptimizedUtils.log('Could not find video title on page');
            return null;
        }

        getCurrentChannelName() {
            // Try multiple selectors to get the channel name
            const channelSelectors = [
                'ytd-video-owner-renderer .ytd-channel-name a',
                'ytd-channel-name #text a',
                '#owner-text a',
                '.ytd-channel-name a',
                'a.yt-simple-endpoint.style-scope.yt-formatted-string',
                '#upload-info #channel-name a'
            ];

            for (const selector of channelSelectors) {
                const channelElement = document.querySelector(selector);
                if (channelElement && channelElement.textContent.trim()) {
                    const channelName = channelElement.textContent.trim();
                    OptimizedUtils.log(`Found channel name: "${channelName}"`);
                    return channelName;
                }
            }

            OptimizedUtils.log('Could not find channel name on page');
            return null;
        }

        async createWatchNextWeightedVideos(allVideos, currentChannelId, currentVideoTitle = null, currentChannelName = null) {
            let nextEpisode = null;

            // First, try to find the next episode in the series
            if (currentVideoTitle && currentChannelName) {
                try {
                    nextEpisode = await this.findNextEpisodeInSeries(currentVideoTitle, currentChannelName);
                } catch (error) {
                    OptimizedUtils.log('Error finding next episode:', error);
                }
            }

            // Use SINGLE unified cache for weighting - no separate caches
            const cacheKey = `all_videos_unified_${this.maxDate.toDateString()}`;
            const allCachedVideos = this.videoCache.get(cacheKey) || this.videoCache.get('all_videos') || [];
            
            // Separate cached videos by type for weighting
            const subscriptions = this.subscriptionManager.getSubscriptions();
            const subscriptionVideos = allCachedVideos.filter(v => subscriptions.some(sub => sub.name === v.channel || sub.id === v.channelId));
            const searchTermVideos = allCachedVideos.filter(v => !subscriptions.some(sub => sub.name === v.channel || sub.id === v.channelId));

            // Separate same channel videos if we have a channel ID
            let sameChannelVideos = [];
            let otherVideos = allCachedVideos;

            if (currentChannelId) {
                sameChannelVideos = allCachedVideos.filter(video => video.channelId === currentChannelId);
                otherVideos = allCachedVideos.filter(video => video.channelId !== currentChannelId);
            }

            const totalCount = CONFIG.maxVideoPageVideos;
            
            // Reserve slot for next episode if found
            const reservedSlots = nextEpisode ? 1 : 0;
            const availableSlots = totalCount - reservedSlots;
            
            const sameChannelCount = Math.floor(availableSlots * CONFIG.sameChannelVideoPercentage);
            const searchTermCount = Math.floor((availableSlots - sameChannelCount) * CONFIG.searchTermVideoPercentage);
            const subscriptionCount = availableSlots - sameChannelCount - searchTermCount;

            // Select videos with weighting
            const selectedSameChannel = OptimizedUtils.shuffleArray(sameChannelVideos).slice(0, sameChannelCount);
            const selectedSearch = OptimizedUtils.shuffleArray(searchTermVideos).slice(0, searchTermCount);
            const selectedSubscription = OptimizedUtils.shuffleArray(subscriptionVideos).slice(0, subscriptionCount);

            // Fill remaining slots if any category doesn't have enough videos
            let combinedVideos = [...selectedSameChannel, ...selectedSearch, ...selectedSubscription];
            if (combinedVideos.length < availableSlots) {
                const remaining = availableSlots - combinedVideos.length;
                const additionalVideos = OptimizedUtils.shuffleArray(otherVideos).slice(0, remaining);
                combinedVideos = [...combinedVideos, ...additionalVideos];
            }

            const finalVideos = OptimizedUtils.removeDuplicates(combinedVideos);

            // Add next episode at the VERY TOP if found
            if (nextEpisode) {
                finalVideos.unshift(nextEpisode);
                OptimizedUtils.log(`🎬 Next episode added to top: "${nextEpisode.title}"`);
            }

            OptimizedUtils.log(`Watch Next weighting: ${nextEpisode ? '1 next episode + ' : ''}${selectedSameChannel.length} same channel (${CONFIG.sameChannelVideoPercentage * 100}%) + ${selectedSearch.length} search (${CONFIG.searchTermVideoPercentage * 100}%) + ${selectedSubscription.length} subscription`);

            return finalVideos; // Don't shuffle to keep next episode at top
        }

        async loadVideosFromSubscriptions(isRefresh = false) {
            const subscriptions = this.subscriptionManager.getSubscriptions();

            if (subscriptions.length === 0) {
                return [];
            }

            OptimizedUtils.log('Loading videos from subscriptions' + (isRefresh ? ' (refresh mode)' : '') + '...');

            const existingVideos = this.videoCache.get('subscription_videos') || [];
            const allVideos = [];
            const endDate = new Date(this.maxDate);
            endDate.setHours(23, 59, 59, 999);

            // Load viral videos
            const viralVideos = await this.apiManager.getViralVideos(endDate, isRefresh);
            OptimizedUtils.log('Loaded ' + viralVideos.length + ' viral videos');

            // Load from subscriptions in batches
            for (let i = 0; i < subscriptions.length; i += CONFIG.batchSize) {
                const batch = subscriptions.slice(i, i + CONFIG.batchSize);

                const batchPromises = batch.map(async (sub) => {
                    try {
                        let channelId = sub.id;
                        if (!channelId) {
                            channelId = await this.getChannelIdByName(sub.name);
                        }

                        if (channelId) {
                            const videos = await this.getChannelVideos(channelId, sub.name, endDate, isRefresh);
                            return videos;
                        }
                        return [];
                    } catch (error) {
                        OptimizedUtils.log('Failed to load videos for ' + sub.name + ':', error);
                        return [];
                    }
                });

                const batchResults = await Promise.all(batchPromises);
                batchResults.forEach(videos => allVideos.push(...videos));

                if (i + CONFIG.batchSize < subscriptions.length) {
                    await OptimizedUtils.sleep(CONFIG.apiCooldown);
                }
            }

            // Mix videos for refresh mode
            let finalVideos = allVideos;
            if (isRefresh && existingVideos.length > 0) {
                const existingViralVideos = this.videoCache.get('viral_videos') || [];
                finalVideos = this.mixVideosForRefresh(finalVideos, existingVideos, viralVideos, existingViralVideos);
                OptimizedUtils.log('Mixed ' + finalVideos.length + ' new videos with ' + existingVideos.length + ' existing videos');
            } else {
                finalVideos = finalVideos.concat(viralVideos);
            }

            // Remove duplicates and shuffle final result
            finalVideos = OptimizedUtils.removeDuplicates(finalVideos);
            finalVideos = OptimizedUtils.shuffleArray(finalVideos);

            // Cache results
            this.videoCache.set('viral_videos', viralVideos);
            this.videoCache.set('subscription_videos', finalVideos);
            OptimizedUtils.log('Loaded ' + finalVideos.length + ' total videos from subscriptions');

            return finalVideos;
        }

        mixVideosForRefresh(newVideos, existingVideos, newViralVideos = [], existingViralVideos = []) {
            const totalDesired = Math.max(CONFIG.maxHomepageVideos, existingVideos.length);
            const viralVideoCount = Math.floor(totalDesired * CONFIG.viralVideoPercentage);
            const remainingSlots = totalDesired - viralVideoCount;
            const newVideoCount = Math.floor(remainingSlots * CONFIG.refreshVideoPercentage);
            const existingVideoCount = remainingSlots - newVideoCount;

            OptimizedUtils.log('Mixing videos: ' + newVideoCount + ' new + ' + existingVideoCount + ' existing + ' + viralVideoCount + ' viral');

            const selectedNew = OptimizedUtils.shuffleArray(newVideos).slice(0, newVideoCount);
            const selectedExisting = OptimizedUtils.shuffleArray(existingVideos).slice(0, existingVideoCount);

            const allViralVideos = newViralVideos.concat(existingViralVideos);
            const selectedViral = OptimizedUtils.shuffleArray(allViralVideos).slice(0, viralVideoCount);

            const mixedVideos = selectedNew.concat(selectedExisting).concat(selectedViral);
            return OptimizedUtils.shuffleArray(mixedVideos);
        }

        async getChannelIdByName(channelName) {
            const cacheKey = 'channel_id_' + channelName;
            let channelId = this.apiManager.getCache(cacheKey);

            if (!channelId) {
                try {
                    const response = await this.apiManager.makeRequest(`${this.apiManager.baseUrl}/search`, {
                        part: 'snippet',
                        q: channelName,
                        type: 'channel',
                        maxResults: 1
                    });

                    if (response.items && response.items.length > 0) {
                        channelId = response.items[0].snippet.channelId;
                        this.apiManager.setCache(cacheKey, channelId);
                        this.stats.apiCalls++;
                    }
                } catch (error) {
                    OptimizedUtils.log('Failed to find channel ID for ' + channelName + ':', error);
                }
            } else {
                this.stats.cacheHits++;
            }

            return channelId;
        }

        async getChannelVideos(channelId, channelName, endDate, forceRefresh = false) {
            const cacheKey = 'channel_videos_' + channelId + '_' + this.settings.date;
            let videos = this.apiManager.getCache(cacheKey, forceRefresh);

            if (!videos) {
                try {
                    const response = await this.apiManager.makeRequest(`${this.apiManager.baseUrl}/search`, {
                        part: 'snippet',
                        channelId: channelId,
                        type: 'video',
                        order: 'date',
                        publishedBefore: endDate.toISOString(),
                        maxResults: CONFIG.videosPerChannel
                    });

                    videos = response.items ? response.items.map(item => ({
                        id: item.id.videoId,
                        title: item.snippet.title,
                        channel: item.snippet.channelTitle || channelName,
                        channelId: item.snippet.channelId,
                        thumbnail: item.snippet.thumbnails?.medium?.url || item.snippet.thumbnails?.default?.url || '',
                        publishedAt: item.snippet.publishedAt,
                        description: item.snippet.description || '',
                        viewCount: this.apiManager.generateRealisticViewCount(item.snippet.publishedAt, endDate),
                        relativeDate: OptimizedUtils.calculateRelativeDate(item.snippet.publishedAt, endDate)
                    })) : [];

                    this.apiManager.setCache(cacheKey, videos, forceRefresh);
                    this.stats.apiCalls++;
                } catch (error) {
                    OptimizedUtils.log('Failed to get videos for channel ' + channelName + ':', error);
                    videos = [];
                }
            } else {
                this.stats.cacheHits++;
            }

            return videos;
        }

        // === PAGE HANDLING ===
        startFiltering() {
            OptimizedUtils.log('Starting ultra-aggressive video filtering...');

            const filterVideos = () => {
                if (this.isProcessing || !this.settings.active) return;
                this.isProcessing = true;

                const videoSelectors = [
                    'ytd-video-renderer',
                    'ytd-grid-video-renderer',
                    'ytd-rich-item-renderer',
                    'ytd-compact-video-renderer',
                    'ytd-movie-renderer',
                    'ytd-playlist-renderer'
                ];

                let processed = 0;
                let filtered = 0;

                videoSelectors.forEach(selector => {
                    const videos = document.querySelectorAll(selector);
                    videos.forEach(video => {
                        if (video.dataset.tmProcessed) return;

                        video.dataset.tmProcessed = 'true';
                        processed++;

                        if (this.shouldHideVideo(video)) {
                            video.style.display = 'none';
                            filtered++;
                        }
                    });
                });

                if (processed > 0) {
                    this.stats.processed += processed;
                    this.stats.filtered += filtered;
                }

                this.isProcessing = false;
            };

            setInterval(filterVideos, CONFIG.updateInterval);
        }

        shouldHideVideo(videoElement) {
            // Check for Shorts
            if (this.isShorts(videoElement)) {
                return true;
            }

            // Check video date
            const videoDate = this.extractVideoDate(videoElement);
            if (videoDate && videoDate > this.maxDate) {
                return true;
            }

            return false;
        }

        isShorts(element) {
            const shortsIndicators = CONFIG.SHORTS_SELECTORS;

            return shortsIndicators.some(selector => {
                try {
                    return element.matches(selector) || element.querySelector(selector);
                } catch (e) {
                    return false;
                }
            });
        }

        extractVideoDate(videoElement) {
            const dateSelectors = [
                '#metadata-line span:last-child',
                '#published-time-text',
                '[aria-label*="ago"]'
            ];

            for (const selector of dateSelectors) {
                const element = videoElement.querySelector(selector);
                if (element) {
                    const dateText = element.textContent?.trim();
                    if (dateText) {
                        return this.parseRelativeDate(dateText);
                    }
                }
            }

            return null;
        }

        parseRelativeDate(dateText) {
            const now = this.maxDate;
            const text = dateText.toLowerCase();

            const minuteMatch = text.match(/(\d+)\s*minutes?\s*ago/);
            if (minuteMatch) {
                return new Date(now.getTime() - parseInt(minuteMatch[1]) * 60 * 1000);
            }

            const hourMatch = text.match(/(\d+)\s*hours?\s*ago/);
            if (hourMatch) {
                return new Date(now.getTime() - parseInt(hourMatch[1]) * 60 * 60 * 1000);
            }

            const dayMatch = text.match(/(\d+)\s*days?\s*ago/);
            if (dayMatch) {
                return new Date(now.getTime() - parseInt(dayMatch[1]) * 24 * 60 * 60 * 1000);
            }

            const weekMatch = text.match(/(\d+)\s*weeks?\s*ago/);
            if (weekMatch) {
                return new Date(now.getTime() - parseInt(weekMatch[1]) * 7 * 24 * 60 * 60 * 1000);
            }

            const monthMatch = text.match(/(\d+)\s*months?\s*ago/);
            if (monthMatch) {
                return new Date(now.getTime() - parseInt(monthMatch[1]) * 30 * 24 * 60 * 60 * 1000);
            }

            const yearMatch = text.match(/(\d+)\s*years?\s*ago/);
            if (yearMatch) {
                return new Date(now.getTime() - parseInt(yearMatch[1]) * 365 * 24 * 60 * 60 * 1000);
            }

            return null;
        }

        startHomepageReplacement() {
            // More aggressive immediate hiding of original homepage
            const nukeOriginalContent = () => {
                if (!this.isHomePage()) return;

                const selectors = [
                    'ytd-rich-grid-renderer',
                    'ytd-rich-section-renderer', 
                    '#contents ytd-rich-item-renderer',
                    'ytd-browse[page-subtype="home"] #contents',
                    '.ytd-rich-grid-renderer'
                ];

                selectors.forEach(selector => {
                    const elements = document.querySelectorAll(selector);
                    elements.forEach(el => {
                        if (!el.dataset.tmNuked && !el.dataset.tmReplaced) {
                            el.style.opacity = '0';
                            el.style.visibility = 'hidden';
                            el.dataset.tmNuked = 'true';
                        }
                    });
                });
            };

            const replaceHomepage = () => {
                if (this.isHomePage() && this.settings.active) {
                    const container = document.querySelector('ytd-browse[page-subtype="home"] ytd-rich-grid-renderer');
                    if (container && !container.dataset.tmReplaced) {
                        container.dataset.tmReplaced = 'true';
                        container.style.opacity = '1';
                        container.style.visibility = 'visible';
                        this.replaceHomepage(container);
                    }
                }
            };

            // Immediately nuke original content
            nukeOriginalContent();

            // Continuous nuking and replacement
            setInterval(() => {
                nukeOriginalContent();
                replaceHomepage();
            }, 100); // More frequent to catch dynamic content
        }

        isHomePage() {
            return location.pathname === '/' || location.pathname === '';
        }

        async replaceHomepage(container, isRefresh = false) {
            OptimizedUtils.log('Replacing homepage' + (isRefresh ? ' (refresh)' : '') + '...');

            container.innerHTML = '<div class="tm-loading">Loading...</div>';

            try {
                // Use SINGLE unified cache - no separate checking
                const cacheKey = `all_videos_unified_${this.maxDate.toDateString()}`;
                let videos = this.videoCache.get(cacheKey) || this.videoCache.get('all_videos');
                
                OptimizedUtils.log('Homepage cache check:', videos ? `${videos.length} cached videos found` : 'No cached videos');

                if (!videos || videos.length === 0) {
                    // Keep trying without timeout - let it load as long as needed
                    try {
                        videos = await this.loadAllVideos(isRefresh);
                    } catch (error) {
                        OptimizedUtils.log('Failed to load videos:', error);
                        videos = [];
                    }
                }

                if (videos && videos.length > 0) {
                    // Completely randomize videos each time
                    // Use weighted shuffle to favor newer videos while keeping older ones visible
                    this.allHomepageVideos = OptimizedUtils.weightedShuffleByDate(videos, this.maxDate);
                    this.currentVideoIndex = 0;

                    // Show initial batch - use smaller initial count to ensure "Load more" appears
                    const initialBatchSize = Math.min(CONFIG.homepageLoadMoreSize || 20, this.allHomepageVideos.length);
                    const initialVideos = this.allHomepageVideos.slice(0, initialBatchSize);
                    this.currentVideoIndex = initialBatchSize;

                    const videoCards = initialVideos.map(video => `
                        <div class="tm-video-card" data-video-id="${video.id}">
                            <img src="${video.thumbnail}" alt="${video.title}">
                            <div class="tm-video-info">
                                <div class="tm-video-title">${video.title}</div>
                                <div class="tm-video-channel">${video.channel}</div>
                                <div class="tm-video-meta">
                                    <span>${video.viewCount} views</span>
                                    <span>•</span>
                                    <span>${video.relativeDate}</span>
                                </div>
                            </div>
                        </div>
                    `).join('');

                    const hasMoreVideos = this.currentVideoIndex < this.allHomepageVideos.length;

                    container.innerHTML = `
                        <div style="margin-bottom: 20px; text-align: center;">
                            <button id="tm-new-videos-btn" style="
                                background: #ff0000; 
                                color: white; 
                                border: none; 
                                padding: 12px 24px; 
                                border-radius: 6px; 
                                font-size: 14px; 
                                font-weight: 500;
                                cursor: pointer;
                                transition: background-color 0.2s;
                            ">New videos</button>
                        </div>
                        <div class="tm-homepage-grid" id="tm-video-grid">${videoCards}</div>
                        ${hasMoreVideos ? `
                        <div style="margin: 30px 0; text-align: center;">
                            <button id="tm-load-more-btn" style="
                                background: #333; 
                                color: white; 
                                border: none; 
                                padding: 12px 24px; 
                                border-radius: 6px; 
                                font-size: 14px; 
                                cursor: pointer;
                                transition: background-color 0.2s;
                            ">Load more videos</button>
                        </div>
                        ` : ''}
                    `;

                    this.attachHomepageClickHandlers();
                    this.attachNewVideosButton();
                    this.attachLoadMoreButton();
                } else {
                    // Show helpful message when no videos are available
                    container.innerHTML = `
                        <div class="tm-no-content" style="text-align: center; padding: 40px;">
                            <h3>No videos found for ${this.maxDate.toLocaleDateString()}</h3>
                            <p>This could mean:</p>
                            <ul style="text-align: left; display: inline-block;">
                                <li>No API keys are configured</li>
                                <li>No subscriptions are set up</li>
                                <li>No videos were uploaded before this date</li>
                            </ul>
                            <p>Click the ⚙️ button to add API keys and configure subscriptions.</p>
                        </div>
                    `;
                }
            } catch (error) {
                OptimizedUtils.log('Homepage replacement failed:', error);
                container.innerHTML = `
                    <div class="tm-error" style="text-align: center; padding: 40px; color: #f44336;">
                        <h3>Failed to load content</h3>
                        <p>Error: ${error.message}</p>
                        <p>Check your API keys and try again.</p>
                    </div>
                `;
            }
        }

        attachHomepageClickHandlers() {
            document.querySelectorAll('.tm-video-card').forEach(card => {
                card.addEventListener('click', () => {
                    const videoId = card.dataset.videoId;
                    if (videoId) {
                        window.location.href = '/watch?v=' + videoId;
                    }
                });
            });
        }

        attachNewVideosButton() {
            const button = document.getElementById('tm-new-videos-btn');
            if (button) {
                button.addEventListener('click', async () => {
                    button.textContent = 'Loading...';
                    button.disabled = true;

                    try {
                        await this.loadAllVideos(true);
                        const container = document.querySelector('ytd-browse[page-subtype="home"] ytd-rich-grid-renderer');
                        if (container) {
                            container.dataset.tmReplaced = '';
                            this.replaceHomepage(container, true);
                        }
                    } catch (error) {
                        OptimizedUtils.log('Failed to load new videos:', error);
                        button.textContent = 'New videos';
                        button.disabled = false;
                    }
                });

                button.addEventListener('mouseenter', () => {
                    button.style.backgroundColor = '#d50000';
                });

                button.addEventListener('mouseleave', () => {
                    button.style.backgroundColor = '#ff0000';
                });
            }
        }

        attachLoadMoreButton() {
            const button = document.getElementById('tm-load-more-btn');
            if (!button) return;

            button.addEventListener('click', () => {
                const videoGrid = document.getElementById('tm-video-grid');
                if (!videoGrid || !this.allHomepageVideos || this.currentVideoIndex >= this.allHomepageVideos.length) return;

                const nextBatch = this.allHomepageVideos.slice(
                    this.currentVideoIndex, 
                    this.currentVideoIndex + CONFIG.homepageLoadMoreSize
                );

                if (nextBatch.length === 0) return;

                const videoCards = nextBatch.map(video => `
                    <div class="tm-video-card" data-video-id="${video.id}">
                        <img src="${video.thumbnail}" alt="${video.title}">
                        <div class="tm-video-info">
                            <div class="tm-video-title">${video.title}</div>
                            <div class="tm-video-channel">${video.channel}</div>
                            <div class="tm-video-meta">
                                <span>${video.viewCount} views</span>
                                <span>•</span>
                                <span>${video.relativeDate}</span>
                            </div>
                        </div>
                    </div>
                `).join('');

                videoGrid.innerHTML += videoCards;
                this.currentVideoIndex += nextBatch.length;

                // Attach click handlers to new cards - use event delegation
                this.attachHomepageClickHandlers();

                // Hide button if no more videos
                if (this.currentVideoIndex >= this.allHomepageVideos.length) {
                    button.style.display = 'none';
                }
            });

            button.addEventListener('mouseenter', () => {
                button.style.backgroundColor = '#555';
            });

            button.addEventListener('mouseleave', () => {
                button.style.backgroundColor = '#333';
            });
        }

        startVideoPageEnhancement() {
            // Watch for URL changes to detect new video clicks
            let currentVideoId = new URL(location.href).searchParams.get('v');

            const checkVideoPage = () => {
                if (location.pathname === '/watch' && this.settings.active) {
                    const newVideoId = new URL(location.href).searchParams.get('v');

                    // More aggressive and frequent content nuking
                    this.nukeOriginalWatchNextContent();

                    const sidebar = document.querySelector('#secondary #secondary-inner');
                    if (sidebar) {
                        if (!sidebar.dataset.tmEnhanced || newVideoId !== currentVideoId) {
                            sidebar.dataset.tmEnhanced = 'true';
                            currentVideoId = newVideoId;
                            this.enhanceVideoPage(sidebar);
                        }
                        // Continuously nuke original content to prevent it from reappearing
                        setTimeout(() => this.nukeOriginalWatchNextContent(), 100);
                        setTimeout(() => this.nukeOriginalWatchNextContent(), 500);
                        setTimeout(() => this.nukeOriginalWatchNextContent(), 1000);
                    }
                }
            };

            // Check more frequently
            setInterval(checkVideoPage, 200);

            // Listen for popstate events (back/forward navigation)
            window.addEventListener('popstate', () => setTimeout(checkVideoPage, 50));

            // Listen for pushstate events (clicking on videos)
            const originalPushState = history.pushState;
            history.pushState = function() {
                originalPushState.apply(this, arguments);
                setTimeout(checkVideoPage, 50);
            };

            // Also listen for replaceState
            const originalReplaceState = history.replaceState;
            history.replaceState = function() {
                originalReplaceState.apply(this, arguments);
                setTimeout(checkVideoPage, 50);
            };
        }

        nukeOriginalWatchNextContent() {
            const selectors = [
                '#related', 
                'ytd-watch-next-secondary-results-renderer',
                '#secondary #secondary-inner > *:not(.tm-watch-next):not([data-tm-enhanced])',
                'ytd-compact-video-renderer:not([data-tm-enhanced])',
                'ytd-continuation-item-renderer',
                '#secondary-inner ytd-item-section-renderer:not([data-tm-enhanced])',
                '#secondary-inner ytd-shelf-renderer:not([data-tm-enhanced])',
                'ytd-watch-next-secondary-results-renderer *',
                '#secondary-inner > ytd-watch-next-secondary-results-renderer'
            ];

            selectors.forEach(selector => {
                const elements = document.querySelectorAll(selector);
                elements.forEach(el => {
                    if (!el.classList.contains('tm-watch-next') && !el.dataset.tmEnhanced) {
                        el.style.display = 'none !important';
                        el.style.visibility = 'hidden';
                        el.style.height = '0';
                        el.style.overflow = 'hidden';
                        el.setAttribute('data-tm-nuked', 'true');
                    }
                });
            });
        }

        async enhanceVideoPage(sidebar) {
            if (!this.settings.active) return;

            OptimizedUtils.log('Enhancing video page...');

            // Clear everything first
            this.clearSidebar(sidebar);

            // Create permanent container
            const permanentContainer = document.createElement('div');
            permanentContainer.id = 'tm-permanent-sidebar';
            permanentContainer.dataset.tmEnhanced = 'true';
            permanentContainer.style.cssText = `
                position: relative !important;
                z-index: 999999 !important;
                background: #0f0f0f !important;
                min-height: 400px !important;
            `;

            // Silent loading - no visible indicator
            permanentContainer.innerHTML = '<div style="height: 20px;"></div>';

            sidebar.innerHTML = '';
            sidebar.appendChild(permanentContainer);

            try {
                // Get current video information for same-channel weighting and series advancement
                const currentVideoId = this.getCurrentVideoId();
                const currentChannelId = await this.getCurrentChannelId(currentVideoId);
                
                // Get current video title and channel name from page DOM
                const currentVideoTitle = this.getCurrentVideoTitle();
                const currentChannelName = this.getCurrentChannelName();

                // FIXED: Use SINGLE unified cache - no separate checking or combining
                const cacheKey = `all_videos_unified_${this.maxDate.toDateString()}`;
                let videos = this.videoCache.get(cacheKey) || this.videoCache.get('all_videos');
                
                if (!videos || videos.length === 0) {
                    // Only load if absolutely no cached videos exist
                    OptimizedUtils.log('No cached videos found, loading initial set...');
                    videos = await this.loadAllVideos(false); 
                } else {
                    OptimizedUtils.log(`Using ${videos.length} cached videos for watch next (no reload)`);
                }

                if (videos && videos.length > 0) {
                    // Apply watch next weighting with same channel priority and series advancement
                    const weightedVideos = await this.createWatchNextWeightedVideos(videos, currentChannelId, currentVideoTitle, currentChannelName);

                    // Store all videos for load more functionality
                    this.allWatchNextVideos = weightedVideos;
                    this.currentWatchNextIndex = 0;

                    // Use smaller initial batch to ensure "Load more" appears
                    const initialBatchSize = Math.min(CONFIG.homepageLoadMoreSize || 12, this.allWatchNextVideos.length);
                    const initialBatch = this.allWatchNextVideos.slice(0, initialBatchSize);
                    this.currentWatchNextIndex = initialBatch.length;

                    this.createWatchNextSectionInContainer(permanentContainer, initialBatch);
                } else {
                    permanentContainer.innerHTML = `
                        <div style="padding: 20px; text-align: center; border: 1px solid #f44336; margin: 10px 0;">
                            <div style="color: #f44336; font-weight: bold;">No videos found for ${this.maxDate.toLocaleDateString()}</div>
                            <div style="font-size: 12px; color: #666; margin-top: 5px;">Check your API keys in settings</div>
                        </div>
                    `;
                }
            } catch (error) {
                OptimizedUtils.log('Video page enhancement failed:', error);
                permanentContainer.innerHTML = `
                    <div style="padding: 20px; text-align: center; border: 1px solid #f44336; margin: 10px 0;">
                        <div style="color: #f44336; font-weight: bold;">Error loading content</div>
                        <div style="font-size: 12px; color: #666; margin-top: 5px;">${error.message}</div>
                    </div>
                `;
            }

            // Protect our container from being removed
            this.protectSidebarContent(permanentContainer);
        }

        clearSidebar(sidebar) {
            // Completely clear sidebar
            const children = [...sidebar.children];
            children.forEach(child => {
                if (!child.dataset.tmEnhanced) {
                    child.remove();
                }
            });
        }

        protectSidebarContent(container) {
            // Set up mutation observer to protect our content
            if (this.sidebarProtector) {
                this.sidebarProtector.disconnect();
            }

            this.sidebarProtector = new MutationObserver((mutations) => {
                mutations.forEach((mutation) => {
                    if (mutation.type === 'childList') {
                        // If our container was removed, re-add it
                        if (!document.getElementById('tm-permanent-sidebar')) {
                            const sidebar = document.querySelector('#secondary #secondary-inner');
                            if (sidebar && container.parentNode !== sidebar) {
                                sidebar.innerHTML = '';
                                sidebar.appendChild(container);
                            }
                        }

                        // Remove any new content that's not ours
                        const sidebar = document.querySelector('#secondary #secondary-inner');
                        if (sidebar) {
                            const children = [...sidebar.children];
                            children.forEach(child => {
                                if (child.id !== 'tm-permanent-sidebar' && !child.dataset.tmEnhanced) {
                                    child.style.display = 'none';
                                }
                            });
                        }
                    }
                });
            });

            const sidebar = document.querySelector('#secondary #secondary-inner');
            if (sidebar) {
                this.sidebarProtector.observe(sidebar, {
                    childList: true,
                    subtree: true
                });
            }
        }

        createWatchNextSectionInContainer(container, videos) {
            const videoCards = videos.map(video => {
                // Remove the "NEXT EPISODE" badge as requested
                const nextEpisodeBadge = '';
                
                return `
                    <div class="tm-watch-next-card" data-video-id="${video.id}" style="position: relative;">
                        ${nextEpisodeBadge}
                        <img src="${video.thumbnail}" alt="${video.title}">
                        <div class="tm-watch-next-info">
                            <div class="tm-watch-next-title">${video.title}</div>
                            <div class="tm-watch-next-channel">${video.channel}</div>
                            <div class="tm-watch-next-meta">${video.viewCount} views • ${video.relativeDate}</div>
                        </div>
                    </div>
                `;
            }).join('');

            container.innerHTML = `
                <div class="tm-watch-next">
                    <h3>Watch next</h3>
                    <div class="tm-watch-next-grid" id="tm-watch-next-grid">${videoCards}</div>
                </div>
            `;

            this.attachWatchNextClickHandlers();
            this.setupWatchNextLoadMore(container);
        }

        setupWatchNextLoadMore(container) {
            // Add load more button if there are more videos
            if (this.allWatchNextVideos && this.currentWatchNextIndex < this.allWatchNextVideos.length) {
                const loadMoreBtn = document.createElement('button');
                loadMoreBtn.id = 'tm-watch-next-load-more';
                loadMoreBtn.style.cssText = `
                    width: 100%;
                    background: #333;
                    color: white;
                    border: none;
                    padding: 12px;
                    border-radius: 6px;
                    font-size: 14px;
                    cursor: pointer;
                    margin-top: 16px;
                    transition: background-color 0.2s;
                `;
                loadMoreBtn.textContent = 'Load more suggestions';

                const watchNextSection = container.querySelector('.tm-watch-next');
                watchNextSection.appendChild(loadMoreBtn);

                loadMoreBtn.addEventListener('click', () => {
                    const watchNextGrid = document.getElementById('tm-watch-next-grid');
                    if (!watchNextGrid || !this.allWatchNextVideos || this.currentWatchNextIndex >= this.allWatchNextVideos.length) return;

                    const nextBatch = this.allWatchNextVideos.slice(
                        this.currentWatchNextIndex,
                        this.currentWatchNextIndex + CONFIG.homepageLoadMoreSize
                    );

                    if (nextBatch.length === 0) return;

                    const videoCards = nextBatch.map(video => `
                        <div class="tm-watch-next-card" data-video-id="${video.id}">
                            <img src="${video.thumbnail}" alt="${video.title}">
                            <div class="tm-watch-next-info">
                                <div class="tm-watch-next-title">${video.title}</div>
                                <div class="tm-watch-next-channel">${video.channel}</div>
                                <div class="tm-watch-next-meta">${video.viewCount} views • ${video.relativeDate}</div>
                            </div>
                        </div>
                    `).join('');

                    watchNextGrid.innerHTML += videoCards;
                    this.currentWatchNextIndex += nextBatch.length;

                    // Reattach click handlers
                    this.attachWatchNextClickHandlers();

                    // Hide button if no more videos
                    if (this.currentWatchNextIndex >= this.allWatchNextVideos.length) {
                        loadMoreBtn.style.display = 'none';
                    }
                });

                loadMoreBtn.addEventListener('mouseenter', () => {
                    loadMoreBtn.style.backgroundColor = '#555';
                });

                loadMoreBtn.addEventListener('mouseleave', () => {
                    loadMoreBtn.style.backgroundColor = '#333';
                });
            }
        }



        attachWatchNextClickHandlers() {
            document.querySelectorAll('.tm-watch-next-card').forEach(card => {
                card.addEventListener('click', () => {
                    const videoId = card.dataset.videoId;
                    if (videoId) {
                        window.location.href = '/watch?v=' + videoId;
                    }
                });
            });
        }



        setupAutoRefresh() {
            if (CONFIG.autoRefreshInterval) {
                OptimizedUtils.log('Setting up auto-refresh every ' + (CONFIG.autoRefreshInterval / 60000) + ' minutes');

                setInterval(() => {
                    if (this.isHomePage() && this.settings.active) {
                        OptimizedUtils.log('Auto-refresh triggered');
                        this.loadAllVideos(true).then(() => {
                            const container = document.querySelector('ytd-browse[page-subtype="home"] ytd-rich-grid-renderer');
                            if (container) {
                                this.replaceHomepage(container, true);
                            }
                        });
                    }
                }, CONFIG.autoRefreshInterval);
            }
        }

        // === PUBLIC API METHODS ===
        removeApiKey(index) {
            if (this.apiManager.removeKey(this.apiManager.keys[index])) {
                this.uiManager.updateUI();
            }
        }

        removeSubscription(index) {
            if (this.subscriptionManager.removeSubscription(index)) {
                this.uiManager.updateUI();
            }
        }

        getStats() {
            return {
                apiCalls: this.stats.apiCalls,
                processed: this.stats.processed,
                cacheHits: this.stats.cacheHits,
                filtered: this.stats.filtered,
                isActive: this.settings.active,
                currentDate: this.settings.date
            };
        }

        cleanup() {
            if (this.autoRefreshTimer) {
                clearInterval(this.autoRefreshTimer);
            }
            if (this.filterTimer) {
                clearInterval(this.filterTimer);
            }

            OptimizedUtils.log('Application cleaned up');
        }

        getMaxDate() {
            return new Date(this.settings.date);
        }

        // Cache watched videos for channel page and general use
        cacheWatchedVideo(videoId) {
            if (!videoId) return;

            // Get current video details from page if possible
            const videoData = this.extractCurrentVideoData(videoId);

            if (videoData) {
                const existingWatchedVideos = GM_getValue('wayback_watched_videos_cache', []);

                const videoToCache = {
                    id: videoId,
                    title: videoData.title || 'Unknown Title',
                    channel: videoData.channel || 'Unknown Channel',
                    channelId: videoData.channelId || '',
                    thumbnail: videoData.thumbnail || '',
                    publishedAt: videoData.publishedAt || new Date().toISOString(),
                    description: videoData.description || '',
                    viewCount: videoData.viewCount || 'Unknown',
                    cachedAt: new Date().toISOString(),
                    source: 'watched_video'
                };

                // Check if already cached
                const existingIndex = existingWatchedVideos.findIndex(v => v.id === videoId);
                if (existingIndex >= 0) {
                    // Update existing entry
                    existingWatchedVideos[existingIndex] = videoToCache;
                } else {
                    // Add new entry
                    existingWatchedVideos.push(videoToCache);
                }

                // Limit cache size
                if (existingWatchedVideos.length > 5000) {
                    existingWatchedVideos.sort((a, b) => new Date(b.cachedAt) - new Date(a.cachedAt));
                    existingWatchedVideos.splice(5000);
                }

                GM_setValue('wayback_watched_videos_cache', existingWatchedVideos);
                OptimizedUtils.log(`Cached watched video: ${videoToCache.title}`);
            }
        }

        extractCurrentVideoData(videoId) {
            // Try to extract video data from current page
            try {
                const titleElement = document.querySelector('h1.title yt-formatted-string, h1.ytd-video-primary-info-renderer yt-formatted-string');
                const channelElement = document.querySelector('#owner-name a, #upload-info #channel-name a, ytd-channel-name a');
                const publishElement = document.querySelector('#info-strings yt-formatted-string, #date yt-formatted-string');
                const descElement = document.querySelector('#description yt-formatted-string, #meta-contents yt-formatted-string');
                const thumbnailElement = document.querySelector('video');

                return {
                    title: titleElement?.textContent?.trim() || 'Unknown Title',
                    channel: channelElement?.textContent?.trim() || 'Unknown Channel',
                    channelId: OptimizedUtils.extractChannelId(channelElement?.href || '') || '',
                    thumbnail: thumbnailElement?.poster || '',
                    publishedAt: this.parsePublishDate(publishElement?.textContent?.trim()) || new Date().toISOString(),
                    description: descElement?.textContent?.trim()?.substring(0, 200) || '',
                    viewCount: this.extractViewCount() || 'Unknown'
                };
            } catch (error) {
                OptimizedUtils.log('Error extracting video data:', error);
                return null;
            }
        }

        parsePublishDate(dateText) {
            if (!dateText) return null;

            // Handle "X years ago", "X months ago", etc.
            const relativeMatch = dateText.match(/(\d+)\s+(second|minute|hour|day|week|month|year)s?\s+ago/i);
            if (relativeMatch) {
                const amount = parseInt(relativeMatch[1]);
                const unit = relativeMatch[2].toLowerCase();
                const date = new Date();

                switch (unit) {
                    case 'second':
                        date.setSeconds(date.getSeconds() - amount);
                        break;
                    case 'minute':
                        date.setMinutes(date.getMinutes() - amount);
                        break;
                    case 'hour':
                        date.setHours(date.getHours() - amount);
                        break;
                    case 'day':
                        date.setDate(date.getDate() - amount);
                        break;
                    case 'week':
                        date.setDate(date.getDate() - (amount * 7));
                        break;
                    case 'month':
                        date.setMonth(date.getMonth() - amount);
                        break;
                    case 'year':
                        date.setFullYear(date.getFullYear() - amount);
                        break;
                }

                return date.toISOString();
            }

            return null;
        }

        extractViewCount() {
            const viewElement = document.querySelector('#count .view-count, #info-strings yt-formatted-string');
            if (viewElement) {
                const viewText = viewElement.textContent.trim();
                const viewMatch = viewText.match(/([\d,]+)\s*views?/i);
                return viewMatch ? viewMatch[1].replace(/,/g, '') : null;
            }
            return null;
        }

        replaceChannelPageWithCache() {
            const channelId = OptimizedUtils.extractChannelId(window.location.href);
            if (!channelId) return;

            const cachedVideos = this.getAllCachedChannelVideos(channelId);
            if (cachedVideos.length > 0) {
                this.replaceChannelPageVideos(cachedVideos, channelId);
            } else {
                // Show placeholder for empty cache
                this.showEmptyChannelCache(channelId);
            }
        }

        getAllCachedChannelVideos(channelId) {
            // Check multiple sources for channel videos
            const watchedVideos = GM_getValue('wayback_watched_videos_cache', []);
            const subscriptionVideos = this.videoCache.get('subscription_videos_only') || [];
            const searchTermVideos = this.videoCache.get('search_term_videos_only') || [];
            const allCachedVideos = this.videoCache.get('all_videos') || [];
            
            // Combine all sources and filter by channel
            const allVideoSources = [...watchedVideos, ...subscriptionVideos, ...searchTermVideos, ...allCachedVideos];
            
            OptimizedUtils.log(`Searching for channel videos with ID: "${channelId}"`);
            OptimizedUtils.log(`Total videos to search: ${allVideoSources.length}`);
            
            // Filter videos for this channel and sort by date (newest first)  
            const channelVideos = allVideoSources
                .filter(video => video.channelId === channelId)
                .sort((a, b) => new Date(b.publishedAt) - new Date(a.publishedAt));

            OptimizedUtils.log(`Found ${channelVideos.length} cached videos for channel ${channelId}`);
            return channelVideos;
        }

        showEmptyChannelCache(channelId) {
            // More aggressive channel content clearing
            const channelSelectors = [
                '#contents', 
                '#primary-inner', 
                'div[page-subtype="channels"]',
                '.page-container',
                '#page-manager',
                'ytd-browse[page-subtype="channels"]'
            ];

            let channelContent = null;
            for (const selector of channelSelectors) {
                channelContent = document.querySelector(selector);
                if (channelContent) break;
            }

            if (!channelContent) {
                // Fallback: use body if we can't find specific containers
                channelContent = document.body;
            }

            // Remove ALL existing YouTube channel content more aggressively
            const contentToRemove = channelContent.querySelectorAll(`
                ytd-c4-tabbed-header-renderer,
                ytd-channel-video-player-renderer,
                ytd-section-list-renderer,
                ytd-item-section-renderer,
                ytd-grid-renderer,
                ytd-shelf-renderer,
                .ytd-browse,
                #contents > *:not(#wayback-channel-content),
                .channel-header,
                .branded-page-v2-container
            `);
            
            contentToRemove.forEach(element => {
                if (element.id !== 'wayback-channel-content') {
                    element.style.display = 'none';
                }
            });

            // Remove existing wayback content
            const existingContent = document.querySelector('#wayback-channel-content');
            if (existingContent) {
                existingContent.remove();
            }

            // Create our replacement content
            const channelContainer = document.createElement('div');
            channelContainer.id = 'wayback-channel-content';
            channelContainer.style.cssText = `
                position: relative;
                z-index: 9999;
                background: white;
                min-height: 400px;
                width: 100%;
                padding: 20px;
            `;
            
            channelContainer.innerHTML = `
                <div style="padding: 40px; background: #f9f9f9; border-radius: 8px; margin: 20px 0; text-align: center;">
                    <h3 style="margin: 0 0 16px 0; color: #333;">No Cached Videos Found</h3>
                    <p style="margin: 0 0 20px 0; color: #666;">
                        No videos have been cached for this channel yet. Watch some videos from this channel 
                        or use the search button below to find historical content.
                    </p>
                    <button id="wayback-search-more-channel" class="wayback-button" style="
                        background: #ff4444; color: white; border: none; padding: 12px 24px; 
                        border-radius: 4px; cursor: pointer; font-size: 14px;
                    ">
                        🔍 Search Channel Videos
                    </button>
                </div>
            `;

            // Insert at the very beginning
            if (channelContent.firstChild) {
                channelContent.insertBefore(channelContainer, channelContent.firstChild);
            } else {
                channelContent.appendChild(channelContainer);
            }

            // Fix the function reference - get the correct context
            const searchButton = document.querySelector('#wayback-search-more-channel');
            if (searchButton) {
                searchButton.addEventListener('click', () => {
                    // Access through the global waybackTubeManager reference
                    if (window.waybackTubeManager && window.waybackTubeManager.searchMoreChannelVideos) {
                        window.waybackTubeManager.searchMoreChannelVideos(channelId, 'This Channel');
                    } else {
                        console.error('WayBackTube: searchMoreChannelVideos function not available');
                    }
                });
            }
        }

        setupChannelPageMonitoring() {
            // Monitor for URL changes to detect channel page navigation
            let currentUrl = window.location.href;

            const checkUrlChange = () => {
                if (window.location.href !== currentUrl) {
                    currentUrl = window.location.href;
                    if (OptimizedUtils.getCurrentPage() === 'channel' && this.settings.active) {
                        setTimeout(() => {
                            this.replaceChannelPageWithCache();
                        }, 1500); // Give page time to load
                    }
                }
            };

            // Check URL changes frequently
            setInterval(checkUrlChange, 1000);

            // Also monitor DOM changes for channel page content
            const observer = new MutationObserver(() => {
                if (OptimizedUtils.getCurrentPage() === 'channel' && this.settings.active) {
                    // Debounce the replacement to avoid excessive calls
                    clearTimeout(this.channelReplaceTimeout);
                    this.channelReplaceTimeout = setTimeout(() => {
                        this.replaceChannelPageWithCache();
                    }, 2000);
                }
            });

            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        }
    }

    // === WORKING SEARCH ENHANCEMENT (COPIED VERBATIM) ===
    class OptimizedSearchEnhancement {
        constructor(timeMachine) {
            this.timeMachine = timeMachine;
            this.maxDate = timeMachine.getMaxDate();
            this.interceptedElements = new Set();
            this.init();
        }

        init() {
            this.log('Search enhancement starting...');
            this.setupSearchInterception();
            this.cleanupSearchResults();
            this.hideSearchSuggestions();
        }

        log(message, ...args) {
            if (CONFIG.debugMode) {
                console.log('[WayBackTube Search]', message, ...args);
            }
        }

        setupSearchInterception() {
            // Monitor for new elements being added to the page
            const observer = new MutationObserver(() => {
                this.interceptSearchInputs();
                this.interceptSearchButtons();
            });

            observer.observe(document.body, {
                childList: true,
                subtree: true
            });

            // Initial setup
            this.interceptSearchInputs();
            this.interceptSearchButtons();
        }

        interceptSearchInputs() {
            const interceptInput = (input) => {
                if (this.interceptedElements.has(input)) return;
                this.interceptedElements.add(input);

                input.addEventListener('keydown', (e) => {
                    if (e.key === 'Enter') {
                        e.preventDefault();
                        e.stopPropagation();
                        this.performSearch(input.value.trim(), input);
                    }
                });

                // Also intercept form submissions
                const form = input.closest('form');
                if (form && !this.interceptedElements.has(form)) {
                    this.interceptedElements.add(form);
                    form.addEventListener('submit', (e) => {
                        e.preventDefault();
                        e.stopPropagation();
                        this.performSearch(input.value.trim(), input);
                    });
                }
            };

            // Find all search inputs
            const searchInputs = document.querySelectorAll('input#search, input[name="search_query"]');
            searchInputs.forEach(interceptInput);
        }

        interceptSearchButtons() {
            const interceptButton = (btn) => {
                if (this.interceptedElements.has(btn)) return;
                this.interceptedElements.add(btn);

                btn.addEventListener('click', (e) => {
                    const input = document.querySelector('input#search, input[name="search_query"]');
                    if (input && input.value.trim()) {
                        e.preventDefault();
                        e.stopPropagation();
                        this.performSearch(input.value.trim(), input);
                    }
                });
            };

            // Find all search buttons
            const searchButtons = document.querySelectorAll(
                '#search-icon-legacy button, ' +
                'button[aria-label="Search"], ' +
                'ytd-searchbox button, ' +
                '.search-button'
            );
            searchButtons.forEach(interceptButton);
        }

        performSearch(query, inputElement) {
            this.log('Intercepting search for:', query);

            // Don't add before: if it already exists
            if (query.includes('before:')) {
                this.log('Search already contains before: filter, proceeding normally');
                this.executeSearch(query, inputElement);
                return;
            }

            // Add the before: filter to the actual search
            const beforeDate = this.maxDate.toISOString().split('T')[0];
            const modifiedQuery = query + ' before:' + beforeDate;

            this.log('Modified search query:', modifiedQuery);

            // Execute the search with the modified query
            this.executeSearch(modifiedQuery, inputElement);

            // Keep the original query visible in the input - multiple attempts
            const restoreOriginalQuery = () => {
                const searchInputs = document.querySelectorAll('input#search, input[name="search_query"]');
                searchInputs.forEach(input => {
                    if (input.value.includes('before:')) {
                        input.value = query;
                    }
                });
            };

            // Restore immediately and with delays
            restoreOriginalQuery();
            setTimeout(restoreOriginalQuery, 50);
            setTimeout(restoreOriginalQuery, 100);
            setTimeout(restoreOriginalQuery, 200);
            setTimeout(restoreOriginalQuery, 500);
            setTimeout(restoreOriginalQuery, 1000);
        }

        executeSearch(searchQuery, inputElement) {
            // Method 1: Try to use YouTube's search API directly
            if (this.tryYouTubeSearch(searchQuery)) {
                return;
            }

            // Method 2: Modify the URL and navigate
            const searchParams = new URLSearchParams();
            searchParams.set('search_query', searchQuery);

            const searchUrl = '/results?' + searchParams.toString();
            this.log('Navigating to search URL:', searchUrl);

            // Show loading indicator to prevent "offline" message
            this.showSearchLoading();

            window.location.href = searchUrl;
        }

        showSearchLoading() {
            // Create a temporary loading overlay to prevent offline message
            const loadingOverlay = document.createElement('div');
            loadingOverlay.id = 'tm-search-loading';
            loadingOverlay.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(15, 15, 15, 0.95);
                z-index: 999999;
                display: flex;
                align-items: center;
                justify-content: center;
                color: white;
                font-family: Roboto, Arial, sans-serif;
                font-size: 16px;
            `;

            loadingOverlay.innerHTML = `
                <div style="text-align: center;">
                    <div style="border: 2px solid #333; border-top: 2px solid #ff0000; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 0 auto 16px;"></div>
                    <div>Searching...</div>
                </div>
                <style>
                    @keyframes spin {
                        0% { transform: rotate(0deg); }
                        100% { transform: rotate(360deg); }
                    }
                </style>
            `;

            document.body.appendChild(loadingOverlay);

            // Remove loading overlay after a delay (in case search doesn't redirect)
            setTimeout(() => {
                const overlay = document.getElementById('tm-search-loading');
                if (overlay) overlay.remove();
            }, 5000);
        }

        tryYouTubeSearch(query) {
            try {
                // Try to trigger YouTube's internal search mechanism
                if (typeof window !== 'undefined' && window.ytplayer && window.ytplayer.config) {
                    // Use YouTube's internal router if available
                    if (typeof window.yt !== 'undefined' && window.yt && window.yt.www && window.yt.www.routing) {
                        window.yt.www.routing.navigate('/results?search_query=' + encodeURIComponent(query));
                        return true;
                    }
                }
                return false;
            } catch (e) {
                OptimizedUtils.log('YouTube internal search failed:', e);
                return false;
            }
        }

        cleanupSearchResults() {
            // Hide search filter chips that show the before: date
            const hideBeforeChips = () => {
                // Hide all elements that contain "before:" text
                const allElements = document.querySelectorAll('*');
                allElements.forEach(element => {
                    if (element.dataset.tmProcessedForBefore) return;

                    const text = element.textContent || element.innerText || '';
                    const ariaLabel = element.getAttribute('aria-label') || '';
                    const title = element.getAttribute('title') || '';

                    if (text.includes('before:') || ariaLabel.includes('before:') || title.includes('before:')) {
                        // Check if it's a search filter chip or similar element
                        if (element.matches('ytd-search-filter-renderer, ytd-toggle-button-renderer, [role="button"], .ytd-search-filter-renderer, .filter-chip')) {
                            element.style.display = 'none';
                            element.setAttribute('data-hidden-by-time-machine', 'true');
                            element.dataset.tmProcessedForBefore = 'true';
                        }
                    }
                });
            };

            // Run cleanup immediately and periodically
            hideBeforeChips();
            setInterval(hideBeforeChips, 200); // More frequent cleanup

            // Also run cleanup on page mutations
            const observer = new MutationObserver(() => {
                setTimeout(hideBeforeChips, 50);
                // Also restore search input if it shows before:
                setTimeout(() => {
                    const searchInputs = document.querySelectorAll('input#search, input[name="search_query"]');
                    searchInputs.forEach(input => {
                        if (input.value.includes('before:')) {
                            const originalQuery = input.value.replace(/\s*before:\d{4}-\d{2}-\d{2}/, '').trim();
                            if (originalQuery) {
                                input.value = originalQuery;
                            }
                        }
                    });
                }, 10);
            });

            observer.observe(document.body, {
                childList: true,
                subtree: true
            });

            // Continuous monitoring of search input
            const self = this;
            setInterval(() => {
                const searchInputs = document.querySelectorAll('input#search, input[name="search_query"]');
                searchInputs.forEach(input => {
                    if (input.value.includes('before:')) {
                        const originalQuery = input.value.replace(/\s*before:\d{4}-\d{2}-\d{2}/, '').trim();
                        if (originalQuery) {
                            input.value = originalQuery;
                        }
                    }
                });

                // Note: Date modification is handled by SearchManager, not FeedChipHider
            }, 100);
        }

        hideBeforeTags() {
            const beforeTags = document.querySelectorAll('span, div');
            beforeTags.forEach(element => {
                const text = element.textContent;
                if (text && text.includes('before:') && text.includes(this.maxDate.toISOString().split('T')[0])) {
                    element.style.display = 'none';
                    element.setAttribute('data-hidden-by-time-machine', 'true');
                }
            });

            const filterChips = document.querySelectorAll('ytd-search-filter-renderer');
            filterChips.forEach(chip => {
                const text = chip.textContent;
                if (text && text.includes('before:')) {
                    chip.style.display = 'none';
                    chip.setAttribute('data-hidden-by-time-machine', 'true');
                }
            });
        }

        hideSearchSuggestions() {
            // Hide search suggestions dropdown/autocomplete
            const hideSearchDropdown = () => {
                const selectors = [
                    'ytd-search-suggestions-renderer',
                    '.sbsb_a', // Google search suggestions
                    '#suggestions-wrapper',
                    '#suggestions',
                    '.search-suggestions',
                    'ytd-searchbox #suggestions',
                    'tp-yt-iron-dropdown',
                    '.ytp-suggestions-container',
                    '#masthead-search-suggestions',
                    '.search-autocomplete'
                ];

                selectors.forEach(selector => {
                    const elements = document.querySelectorAll(selector);
                    elements.forEach(el => {
                        if (!el.dataset.tmSuggestionHidden) {
                            el.style.display = 'none !important';
                            el.style.visibility = 'hidden !important';
                            el.style.opacity = '0 !important';
                            el.style.height = '0 !important';
                            el.style.overflow = 'hidden !important';
                            el.setAttribute('data-tm-suggestion-hidden', 'true');
                        }
                    });
                });
            };

            // Hide immediately and continuously
            hideSearchDropdown();
            setInterval(hideSearchDropdown, 100);

            // Set up mutation observer for dynamic suggestions
            const observer = new MutationObserver(() => {
                hideSearchDropdown();
            });

            observer.observe(document.body, {
                childList: true,
                subtree: true
            });

            // Also disable autocomplete attributes on search inputs
            const disableAutocomplete = () => {
                const searchInputs = document.querySelectorAll('input#search, input[name="search_query"]');
                searchInputs.forEach(input => {
                    if (!input.dataset.tmAutocompleteDisabled) {
                        input.setAttribute('autocomplete', 'off');
                        input.setAttribute('spellcheck', 'false');
                        input.dataset.tmAutocompleteDisabled = 'true';
                    }
                });
            };

            disableAutocomplete();
            setInterval(disableAutocomplete, 1000);
        }
    }

    // === TAB HIDING FUNCTIONALITY ===
    class TabHider {
        constructor() {
            this.tabsToHide = ['All', 'Music', 'Gaming', 'News', 'Live', 'Sports', 'Learning', 'Fashion & Beauty', 'Podcasts'];
            this.isActive = false;
        }

        init() {
            this.isActive = true;
            this.startHiding();
            OptimizedUtils.log('Tab hider initialized');
        }

        startHiding() {
            // Hide tabs immediately and then continuously
            this.hideTabs();
            setInterval(() => this.hideTabs(), 500);
        }

        hideTabs() {
            if (!this.isActive) return;

            // Hide YouTube navigation tabs
            const tabSelectors = [
                'tp-yt-paper-tab', 
                '.ytd-feed-filter-chip-bar-renderer',
                'ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer',
                '[role="tab"]'
            ];

            tabSelectors.forEach(selector => {
                const tabs = OptimizedUtils.$$(selector);
                tabs.forEach(tab => {
                    const text = tab.textContent?.trim();
                    if (text && this.tabsToHide.includes(text)) {
                        tab.style.display = 'none';
                        tab.setAttribute('data-hidden-by-wayback', 'true');
                    }
                });
            });

            // Hide feed filter chips
            const chipSelectors = [
                'yt-chip-cloud-chip-renderer',
                '.ytd-feed-filter-chip-bar-renderer yt-chip-cloud-chip-renderer',
                'ytd-feed-filter-chip-bar-renderer [role="tab"]'
            ];

            chipSelectors.forEach(selector => {
                const chips = OptimizedUtils.$$(selector);
                chips.forEach(chip => {
                    const text = chip.textContent?.trim();
                    if (text && this.tabsToHide.includes(text)) {
                        chip.style.display = 'none';
                        chip.setAttribute('data-hidden-by-wayback', 'true');
                    }
                });
            });

            // Hide entire filter bar if needed
            const filterBars = OptimizedUtils.$$('ytd-feed-filter-chip-bar-renderer');
            filterBars.forEach(bar => {
                const visibleChips = bar.querySelectorAll('yt-chip-cloud-chip-renderer:not([data-hidden-by-wayback])');
                if (visibleChips.length === 0) {
                    bar.style.display = 'none';
                }
            });
        }

        stop() {
            this.isActive = false;
            // Restore hidden tabs
            const hiddenElements = OptimizedUtils.$$('[data-hidden-by-wayback]');
            hiddenElements.forEach(element => {
                element.style.display = '';
                element.removeAttribute('data-hidden-by-wayback');
            });
        }
    }

    // === SUBSCRIPTION MANAGER ===
    class SubscriptionManager {
        constructor() {
            this.subscriptions = this.loadSubscriptions();
        }

        loadSubscriptions() {
            const saved = GM_getValue('ytSubscriptions', '[]');
            try {
                return JSON.parse(saved);
            } catch (e) {
                OptimizedUtils.log('Failed to parse subscriptions, using defaults');
                return this.getDefaultSubscriptions();
            }
        }

        getDefaultSubscriptions() {
            return [
                { name: 'PewDiePie', id: 'UC-lHJZR3Gqxm24_Vd_AJ5Yw' },
                { name: 'Markiplier', id: 'UC7_YxT-KID8kRbqZo7MyscQ' },
                { name: 'Jacksepticeye', id: 'UCYzPXprvl5Y-Sf0g4vX-m6g' },
                { name: 'VanossGaming', id: 'UCKqH_9mk1waLgBiL2vT5b9g' },
                { name: 'nigahiga', id: 'UCSAUGyc_xA8uYzaIVG6MESQ' },
                { name: 'Smosh', id: 'UCY30JRSgfhYXA6i6xX1erWg' },
                { name: 'RayWilliamJohnson', id: 'UCGt7X90Au6BV8rf49BiM6Dg' },
                { name: 'Fred', id: 'UCJKjhgPJcPlW0WV_YQCXq_A' },
                { name: 'Shane', id: 'UCtinbF-Q-fVthA0qrFQTgXQ' },
                { name: 'TheFineBros', id: 'UC0v-tlzsn0QZwJnkiaUSJVQ' }
            ];
        }

        saveSubscriptions() {
            GM_setValue('ytSubscriptions', JSON.stringify(this.subscriptions));
        }

        getSubscriptions() {
            return this.subscriptions;
        }

        addSubscription(name, id = null) {
            if (!name.trim()) return false;

            const subscription = { 
                name: name.trim(), 
                id: id 
            };

            // Check for duplicates
            const exists = this.subscriptions.some(sub => 
                sub.name.toLowerCase() === subscription.name.toLowerCase()
            );

            if (!exists) {
                this.subscriptions.push(subscription);
                this.saveSubscriptions();
                OptimizedUtils.log(`Added subscription: ${subscription.name}`);
                return true;
            }

            return false;
        }

        removeSubscription(index) {
            if (index >= 0 && index < this.subscriptions.length) {
                const removed = this.subscriptions.splice(index, 1)[0];
                this.saveSubscriptions();
                OptimizedUtils.log(`Removed subscription: ${removed.name}`);
                return true;
            }
            return false;
        }

        clearAllSubscriptions() {
            this.subscriptions = [];
            this.saveSubscriptions();
            OptimizedUtils.log('Cleared all subscriptions');
        }
    }

    // === FEED CHIP HIDER ===
    class FeedChipHider {
        constructor() {
            this.hiddenChips = new Set();
            this.initializeHiding();
        }

        initializeHiding() {
            setInterval(() => {
                this.hideTopTabs();
            }, 200);
        }

        hideTopTabs() {
            // Hide feed filter chips (All, Music, Gaming, etc.)
            CONFIG.FEED_CHIP_SELECTORS.forEach(selector => {
                const elements = document.querySelectorAll(selector);
                elements.forEach(element => {
                    if (!element.dataset.tmHidden) {
                        element.style.display = 'none !important';
                        element.style.visibility = 'hidden !important';
                        element.style.opacity = '0 !important';
                        element.style.height = '0 !important';
                        element.style.maxHeight = '0 !important';
                        element.style.overflow = 'hidden !important';
                        element.dataset.tmHidden = 'true';
                        this.hiddenChips.add(element);
                    }
                });
            });

            // Hide specific tab-like elements by text content
            const tabSelectors = [
                'yt-chip-cloud-chip-renderer',
                'ytd-feed-filter-chip-renderer',
                'paper-tab[role="tab"]',
                '[role="tab"]'
            ];

            tabSelectors.forEach(selector => {
                const tabs = document.querySelectorAll(selector);
                tabs.forEach(tab => {
                    const text = tab.textContent?.toLowerCase().trim();
                    if (text && ['all', 'music', 'gaming', 'news', 'live', 'sports', 'learning', 'fashion & beauty', 'gaming'].includes(text)) {
                        if (!tab.dataset.tmHidden) {
                            tab.style.display = 'none !important';
                            tab.style.visibility = 'hidden !important';
                            tab.dataset.tmHidden = 'true';
                            this.hiddenChips.add(tab);
                        }
                    }
                });
            });
        }

        hideSearchFilters() {
            const elementsToCheck = document.querySelectorAll('*:not([data-tm-processed-for-before])');

            elementsToCheck.forEach(element => {
                const text = element.textContent || '';
                const ariaLabel = element.getAttribute('aria-label') || '';
                const title = element.getAttribute('title') || '';

                if (text.includes('before:') || ariaLabel.includes('before:') || title.includes('before:')) {
                    if (element.matches('ytd-search-filter-renderer, .search-filter-chip, ytd-chip-cloud-chip-renderer, ytd-search-sub-menu-renderer *')) {
                        element.style.display = 'none !important';
                        element.style.visibility = 'hidden !important';
                        element.style.opacity = '0 !important';
                        element.style.height = '0 !important';
                        element.style.width = '0 !important';
                        element.style.position = 'absolute !important';
                        element.style.left = '-9999px !important';
                        element.setAttribute('data-hidden-by-time-machine', 'true');
                    }

                    let parent = element.parentElement;
                    while (parent && parent !== document.body) {
                        if (parent.matches('ytd-search-filter-renderer, ytd-chip-cloud-chip-renderer, ytd-search-sub-menu-renderer')) {
                            parent.style.display = 'none !important';
                            parent.setAttribute('data-hidden-by-time-machine', 'true');
                            break;
                        }
                        parent = parent.parentElement;
                    }
                }

                element.dataset.tmProcessedForBefore = 'true';
            });

            const specificSelectors = [
                'ytd-search-filter-renderer',
                'ytd-chip-cloud-chip-renderer',
                'ytd-search-sub-menu-renderer',
                '.search-filter-chip',
                '[data-text*="before:"]',
                '[aria-label*="before:"]',
                '[title*="before:"]'
            ];

            specificSelectors.forEach(selector => {
                try {
                    const elements = document.querySelectorAll(selector);
                    elements.forEach(element => {
                        element.style.display = 'none !important';
                        element.setAttribute('data-hidden-by-time-machine', 'true');
                    });
                } catch (e) {
                    // Ignore selector errors
                }
            });
        }
    }

    // === ENHANCED SEARCH MANAGER ===
    class SearchManager {
        constructor(apiManager, maxDate) {
            this.apiManager = apiManager;
            this.maxDate = maxDate;
            this.feedChipHider = new FeedChipHider();
            this.initializeSearchHiding();
        }

        initializeSearchHiding() {
            setInterval(() => {
                this.feedChipHider.hideSearchFilters();
                // Also modify dates in search results from the correct context
                if (OptimizedUtils.getCurrentPage() === 'search') {
                    this.modifyDatesInSearchResults();
                }
                // Process comments on watch pages
                if (OptimizedUtils.getCurrentPage() === 'watch') {
                    this.modifyCommentDates();
                }
            }, 500); // Increased interval to reduce excessive logging

            const observer = new MutationObserver(() => {
                setTimeout(() => {
                    this.feedChipHider.hideSearchFilters();
                    if (OptimizedUtils.getCurrentPage() === 'search') {
                        this.modifyDatesInSearchResults();
                    }
                    if (OptimizedUtils.getCurrentPage() === 'watch') {
                        this.modifyCommentDates();
                    }
                }, 2000); // Increased delay to prevent excessive processing
            });

            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        }

        modifyDatesInSearchResults() {
            if (OptimizedUtils.getCurrentPage() !== 'search') return;

            // Find all video duration/date elements in search results
            const videoElements = document.querySelectorAll('ytd-video-renderer, ytd-compact-video-renderer, ytd-grid-video-renderer');

            videoElements.forEach(videoElement => {
                if (videoElement.dataset.tmDateModified) return;

                // Look for upload date elements - using valid CSS selectors only
                const dateSelectors = [
                    '.ytd-video-meta-block .ytd-video-meta-block span:nth-child(2)',
                    '#metadata .ytd-video-meta-block span:nth-child(2)', 
                    '.ytd-video-meta-block div:nth-child(2)',
                    '.ytd-video-meta-block [aria-label*="ago"]',
                    '#metadata-line .ytd-video-meta-block span',
                    '#metadata .published-time-text',
                    '.video-time',
                    '.ytd-video-meta-block span:last-child'
                ];

                // Find elements containing "ago" text manually
                const metadataSpans = videoElement.querySelectorAll('[id*="metadata"] span');
                metadataSpans.forEach(span => {
                    if (span.textContent && span.textContent.includes('ago')) {
                        if (this.isRelativeDateElement(span)) {
                            this.updateRelativeDate(span);
                            videoElement.dataset.tmDateModified = 'true';
                        }
                    }
                });

                // Process other selectors
                for (const selector of dateSelectors) {
                    try {
                        const dateElement = videoElement.querySelector(selector);
                        if (dateElement && this.isRelativeDateElement(dateElement)) {
                            this.updateRelativeDate(dateElement);
                            videoElement.dataset.tmDateModified = 'true';
                            break;
                        }
                    } catch (error) {
                        // Skip invalid selectors
                        continue;
                    }
                }
            });
        }

        isRelativeDateElement(element) {
            const text = element.textContent || element.innerText || '';
            const relativePatterns = [
                /\d+\s+(year|month|week|day|hour|minute)s?\s+ago/i,
                /\d+\s+(yr|mo|wk|day|hr|min)s?\s+ago/i,
                /(yesterday|today)/i
            ];

            return relativePatterns.some(pattern => pattern.test(text));
        }

        updateRelativeDate(element) {
            const originalText = element.textContent || element.innerText || '';
            const maxDate = this.maxDate;

            if (!maxDate) return;

            // Parse the original relative date
            const match = originalText.match(/(\d+)\s+(year|month|week|day|hour|minute)s?\s+ago/i);

            if (match) {
                const value = parseInt(match[1]);
                const unit = match[2].toLowerCase();

                // Calculate original upload date from current time (not time machine date)
                const now = new Date();
                let uploadDate = new Date(now);

                // Use proper date arithmetic for accurate calculations
                switch (unit) {
                    case 'year':
                        uploadDate.setFullYear(uploadDate.getFullYear() - value);
                        break;
                    case 'month':
                        uploadDate.setMonth(uploadDate.getMonth() - value);
                        break;
                    case 'week':
                        uploadDate.setDate(uploadDate.getDate() - (value * 7));
                        break;
                    case 'day':
                        uploadDate.setDate(uploadDate.getDate() - value);
                        break;
                    case 'hour':
                        uploadDate.setHours(uploadDate.getHours() - value);
                        break;
                    case 'minute':
                        uploadDate.setMinutes(uploadDate.getMinutes() - value);
                        break;
                }

                // Apply 1-year leniency for future date detection
                const maxDateWithLeniency = new Date(maxDate);
                maxDateWithLeniency.setFullYear(maxDateWithLeniency.getFullYear() + 1);

                if (uploadDate <= maxDate) {
                    // Video is within the time machine date - update normally
                    const newRelativeDate = OptimizedUtils.calculateRelativeDate(uploadDate, maxDate);

                    if (newRelativeDate && newRelativeDate !== originalText) {
                        element.textContent = newRelativeDate;
                        element.title = `Original: ${originalText} | Adjusted for ${OptimizedUtils.formatDate(maxDate)}`;
                    }
                } else if (uploadDate <= maxDateWithLeniency) {
                    // Video is within 1-year leniency - show random months from 6-11
                    const randomMonths = Math.floor(Math.random() * 6) + 6; // 6-11 months
                    element.textContent = `${randomMonths} month${randomMonths > 1 ? 's' : ''} ago`;
                    element.title = `Original: ${originalText} | Within grace period, showing random months`;
                    return;
                } else {
                    // Video is more than 1 year in the future - remove completely
                    const videoElement = element.closest('ytd-video-renderer, ytd-compact-video-renderer, ytd-grid-video-renderer');
                    if (videoElement) {
                        OptimizedUtils.log(`Removing future video from search: ${originalText} (uploaded after ${OptimizedUtils.formatDate(maxDateWithLeniency)})`);
                        videoElement.style.display = 'none';
                        videoElement.remove();
                    }
                }
            }
        }

        modifyCommentDates() {
            const currentPage = OptimizedUtils.getCurrentPage();
            if (currentPage !== 'watch') {
                // OptimizedUtils.log(`Not on watch page, current page: ${currentPage}`);
                return;
            }

            // Find all comment date elements with multiple selectors
            const commentSelectors = [
                'ytd-comment-view-model',
                'ytd-comment-replies-renderer', 
                'ytd-comment-thread-renderer',
                '#comments #contents',
                'ytd-comments',
                '#comment'
            ];

            let commentElements = [];
            commentSelectors.forEach(selector => {
                const elements = document.querySelectorAll(selector);
                commentElements = [...commentElements, ...Array.from(elements)];
            });

            // Also try to find comment date links directly with more selectors
            const allDateLinks = document.querySelectorAll(`
                a.yt-simple-endpoint[href*="lc="], 
                a[href*="lc="],
                .published-time-text,
                [aria-label*="ago"],
                #published-time-text,
                .style-scope.ytd-comment-view-model a
            `);

            // Debug elements found
            OptimizedUtils.log(`Found ${commentElements.length} comment containers and ${allDateLinks.length} date links`);

            // Process direct date links first
            allDateLinks.forEach(dateLink => {
                if (dateLink.dataset.tmCommentDateModified) return;

                const dateText = dateLink.textContent.trim();
                OptimizedUtils.log(`Processing comment date link: "${dateText}"`);

                // Check if this looks like a relative date
                if (this.isRelativeDateElement({ textContent: dateText })) {
                    this.updateCommentDate(dateLink, dateText);
                    dateLink.dataset.tmCommentDateModified = 'true';
                }
            });

            // Also process within comment containers
            commentElements.forEach(commentElement => {
                if (commentElement.dataset.tmCommentDateModified) return;

                // Look for comment date links - using broader selectors
                const dateLinks = commentElement.querySelectorAll('a[href*="lc="], .published-time-text, [class*="published"], [class*="time"]');

                dateLinks.forEach(dateLink => {
                    if (dateLink.dataset.tmCommentDateModified) return;

                    const dateText = dateLink.textContent.trim();

                    // Check if this looks like a relative date
                    if (this.isRelativeDateElement({ textContent: dateText })) {
                        OptimizedUtils.log(`Processing comment in container: "${dateText}"`);
                        this.updateCommentDate(dateLink, dateText);
                        dateLink.dataset.tmCommentDateModified = 'true';
                    }
                });

                commentElement.dataset.tmCommentDateModified = 'true';
            });
        }

        updateCommentDate(element, originalText) {
            const maxDate = this.maxDate;

            if (!maxDate) {
                OptimizedUtils.log('No maxDate available for comment processing');
                return;
            }

            OptimizedUtils.log(`Updating comment date: "${originalText}" with maxDate: ${OptimizedUtils.formatDate(maxDate)}`);

            // Parse the original relative date
            const match = originalText.match(/(\d+)\s+(year|month|week|day|hour|minute)s?\s+ago/i);

            if (match) {
                OptimizedUtils.log(`Matched comment date pattern: ${match[1]} ${match[2]}`);
                const value = parseInt(match[1]);
                const unit = match[2].toLowerCase();

                // Calculate original comment date from current time
                const now = new Date();
                let commentDate = new Date(now);

                // Use proper date arithmetic for accurate calculations
                switch (unit) {
                    case 'year':
                        commentDate.setFullYear(commentDate.getFullYear() - value);
                        break;
                    case 'month':
                        commentDate.setMonth(commentDate.getMonth() - value);
                        break;
                    case 'week':
                        commentDate.setDate(commentDate.getDate() - (value * 7));
                        break;
                    case 'day':
                        commentDate.setDate(commentDate.getDate() - value);
                        break;
                    case 'hour':
                        commentDate.setHours(commentDate.getHours() - value);
                        break;
                    case 'minute':
                        commentDate.setMinutes(commentDate.getMinutes() - value);
                        break;
                }

                // Apply 1-year leniency for future date detection
                const maxDateWithLeniency = new Date(maxDate);
                maxDateWithLeniency.setFullYear(maxDateWithLeniency.getFullYear() + 1);

                if (commentDate <= maxDate) {
                    // Comment is within time machine date - update normally
                    const newRelativeDate = OptimizedUtils.calculateRelativeDate(commentDate, maxDate);

                    if (newRelativeDate && newRelativeDate !== originalText) {
                        element.textContent = newRelativeDate;
                        element.title = `Original: ${originalText} | Adjusted for ${OptimizedUtils.formatDate(maxDate)}`;
                    }
                } else if (commentDate <= maxDateWithLeniency) {
                    // Comment is within 1-year leniency - show random months from 6-11
                    const randomMonths = Math.floor(Math.random() * 6) + 6; // 6-11 months
                    element.textContent = `${randomMonths} month${randomMonths > 1 ? 's' : ''} ago`;
                    element.title = `Original: ${originalText} | Within grace period, showing random months`;
                } else {
                    // Comment is more than 1 year in the future - remove completely
                    const commentContainer = element.closest('ytd-comment-view-model, ytd-comment-replies-renderer, ytd-comment-thread-renderer');
                    if (commentContainer) {
                        OptimizedUtils.log(`Removing future comment: ${originalText} (posted after ${OptimizedUtils.formatDate(maxDateWithLeniency)})`);
                        commentContainer.style.display = 'none';
                        commentContainer.remove();
                    }
                }
            }
        }

        injectSearchDateFilter() {
            if (location.pathname !== '/results') return;

            const urlParams = new URLSearchParams(location.search);
            let searchQuery = urlParams.get('search_query') || urlParams.get('q') || '';

            if (!searchQuery.includes('before:') && this.maxDate) {
                const beforeDate = this.maxDate.toISOString().split('T')[0];
                const newQuery = `${searchQuery} before:${beforeDate}`;

                urlParams.set('search_query', newQuery);
                const newUrl = `${location.pathname}?${urlParams.toString()}`;

                if (newUrl !== location.href) {
                    OptimizedUtils.log(`Injecting date filter: ${beforeDate}`);
                    window.history.replaceState({}, '', newUrl);
                }
            }
        }

        updateMaxDate(newMaxDate) {
            this.maxDate = newMaxDate;
        }
    }

    // === ENHANCED UI MANAGER ===
    class EnhancedUIManager {
        constructor(timeMachine) {
            this.timeMachine = timeMachine;
            this.isVisible = GM_getValue('ytTimeMachineUIVisible', true);
            this.init();
        }

        init() {
            // Wait for DOM to be ready before creating UI
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', () => {
                    this.createUI();
                    this.setupKeyboardShortcuts();
                });
            } else {
                this.createUI();
                this.setupKeyboardShortcuts();
            }
        }

        createUI() {
            GM_addStyle(`
                .yt-time-machine-ui {
                    position: fixed;
                    top: 10px;
                    right: 10px;
                    width: 320px;
                    max-height: 80vh;
                    background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
                    border: 1px solid #444;
                    border-radius: 12px;
                    padding: 16px;
                    font-family: 'Roboto', sans-serif;
                    font-size: 13px;
                    color: #fff;
                    z-index: 10000;
                    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
                    backdrop-filter: blur(10px);
                    transition: opacity 0.3s ease;
                    overflow-y: auto;
                    overflow-x: hidden;
                }

                .yt-time-machine-ui::-webkit-scrollbar {
                    width: 8px;
                }

                .yt-time-machine-ui::-webkit-scrollbar-track {
                    background: rgba(255, 255, 255, 0.1);
                    border-radius: 4px;
                }

                .yt-time-machine-ui::-webkit-scrollbar-thumb {
                    background: rgba(255, 255, 255, 0.3);
                    border-radius: 4px;
                }

                .yt-time-machine-ui::-webkit-scrollbar-thumb:hover {
                    background: rgba(255, 255, 255, 0.5);
                }

                .yt-time-machine-ui.hidden {
                    opacity: 0;
                    pointer-events: none;
                }

                .yt-time-machine-toggle {
                    position: fixed;
                    top: 10px;
                    right: 10px;
                    width: 40px;
                    height: 40px;
                    background: #c41e3a;
                    border: none;
                    border-radius: 50%;
                    color: white;
                    font-size: 16px;
                    cursor: pointer;
                    z-index: 10001;
                    display: none;
                    align-items: center;
                    justify-content: center;
                    box-shadow: 0 4px 16px rgba(196, 30, 58, 0.4);
                }

                .yt-time-machine-toggle.visible {
                    display: flex;
                }

                .tm-title {
                    font-size: 16px;
                    font-weight: bold;
                    margin-bottom: 12px;
                    color: #ff6b6b;
                    text-align: center;
                    position: relative;
                }

                .tm-minimize-btn {
                    position: absolute;
                    right: 0;
                    top: -2px;
                    background: #666;
                    color: white;
                    border: none;
                    width: 20px;
                    height: 20px;
                    border-radius: 50%;
                    cursor: pointer;
                    font-size: 12px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }

                .tm-minimize-btn:hover {
                    background: #888;
                }

                .tm-input {
                    width: 100%;
                    padding: 8px 10px;
                    margin: 4px 0;
                    border: 1px solid #555;
                    border-radius: 6px;
                    background: #333;
                    color: #fff;
                    font-size: 12px;
                }

                .tm-button {
                    padding: 8px 12px;
                    margin: 4px 2px;
                    border: none;
                    border-radius: 6px;
                    background: #4a90e2;
                    color: white;
                    cursor: pointer;
                    font-size: 11px;
                    transition: background 0.2s ease;
                }

                .tm-button:hover {
                    background: #357abd;
                }

                .tm-button:disabled {
                    background: #666;
                    cursor: not-allowed;
                }

                .tm-button.tm-danger {
                    background: #dc3545;
                }

                .tm-button.tm-danger:hover {
                    background: #c82333;
                }

                .tm-section {
                    margin: 12px 0;
                    padding: 10px;
                    background: rgba(255, 255, 255, 0.05);
                    border-radius: 8px;
                }

                .tm-section h3 {
                    margin: 0 0 8px 0;
                    font-size: 12px;
                    color: #4a90e2;
                }

                .tm-stats {
                    display: grid;
                    grid-template-columns: 1fr 1fr;
                    gap: 8px;
                    font-size: 11px;
                }

                .tm-stat {
                    background: rgba(0, 0, 0, 0.3);
                    padding: 6px;
                    border-radius: 4px;
                    text-align: center;
                }

                .tm-subscription-item {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    padding: 4px 0;
                    border-bottom: 1px solid #444;
                }

                .tm-subscription-item:last-child {
                    border-bottom: none;
                }

                .tm-subscription-name {
                    flex: 1;
                    font-size: 11px;
                }

                .tm-remove-btn {
                    background: #e74c3c;
                    color: white;
                    border: none;
                    border-radius: 3px;
                    padding: 2px 6px;
                    font-size: 10px;
                    cursor: pointer;
                }

                .tm-loading {
                    text-align: center;
                    padding: 20px;
                    color: #4a90e2;
                }

                /* Homepage Video Cards */
                .tm-homepage-grid {
                    display: grid;
                    grid-template-columns: repeat(4, 1fr);
                    gap: 16px;
                    padding: 16px;
                }

                .tm-video-card {
                    background: #0f0f0f;
                    border-radius: 12px;
                    overflow: hidden;
                    cursor: pointer;
                    transition: transform 0.2s ease, box-shadow 0.2s ease;
                }

                .tm-video-card:hover {
                    transform: translateY(-2px);
                    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
                }

                .tm-video-card img {
                    width: 100%;
                    height: 135px;
                    object-fit: cover;
                    border-radius: 0;
                }

                .tm-video-info {
                    padding: 12px;
                }

                .tm-video-title {
                    font-size: 14px;
                    font-weight: 500;
                    color: #fff;
                    line-height: 1.3;
                    margin-bottom: 8px;
                    display: -webkit-box;
                    -webkit-line-clamp: 2;
                    -webkit-box-orient: vertical;
                    overflow: hidden;
                }

                .tm-video-channel {
                    font-size: 12px;
                    color: #aaa;
                    margin-bottom: 4px;
                }

                .tm-video-meta {
                    font-size: 12px;
                    color: #aaa;
                }

                .tm-video-meta span {
                    margin-right: 8px;
                }

                /* Vintage theme toggle button */
                .tm-vintage-toggle {
                    background: linear-gradient(135deg, #8b4513, #a0522d) !important;
                    color: white !important;
                }
                
                .tm-vintage-toggle:hover {
                    background: linear-gradient(135deg, #a0522d, #d2b48c) !important;
                    color: #333 !important;
                }
                
                .tm-vintage-toggle.active {
                    background: linear-gradient(135deg, #228b22, #32cd32) !important;
                    color: white !important;
                }
                
                .tm-vintage-toggle.active:hover {
                    background: linear-gradient(135deg, #32cd32, #90ee90) !important;
                    color: #333 !important;
                }

                /* Watch Next Cards - Enhanced and bigger */
                .tm-watch-next {
                    background: #0f0f0f;
                    padding: 16px;
                    margin-bottom: 16px;
                    position: relative;
                    z-index: 999999 !important;
                    min-height: 400px;
                }

                .tm-watch-next h3 {
                    color: #fff;
                    font-size: 16px;
                    margin: 0 0 16px 0;
                    font-weight: normal;
                }

                .tm-watch-next-grid {
                    display: flex;
                    flex-direction: column;
                    gap: 0;
                }

                .tm-watch-next-card {
                    display: flex;
                    cursor: pointer;
                    padding: 12px 0;
                    border-bottom: 1px solid #333;
                }

                .tm-watch-next-card:hover {
                    background: #1a1a1a;
                }

                .tm-watch-next-card img {
                    width: 140px;
                    height: 78px;
                    object-fit: cover;
                    margin-right: 12px;
                }

                .tm-watch-next-info {
                    flex: 1;
                }

                .tm-watch-next-title {
                    font-size: 13px;
                    color: #fff;
                    line-height: 1.3;
                    margin-bottom: 4px;
                    display: -webkit-box;
                    -webkit-line-clamp: 2;
                    -webkit-box-orient: vertical;
                    overflow: hidden;
                }

                .tm-watch-next-channel {
                    font-size: 12px;
                    color: #999;
                    margin-bottom: 3px;
                }

                .tm-watch-next-meta {
                    font-size: 11px;
                    color: #666;
                }
            `);

            const uiHTML = `
                <div id="timeMachineUI" class="yt-time-machine-ui ${this.isVisible ? '' : 'hidden'}">
                    <div class="tm-title">
                        ⏰ WayBackTube
                        <button class="tm-minimize-btn" id="tmMinimizeBtn">×</button>
                    </div>

                    <div class="tm-section">
                        <label>Travel to date:</label>
                        <input type="date" id="tmDateInput" class="tm-input" value="${this.timeMachine.getDateString()}">
                        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px;">
                            <button id="tmApplyDate" class="tm-button">Apply Date</button>
                            <button id="tmRandomDate" class="tm-button">Random Date</button>
                        </div>
                    </div>

                    <div class="tm-section">
                        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px;">
                            <button id="tmToggle" class="tm-button">${this.timeMachine.settings.active ? 'Disable' : 'Enable'}</button>
                            <button id="tmClearCache" class="tm-button">Clear Cache</button>
                        </div>
                        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px;">
                            <button id="tmRefreshVideosBtn" class="tm-button">Refresh Videos</button>
                            <button id="tmVintageToggle" class="tm-button tm-vintage-toggle">🕰️ 2011 Theme</button>
                        </div>
                        <div style="margin-top: 8px;">
                            <label style="display: flex; align-items: center; color: #fff; font-size: 12px;">
                                <input type="checkbox" id="tmDateRotation" style="margin-right: 6px;">
                                Auto-advance date daily (simulates real uploads)
                            </label>
                        </div>
                        <div style="margin-top: 8px;">
                            <label style="display: flex; align-items: center; color: #fff; font-size: 12px;">
                                <input type="checkbox" id="tmTestClock" style="margin-right: 6px;">
                                Real-time Clock (new videos every 4h, date advances daily)
                            </label>
                        </div>
                    </div>

                    <div class="tm-section">
                        <h3>Search Terms</h3>
                        <input type="text" id="tmSearchTermInput" class="tm-input" placeholder="Enter search term (e.g. memes, gaming)">
                        <button id="tmAddSearchTerm" class="tm-button" style="width: 100%; margin-top: 4px;">Add Search Term</button>
                        <div id="tmSearchTermList"></div>
                        <button id="tmClearSearchTerms" class="tm-button" style="width: 100%; margin-top: 8px; background: #dc3545;">Clear All Search Terms</button>
                    </div>

                    <div class="tm-section">
                        <h3>Real-Time Clock</h3>
                        <div style="text-align: center; padding: 12px; background: rgba(0,0,0,0.3); border-radius: 6px; margin-bottom: 12px;">
                            <div style="font-family: monospace; font-size: 18px; color: #00ff00; font-weight: bold;" id="tm-clock-display">
                                ${GM_getValue('ytTestClockEnabled', false) ? 'Day 0, 00:00:00' : 'Clock not running'}
                            </div>
                            <div style="font-size: 11px; color: #888; margin-top: 4px;">
                                New videos every 4 hours • Date advances every 24 hours
                            </div>
                        </div>
                    </div>

                    <div class="tm-section">
                        <h3>Statistics</h3>
                        <div class="tm-stats">
                            <div class="tm-stat">
                                <div>API Calls</div>
                                <div id="tmApiCalls">0</div>
                            </div>
                            <div class="tm-stat">
                                <div>Videos Processed</div>
                                <div id="tmVideosProcessed">0</div>
                            </div>
                            <div class="tm-stat">
                                <div>Cache Hits</div>
                                <div id="tmCacheHits">0</div>
                            </div>
                            <div class="tm-stat">
                                <div>Videos Filtered</div>
                                <div id="tmVideosFiltered">0</div>
                            </div>
                        </div>
                    </div>

                    <div class="tm-section">
                        <h3>API Keys</h3>
                        <input type="text" id="tmApiKeyInput" class="tm-input" placeholder="Enter YouTube API key">
                        <div style="display: flex; gap: 4px; margin-top: 4px;">
                            <button id="tmAddApiKey" class="tm-button" style="flex: 1;">Add Key</button>
                            <button id="tmTestAllKeys" class="tm-button" style="flex: 1;">Test All</button>
                        </div>
                        <div id="tmApiKeyList"></div>
                    </div>



                    <div class="tm-section">
                        <h3>Subscriptions</h3>
                        <input type="text" id="tmSubscriptionInput" class="tm-input" placeholder="Enter channel name">
                        <button id="tmAddSubscription" class="tm-button" style="width: 100%; margin-top: 4px;">Add Channel</button>
                        <div id="tmSubscriptionList"></div>
                    </div>

                    <div style="font-size: 10px; color: #666; text-align: center; margin-top: 15px;">
                        Press Ctrl+Shift+T to toggle UI
                    </div>
                </div>

                <button id="timeMachineToggle" class="yt-time-machine-toggle ${this.isVisible ? '' : 'visible'}">⏰</button>
            `;

            // Safely insert UI with error handling
            this.safeInsertUI(uiHTML);
        }

        safeInsertUI(uiHTML) {
            const insertUI = () => {
                try {
                    if (!document.body) {
                        // Body not ready yet, wait a bit
                        setTimeout(insertUI, 100);
                        return;
                    }
                    
                    // Remove any existing UI first
                    const existingUI = document.querySelector('.yt-time-machine-ui');
                    const existingToggle = document.querySelector('.yt-time-machine-toggle');
                    if (existingUI) existingUI.remove();
                    if (existingToggle) existingToggle.remove();
                    
                    // Create elements using safe DOM construction
                    this.createUIElements();
                    
                    this.attachEventListeners();
                    this.initializeVintageTheme();
                    this.updateUI();
                    OptimizedUtils.log('UI successfully created');
                } catch (error) {
                    OptimizedUtils.log('UI creation error:', error);
                    // Try again after a delay
                    setTimeout(insertUI, 500);
                }
            };
            
            insertUI();
        }

        createUIElements() {
            // Create main UI container
            const uiContainer = document.createElement('div');
            uiContainer.className = `yt-time-machine-ui ${this.isVisible ? '' : 'hidden'}`;
            uiContainer.id = 'timeMachineUI';
            
            // Create title section
            const titleDiv = document.createElement('div');
            titleDiv.className = 'tm-title';
            titleDiv.textContent = '⏰ WayBackTube';
            
            const minimizeBtn = document.createElement('button');
            minimizeBtn.className = 'tm-minimize-btn';
            minimizeBtn.id = 'tmMinimizeBtn';
            minimizeBtn.textContent = '×';
            titleDiv.appendChild(minimizeBtn);
            
            uiContainer.appendChild(titleDiv);
            
            // Create date section
            const dateSection = document.createElement('div');
            dateSection.className = 'tm-section';
            
            const dateLabel = document.createElement('label');
            dateLabel.textContent = 'Travel to date:';
            dateSection.appendChild(dateLabel);
            
            const dateInput = document.createElement('input');
            dateInput.type = 'date';
            dateInput.id = 'tmDateInput';
            dateInput.className = 'tm-input';
            dateSection.appendChild(dateInput);
            
            const buttonContainer = document.createElement('div');
            buttonContainer.style.cssText = 'display: flex; gap: 4px; margin-top: 4px;';
            
            const applyBtn = document.createElement('button');
            applyBtn.id = 'tmApplyDate';
            applyBtn.className = 'tm-button';
            applyBtn.style.flex = '1';
            applyBtn.textContent = 'Apply';
            
            const randomBtn = document.createElement('button');
            randomBtn.id = 'tmRandomDate';
            randomBtn.className = 'tm-button';
            randomBtn.style.flex = '1';
            randomBtn.textContent = 'Random';
            
            buttonContainer.appendChild(applyBtn);
            buttonContainer.appendChild(randomBtn);
            dateSection.appendChild(buttonContainer);
            
            uiContainer.appendChild(dateSection);
            
            // Create control section
            const controlSection = document.createElement('div');
            controlSection.className = 'tm-section';
            
            const controlGrid = document.createElement('div');
            controlGrid.style.cssText = 'display: grid; grid-template-columns: 1fr 1fr; gap: 8px;';
            
            const toggleBtn = document.createElement('button');
            toggleBtn.id = 'tmToggle';
            toggleBtn.className = 'tm-button primary';
            toggleBtn.textContent = 'Activate';
            
            const vintageBtn = document.createElement('button');
            vintageBtn.id = 'tmVintageToggle';
            vintageBtn.className = 'tm-button';
            vintageBtn.textContent = '2011 Theme';
            
            controlGrid.appendChild(toggleBtn);
            controlGrid.appendChild(vintageBtn);
            controlSection.appendChild(controlGrid);
            
            uiContainer.appendChild(controlSection);
            
            // Add all other sections similarly...
            // For brevity, I'll add the remaining sections with innerHTML since they're complex
            const restOfUI = document.createElement('div');
            restOfUI.innerHTML = `
                <div class="tm-section">
                    <h3>API Keys</h3>
                    <input type="text" id="tmApiKeyInput" class="tm-input" placeholder="Enter YouTube API key">
                    <div style="display: flex; gap: 4px; margin-top: 4px;">
                        <button id="tmAddApiKey" class="tm-button" style="flex: 1;">Add Key</button>
                        <button id="tmTestAllKeys" class="tm-button" style="flex: 1;">Test All</button>
                    </div>
                    <div id="tmApiKeyList"></div>
                </div>

                <div class="tm-section">
                    <h3>Subscriptions</h3>
                    <input type="text" id="tmSubscriptionInput" class="tm-input" placeholder="Enter channel name">
                    <button id="tmAddSubscription" class="tm-button" style="width: 100%; margin-top: 4px;">Add Channel</button>
                    <div id="tmSubscriptionList"></div>
                </div>

                <div style="font-size: 10px; color: #666; text-align: center; margin-top: 15px;">
                    Press Ctrl+Shift+T to toggle UI
                </div>
            `;
            
            uiContainer.appendChild(restOfUI);
            
            // Create toggle button
            const toggleButton = document.createElement('button');
            toggleButton.id = 'timeMachineToggle';
            toggleButton.className = `yt-time-machine-toggle ${this.isVisible ? '' : 'visible'}`;
            toggleButton.textContent = '⏰';
            
            // Append to body
            document.body.appendChild(uiContainer);
            document.body.appendChild(toggleButton);
        }

        attachEventListeners() {
            // Toggle button
            document.getElementById('timeMachineToggle')?.addEventListener('click', () => {
                this.toggleUI();
            });

            // Minimize button
            document.getElementById('tmMinimizeBtn')?.addEventListener('click', () => {
                this.toggleUI();
            });

            // Date controls
            document.getElementById('tmApplyDate')?.addEventListener('click', () => {
                const dateInput = document.getElementById('tmDateInput');
                if (dateInput.value) {
                    this.timeMachine.setDate(dateInput.value);
                    this.updateUI();
                }
            });

            document.getElementById('tmRandomDate')?.addEventListener('click', () => {
                this.timeMachine.setRandomDate();
                this.updateUI();
            });

            // Main controls
            document.getElementById('tmToggle')?.addEventListener('click', () => {
                this.timeMachine.toggle();
                this.updateUI();
            });

            document.getElementById('tmClearCache')?.addEventListener('click', () => {
                this.timeMachine.apiManager.clearCache();
                this.timeMachine.videoCache.clear(); // Also clear persistent video cache
                this.updateUI();
            });

            // Vintage theme toggle
            document.getElementById('tmVintageToggle')?.addEventListener('click', () => {
                this.handleVintageToggle();
            });

            // Refresh button
            const refreshBtn = document.getElementById('tmRefreshVideosBtn');
            if (refreshBtn) {
                refreshBtn.addEventListener('click', () => {
                    refreshBtn.disabled = true;
                    refreshBtn.textContent = 'Refreshing...';

                    this.timeMachine.loadAllVideos(true).then(() => {
                        const container = document.querySelector('ytd-browse[page-subtype="home"] ytd-rich-grid-renderer');
                        if (container) {
                            this.timeMachine.replaceHomepage(container, true);
                        }
                        refreshBtn.textContent = 'Refreshed!';
                    }).catch(error => {
                        refreshBtn.textContent = 'Refresh Failed';
                        OptimizedUtils.log('Manual refresh failed:', error);
                    }).finally(() => {
                        setTimeout(() => {
                            refreshBtn.disabled = false;
                            refreshBtn.textContent = 'Refresh Videos';
                        }, 2000);
                    });
                });
            }

            // API key management
            document.getElementById('tmAddApiKey')?.addEventListener('click', () => {
                const input = document.getElementById('tmApiKeyInput');
                if (input.value.trim()) {
                    this.timeMachine.apiManager.addKey(input.value.trim());
                    input.value = '';
                    this.updateUI();
                }
            });

            document.getElementById('tmTestAllKeys')?.addEventListener('click', async () => {
                const testBtn = document.getElementById('tmTestAllKeys');
                testBtn.disabled = true;
                testBtn.textContent = 'Testing...';

                try {
                    const result = await this.timeMachine.apiManager.testAllKeys();
                    this.showStatusMessage(result.message, result.success ? 'success' : 'error');
                    this.updateUI(); // Refresh to show updated key statuses
                } catch (error) {
                    this.showStatusMessage('Error testing keys: ' + error.message, 'error');
                }

                testBtn.disabled = false;
                testBtn.textContent = 'Test All';
            });

            // Proxy management
            document.getElementById('tmProxyEnabled')?.addEventListener('change', (e) => {
                this.timeMachine.apiManager.enableProxies(e.target.checked);
                this.updateUI();
            });



            // Date rotation toggle
            document.getElementById('tmDateRotation')?.addEventListener('change', (e) => {
                this.timeMachine.enableDateRotation(e.target.checked);
                this.updateUI();
            });

            document.getElementById('tmTestClock')?.addEventListener('change', (e) => {
                this.timeMachine.toggleTestClock(e.target.checked);
                this.updateUI();
            });

            // Subscription management
            document.getElementById('tmAddSubscription')?.addEventListener('click', () => {
                const input = document.getElementById('tmSubscriptionInput');
                if (input.value.trim()) {
                    this.timeMachine.subscriptionManager.addSubscription(input.value.trim());
                    input.value = '';
                    this.updateUI();
                }
            });

            // Search Terms management
            document.getElementById('tmAddSearchTerm')?.addEventListener('click', () => {
                const input = document.getElementById('tmSearchTermInput');
                if (input.value.trim()) {
                    this.addSearchTerm(input.value.trim());
                    input.value = '';
                    this.updateSearchTermsList();
                }
            });

            document.getElementById('tmSearchTermInput')?.addEventListener('keypress', (e) => {
                if (e.key === 'Enter') {
                    const input = document.getElementById('tmSearchTermInput');
                    if (input.value.trim()) {
                        this.addSearchTerm(input.value.trim());
                        input.value = '';
                        this.updateSearchTermsList();
                    }
                }
            });

            document.getElementById('tmClearSearchTerms')?.addEventListener('click', () => {
                this.clearAllSearchTerms();
                this.updateSearchTermsList();
            });

            // Keyboard shortcuts
            document.addEventListener('keydown', (e) => {
                if (e.ctrlKey && e.shiftKey && e.key === 'T') {
                    e.preventDefault();
                    this.toggleUI();
                }
            });
        }

        setupKeyboardShortcuts() {
            document.addEventListener('keydown', (e) => {
                if (e.ctrlKey && e.shiftKey && e.key === 'T') {
                    e.preventDefault();
                    this.toggleUI();
                }
            });
        }

        toggleUI() {
            this.isVisible = !this.isVisible;
            GM_setValue('ytTimeMachineUIVisible', this.isVisible);

            const ui = document.getElementById('timeMachineUI');
            const toggle = document.getElementById('timeMachineToggle');

            if (this.isVisible) {
                ui?.classList.remove('hidden');
                toggle?.classList.remove('visible');
            } else {
                ui?.classList.add('hidden');
                toggle?.classList.add('visible');
            }
        }

        updateUI() {
            // Update date input
            const dateInput = document.getElementById('tmDateInput');
            if (dateInput) {
                dateInput.value = this.timeMachine.getDateString();
            }

            // Update toggle button
            const toggleBtn = document.getElementById('tmToggle');
            if (toggleBtn) {
                toggleBtn.textContent = this.timeMachine.settings.active ? 'Disable' : 'Enable';
            }

            // Update statistics
            this.updateStatistics();

            // Update API keys list
            this.updateApiKeysList();

            // Update subscriptions list
            this.updateSubscriptionsList();

            // Update search terms list
            this.updateSearchTermsList();

            // Update date rotation checkbox
            const dateRotationCheckbox = document.getElementById('tmDateRotation');
            if (dateRotationCheckbox) {
                dateRotationCheckbox.checked = this.timeMachine.settings.dateRotationEnabled;
            }

            const testClockCheckbox = document.getElementById('tmTestClock');
            if (testClockCheckbox) {
                testClockCheckbox.checked = GM_getValue('wayback_persistent_clock_enabled', false);
            }
        }

        showStatusMessage(message, type = 'info') {
            // Create a temporary message overlay
            const messageDiv = document.createElement('div');
            messageDiv.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                padding: 12px 16px;
                border-radius: 6px;
                color: white;
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                font-size: 14px;
                z-index: 999999;
                max-width: 300px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            `;

            const colors = {
                success: '#4CAF50',
                error: '#f44336',
                warning: '#ff9800',
                info: '#2196F3'
            };

            messageDiv.style.backgroundColor = colors[type] || colors.info;
            messageDiv.textContent = message;

            document.body.appendChild(messageDiv);

            // Auto-remove after 3 seconds
            setTimeout(() => {
                if (messageDiv.parentNode) {
                    messageDiv.remove();
                }
            }, 3000);

            console.log(`[WayBackTube] ${type.toUpperCase()}: ${message}`);
        }





        updateStatistics() {
            const stats = this.timeMachine.getStats();

            document.getElementById('tmApiCalls').textContent = stats.apiCalls;
            document.getElementById('tmVideosProcessed').textContent = stats.processed;
            document.getElementById('tmCacheHits').textContent = stats.cacheHits;
            document.getElementById('tmVideosFiltered').textContent = stats.filtered;
        }

        updateApiKeysList() {
            const container = document.getElementById('tmApiKeyList');
            if (!container) return;

            const keys = this.timeMachine.apiManager.keys;
            const currentKeyIndex = this.timeMachine.apiManager.currentKeyIndex;
            const keyStats = this.timeMachine.apiManager.keyStats;

            if (keys.length === 0) {
                container.innerHTML = '<div style="color: #666; font-size: 11px; text-align: center; padding: 8px;">No API keys added</div>';
                return;
            }

            container.innerHTML = keys.map((key, index) => {
                const isActive = index === currentKeyIndex;
                const stats = keyStats[key] || {};

                let status = 'Unknown';
                let statusIcon = '❓';
                let statusColor = '#666';

                if (stats.quotaExceeded) {
                    status = 'Quota Exceeded';
                    statusIcon = '🚫';
                    statusColor = '#ff4444';
                } else if (stats.failed) {
                    status = 'Failed';
                    statusIcon = '❌';
                    statusColor = '#ff6666';
                } else if (isActive) {
                    status = 'Active';
                    statusIcon = '✅';
                    statusColor = '#4CAF50';
                } else if (stats.successCount > 0) {
                    status = 'Standby';
                    statusIcon = '⏸️';
                    statusColor = '#ff9800';
                } else {
                    status = 'Untested';
                    statusIcon = '⚪';
                    statusColor = '#999';
                }

                return `
                    <div class="tm-api-key-item" data-key="${key}" style="margin-bottom: 8px; padding: 8px; background: #2a2a2a; border-radius: 4px;">
                        <div style="display: flex; justify-content: space-between; align-items: center;">
                            <div style="flex: 1; min-width: 0;">
                                <div style="font-size: 11px; color: #fff; margin-bottom: 4px;">
                                    ${statusIcon} ${key.substring(0, 8)}...${key.substring(key.length - 4)}
                                </div>
                                <div style="display: flex; gap: 12px; font-size: 10px; color: #999;">
                                    <span style="color: ${statusColor};">${status}</span>
                                    <span>${stats.requestCount || 0} requests</span>
                                    <span>${stats.successCount || 0} successful</span>
                                </div>
                            </div>
                            <button class="tm-remove-key" data-key="${key}" style="
                                background: #ff4444;
                                border: none;
                                color: white;
                                padding: 4px 8px;
                                border-radius: 3px;
                                font-size: 10px;
                                cursor: pointer;
                                margin-left: 8px;
                            ">Remove</button>
                        </div>
                    </div>
                `;
            }).join('');

            // Add event listeners for remove buttons
            container.querySelectorAll('.tm-remove-key').forEach(btn => {
                btn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    const key = btn.dataset.key;
                    this.timeMachine.apiManager.removeKey(key);
                    this.updateUI();
                });
            });
        }

        updateSubscriptionsList() {
            const container = document.getElementById('tmSubscriptionList');
            if (!container) return;

            const subscriptions = this.timeMachine.subscriptionManager.getSubscriptions();

            if (subscriptions.length === 0) {
                container.innerHTML = '<div style="padding: 8px; text-align: center; color: #666;">No subscriptions added</div>';
                return;
            }

            container.innerHTML = subscriptions.map((sub, index) => `
                <div class="tm-subscription-item">
                    <span class="tm-subscription-name">${sub.name}</span>
                    <button class="tm-remove-btn" data-remove-subscription="${index}">Remove</button>
                </div>
            `).join('');

            // Add event listeners for remove buttons
            container.querySelectorAll('[data-remove-subscription]').forEach(btn => {
                btn.addEventListener('click', (e) => {
                    const index = parseInt(e.target.getAttribute('data-remove-subscription'));
                    this.timeMachine.removeSubscription(index);
                });
            });
        }

        // Search Terms Management Methods
        loadSearchTerms() {
            try {
                const searchTerms = JSON.parse(GM_getValue('ytSearchTerms', '[]'));
                return searchTerms.length > 0 ? searchTerms : this.getDefaultSearchTerms();
            } catch (error) {
                return this.getDefaultSearchTerms();
            }
        }

        saveSearchTerms(searchTerms) {
            GM_setValue('ytSearchTerms', JSON.stringify(searchTerms));
        }

        getDefaultSearchTerms() {
            return ['memes', 'gaming', 'funny', 'music', 'tutorial'];
        }

        addSearchTerm(term) {
            const searchTerms = this.loadSearchTerms();
            if (!searchTerms.includes(term.toLowerCase())) {
                searchTerms.push(term.toLowerCase());
                this.saveSearchTerms(searchTerms);
            }
        }

        removeSearchTerm(index) {
            const searchTerms = this.loadSearchTerms();
            searchTerms.splice(index, 1);
            this.saveSearchTerms(searchTerms);
        }

        clearAllSearchTerms() {
            this.saveSearchTerms([]);
        }

        getSearchTerms() {
            return this.loadSearchTerms();
        }

        updateSearchTermsList() {
            const container = document.getElementById('tmSearchTermList');
            if (!container) return;

            const searchTerms = this.loadSearchTerms();

            if (searchTerms.length === 0) {
                container.innerHTML = '<div style="padding: 8px; text-align: center; color: #666;">No search terms added</div>';
                return;
            }

            container.innerHTML = searchTerms.map((term, index) => `
                <div class="tm-subscription-item">
                    <span class="tm-subscription-name">${term}</span>
                    <button class="tm-remove-btn" data-remove-search-term="${index}">Remove</button>
                </div>
            `).join('');

            // Add event listeners for remove buttons
            container.querySelectorAll('[data-remove-search-term]').forEach(btn => {
                btn.addEventListener('click', (e) => {
                    const index = parseInt(e.target.getAttribute('data-remove-search-term'));
                    this.removeSearchTerm(index);
                    this.updateSearchTermsList();
                });
            });
        }

        handleVintageToggle() {
            const currentState = GM_getValue('ytVintage2011Theme', false);
            const newState = !currentState;
            
            // Save the new state
            GM_setValue('ytVintage2011Theme', newState);
            
            // Force CSS re-injection if enabling theme
            if (newState && !document.querySelector('style[data-wayback-vintage]')) {
                OptimizedUtils.log('Re-injecting vintage CSS...');
                this.injectVintageCSS();
            }
            
            // Update the DOM
            if (newState) {
                document.body.classList.add('wayback-2011-theme');
                OptimizedUtils.log('Added wayback-2011-theme class to body');
            } else {
                document.body.classList.remove('wayback-2011-theme');
                OptimizedUtils.log('Removed wayback-2011-theme class from body');
            }
            
            // Update ALL possible buttons (both UI systems)
            const buttons = [
                document.getElementById('tmVintageToggle'),
                document.getElementById('wayback-vintage-toggle')
            ];
            
            buttons.forEach(button => {
                if (button) {
                    button.textContent = newState ? '🕰️ Modern Theme' : '🕰️ 2011 Theme';
                    button.classList.toggle('active', newState);
                    OptimizedUtils.log(`Button updated: ${button.textContent}`);
                }
            });
            
            // Debug: Check if class is actually on body
            OptimizedUtils.log(`Body classes: ${document.body.className}`);
            OptimizedUtils.log(`2011 Vintage Theme ${newState ? 'enabled' : 'disabled'}`);
        }

        injectVintageCSS() {
            // Make sure vintage CSS is injected
            const vintage2011CSS = `
                /* Simple 2011 Theme - NO BLUE TEXT (user request) */
                body.wayback-2011-theme {
                    /* Remove blue text styling completely */
                }

                /* Remove ALL rounded corners - make everything square */
                body.wayback-2011-theme *,
                body.wayback-2011-theme *:before,
                body.wayback-2011-theme *:after {
                    border-radius: 0 !important;
                    -webkit-border-radius: 0 !important;
                    -moz-border-radius: 0 !important;
                }

                /* FIXED: Square thumbnails with normal sizing */
                body.wayback-2011-theme ytd-thumbnail img,
                body.wayback-2011-theme .ytd-thumbnail img {
                    border-radius: 0 !important;
                    object-fit: cover !important; /* Use cover for normal thumbnail behavior */
                }

                /* Fix thumbnail containers */
                body.wayback-2011-theme ytd-thumbnail,
                body.wayback-2011-theme .ytd-thumbnail,
                body.wayback-2011-theme #thumbnail {
                    border-radius: 0 !important;
                }

                /* Don't break all images - only target thumbnails specifically */
                body.wayback-2011-theme ytd-video-renderer ytd-thumbnail img,
                body.wayback-2011-theme ytd-rich-item-renderer ytd-thumbnail img,
                body.wayback-2011-theme ytd-grid-video-renderer ytd-thumbnail img {
                    border-radius: 0 !important;
                    object-fit: cover !important;
                }

                /* Fix channel profile pictures - keep normal size */
                body.wayback-2011-theme yt-img-shadow img,
                body.wayback-2011-theme ytd-channel-avatar img,
                body.wayback-2011-theme #avatar img,
                body.wayback-2011-theme .ytd-channel-avatar img {
                    border-radius: 0 !important;
                    max-width: 36px !important;
                    max-height: 36px !important;
                    width: 36px !important;
                    height: 36px !important;
                }

                /* Square buttons */
                body.wayback-2011-theme button,
                body.wayback-2011-theme .yt-spec-button-shape-next,
                body.wayback-2011-theme .yt-spec-button-shape-next__button {
                    border-radius: 0 !important;
                }

                /* Square search box */
                body.wayback-2011-theme input,
                body.wayback-2011-theme #search-form,
                body.wayback-2011-theme ytd-searchbox,
                body.wayback-2011-theme #search-form input {
                    border-radius: 0 !important;
                }

                /* Square video containers */
                body.wayback-2011-theme ytd-video-renderer,
                body.wayback-2011-theme ytd-grid-video-renderer,
                body.wayback-2011-theme ytd-rich-item-renderer {
                    border-radius: 0 !important;
                }

                /* FIXED: Remove ALL hover elevation effects and animations */
                body.wayback-2011-theme *,
                body.wayback-2011-theme *:before,
                body.wayback-2011-theme *:after,
                body.wayback-2011-theme *:hover,
                body.wayback-2011-theme *:hover:before,
                body.wayback-2011-theme *:hover:after {
                    transition: none !important;
                    animation: none !important;
                    transform: none !important;
                    box-shadow: none !important;
                    -webkit-transition: none !important;
                    -webkit-animation: none !important;
                    -webkit-transform: none !important;
                    -webkit-box-shadow: none !important;
                    -moz-transition: none !important;
                    -moz-animation: none !important;
                    -moz-transform: none !important;
                    -moz-box-shadow: none !important;
                }

                /* Specifically disable hover effects on video containers */
                body.wayback-2011-theme ytd-video-renderer:hover,
                body.wayback-2011-theme ytd-rich-item-renderer:hover,
                body.wayback-2011-theme ytd-grid-video-renderer:hover,
                body.wayback-2011-theme .ytd-video-renderer:hover,
                body.wayback-2011-theme .ytd-rich-item-renderer:hover,
                body.wayback-2011-theme .ytd-grid-video-renderer:hover {
                    transform: none !important;
                    box-shadow: none !important;
                    transition: none !important;
                    animation: none !important;
                    -webkit-transform: none !important;
                    -webkit-box-shadow: none !important;
                    -webkit-transition: none !important;
                    -webkit-animation: none !important;
                }

                /* Disable thumbnail hover scaling/animations */
                body.wayback-2011-theme ytd-thumbnail:hover img,
                body.wayback-2011-theme .ytd-thumbnail:hover img,
                body.wayback-2011-theme #thumbnail:hover img {
                    transform: none !important;
                    transition: none !important;
                    animation: none !important;
                    -webkit-transform: none !important;
                    -webkit-transition: none !important;
                    -webkit-animation: none !important;
                }

                /* Fix oversized watch next section */
                body.wayback-2011-theme #secondary #secondary-inner,
                body.wayback-2011-theme ytd-watch-next-secondary-results-renderer {
                    max-width: 400px !important;
                }
                
                body.wayback-2011-theme #secondary ytd-compact-video-renderer ytd-thumbnail,
                body.wayback-2011-theme #secondary .ytd-compact-video-renderer .ytd-thumbnail {
                    width: 220px !important;
                    height: 124px !important;
                    min-width: 220px !important;
                    flex-shrink: 0 !important;
                }

                body.wayback-2011-theme #secondary ytd-compact-video-renderer ytd-thumbnail img,
                body.wayback-2011-theme #secondary .ytd-compact-video-renderer .ytd-thumbnail img {
                    width: 220px !important;
                    height: 124px !important;
                    object-fit: cover !important;
                    border-radius: 0 !important;
                }

                /* Fix oversized emojis - be more specific to avoid breaking thumbnails */
                body.wayback-2011-theme .emoji,
                body.wayback-2011-theme img[src*="emoji"] {
                    max-width: 20px !important;
                    max-height: 20px !important;
                    width: auto !important;
                    height: auto !important;
                }

                /* Don't break main video thumbnails */
                body.wayback-2011-theme ytd-video-renderer:not(#secondary *) ytd-thumbnail,
                body.wayback-2011-theme ytd-rich-item-renderer:not(#secondary *) ytd-thumbnail,
                body.wayback-2011-theme ytd-grid-video-renderer:not(#secondary *) ytd-thumbnail {
                    width: auto !important;
                    height: auto !important;
                }
            `;

            // Create style element with marker
            const styleElement = document.createElement('style');
            styleElement.setAttribute('data-wayback-vintage', 'true');
            styleElement.textContent = vintage2011CSS;
            document.head.appendChild(styleElement);
            
            // Also use GM_addStyle as backup
            GM_addStyle(vintage2011CSS);
            
            OptimizedUtils.log('Vintage 2011 CSS injected');
        }

        initializeVintageTheme() {
            const isVintageActive = GM_getValue('ytVintage2011Theme', false);
            const button = document.getElementById('tmVintageToggle');
            
            // Always inject vintage CSS on initialization
            this.injectVintageCSS();
            
            // Apply saved theme state
            if (isVintageActive) {
                document.body.classList.add('wayback-2011-theme');
            }
            
            // Update button state
            if (button) {
                button.textContent = isVintageActive ? '🕰️ Modern Theme' : '🕰️ 2011 Theme';
                button.classList.toggle('active', isVintageActive);
            }
            
            // Expose global vintage toggle function for compatibility
            window.handleGlobalVintageToggle = () => this.handleVintageToggle();
            
            OptimizedUtils.log(`2011 Vintage Theme initialized: ${isVintageActive ? 'active' : 'inactive'}`);
        }

        handleUrlChange() {
            // Re-initialize elements that may have been replaced by navigation
            setTimeout(() => {
                this.timeMachine.searchManager?.injectSearchDateFilter();
            }, 500);
        }
    }

    // === INITIALIZATION ===
    let wayBackTubeApp;

    // Initialize when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initializeApp);
    } else {
        initializeApp();
    }

    function initializeApp() {
        try {
            wayBackTubeApp = new WayBackTubeOptimized();

            // Global access for debugging and video caching
            window.WayBackTube = wayBackTubeApp;
            window.waybackTubeManager = wayBackTubeApp; // For video caching compatibility

            // Removed relative date filtering to prevent double-processing and "in the future" issues

            OptimizedUtils.log('WayBackTube Optimized loaded successfully');
        } catch (error) {
            console.error('Failed to initialize WayBackTube:', error);
        }
    }

    // Cleanup on page unload
    window.addEventListener('beforeunload', () => {
        if (wayBackTubeApp) {
            wayBackTubeApp.cleanup();
        }
    });

    // Handle navigation changes (for SPAs like YouTube)
    let lastUrl = location.href;
    new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;
            if (wayBackTubeApp && wayBackTubeApp.isInitialized) {
                // Re-initialize UI for new page if needed
                setTimeout(() => {
                    wayBackTubeApp.uiManager.handleUrlChange();
                }, 500);
            }
        }
    }).observe(document, { subtree: true, childList: true });

    OptimizedUtils.log('WayBackTube Optimized script loaded');

})();

QingJ © 2025

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