{
  "manifest_version": 3,
  "name": "Media Loader",
  "version": "1.3",
  "description": "Load and play music and videos from YouTube and Vimeo",
  "permissions": ["storage", "tabs"],
  "host_permissions": [
      "https://www.youtube.com/",
      "https://player.vimeo.com/"
  ],
  "background": {
      "service_worker": "background.js"
  },
  "action": {
      "default_title": "Open Media Loader",
      "default_icon": {
          "16": "icons/icon16.png",
          "48": "icons/icon48.png",
          "128": "icons/icon128.png"
      }
  },
  "icons": {
      "16": "icons/icon16.png",
      "48": "icons/icon48.png",
      "128": "icons/icon128.png"
  },
  "content_security_policy": {
      "extension_pages": "script-src 'self'; object-src 'self'"
  },
  "web_accessible_resources": [
      {
          "resources": ["lib/player.js"],
          "matches": ["<all_urls>"]
      }
  ]
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Media Loader Dashboard</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <main class="container">
        <!-- Header with Settings Button and Title -->
        <header class="header">
            <button id="settings-button" class="settings-button" aria-label="Open Settings">
                <img src="icons/settings.svg" alt="Settings" class="settings-icon">
            </button>
            <h1 class="main-title">SyncWave</h1>
        </header>

        <!-- Load Audio Section -->
        <section class="section" id="load-music-section">
            <fieldset>
                <label for="music-url">Audio URL</label>
                <input type="text" id="music-url" name="music-url" placeholder="Enter YouTube or Vimeo URL">

                <label for="music-file">Local Audio File</label>
                <input type="file" id="music-file" name="music-file" accept="audio/*">

                <label for="music-start">Start Time (seconds)</label>
                <input type="number" id="music-start" name="music-start" placeholder="Start Time (seconds)" min="0">

                <button type="button" id="load-music" class="load-button">Load Audio</button>
            </fieldset>
            <div id="music-player-container" class="player-container"></div>
        </section>

        <!-- Load Video Section -->
        <section class="section" id="load-video-section">
            <fieldset>
                <label for="video-url">Video URL</label>
                <input type="text" id="video-url" name="video-url" placeholder="Enter YouTube or Vimeo URL">

                <label for="video-file">Local Video File</label>
                <input type="file" id="video-file" name="video-file" accept="video/*">

                <label for="video-start">Start Time (seconds)</label>
                <input type="number" id="video-start" name="video-start" placeholder="Start Time (seconds)" min="0">

                <button type="button" id="load-video" class="load-button">Load Video</button>
            </fieldset>
            <div id="video-player-container" class="player-container"></div>
        </section>

        <!-- Playback Controls -->
        <section class="controls">
            <button type="button" id="play-button" class="play-button" disabled aria-label="Play">Play</button>
            <button type="button" id="pause-button" class="pause-button" disabled aria-label="Pause">Pause</button>
            <button type="button" id="resume-button" class="resume-button" disabled aria-label="Resume">Resume</button>
        </section>

        <!-- Message Container -->
        <section id="message-container" class="message-container" role="alert" aria-live="assertive"></section>

        <!-- Settings Modal -->
        <div id="settings-modal" class="modal" role="dialog" aria-labelledby="settings-modal-title" aria-modal="true" hidden>
            <div class="modal-content">
                <button class="close-button" aria-label="Close Settings Modal">&times;</button>
                <h2 id="settings-modal-title">Settings</h2>
                <form>
                    <label for="fullscreen-toggle">
                        <input type="checkbox" id="fullscreen-toggle" name="fullscreen-toggle">
                        Full Screen on Play
                    </label>
                    <!-- Additional settings can go here -->
                </form>
            </div>
        </div>
    </main>

    <!-- Local Vimeo Player API -->
    <script src="lib/player.js"></script>

    <!-- Your Dashboard JS -->
    <script src="dashboard.js"></script>
</body>
</html>

"use strict";

document.addEventListener('DOMContentLoaded', () => {
    // === Element References ===
    const elements = {
        music: {
            urlInput: document.getElementById('music-url'),
            fileInput: document.getElementById('music-file'),
            startInput: document.getElementById('music-start'),
            loadButton: document.getElementById('load-music'),
            playerContainer: document.getElementById('music-player-container')
        },
        video: {
            urlInput: document.getElementById('video-url'),
            fileInput: document.getElementById('video-file'),
            startInput: document.getElementById('video-start'),
            loadButton: document.getElementById('load-video'),
            playerContainer: document.getElementById('video-player-container')
        },
        controls: {
            playButton: document.getElementById('play-button'),
            pauseButton: document.getElementById('pause-button'),
            resumeButton: document.getElementById('resume-button')
        },
        messageContainer: document.getElementById('message-container'),
        settings: {
            button: document.getElementById('settings-button'),
            modal: document.getElementById('settings-modal'),
            closeButton: document.querySelector('.close-button'),
            fullscreenToggle: document.getElementById('fullscreen-toggle')
        }
    };

    // === State Management ===
    const state = {
        music: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLAudioElement | YT.Player | Vimeo.Player, start: Number }
        video: null, // { type: 'file' | 'youtube' | 'vimeo', element: HTMLVideoElement | YT.Player | Vimeo.Player, start: Number }
        isPaused: false,
        fullscreenOnPlay: false
    };

    // === Utility Functions ===

    /**
     * Displays a message to the user.
     * @param {string} message - The message to display.
     * @param {string} type - The type of message ('success', 'error', 'info').
     */
    function showMessage(message, type) {
        elements.messageContainer.innerHTML = '';
        const msgDiv = document.createElement('div');
        msgDiv.textContent = message;
        msgDiv.classList.add('message', type); // 'success', 'error', 'info'
        elements.messageContainer.appendChild(msgDiv);

        // Automatically hide message after 5 seconds
        setTimeout(() => {
            if (elements.messageContainer.contains(msgDiv)) {
                elements.messageContainer.removeChild(msgDiv);
            }
        }, 5000);
    }

    /**
     * Shows a loading spinner in the specified container.
     * @param {HTMLElement} container - The container to show the loader in.
     */
    function showLoading(container) {
        container.innerHTML = '';
        const loader = document.createElement('div');
        loader.classList.add('loader'); // Define loader styles in CSS
        container.appendChild(loader);
    }

    /**
     * Hides the loading spinner from the specified container.
     * @param {HTMLElement} container - The container to hide the loader from.
     */
    function hideLoading(container) {
        const loader = container.querySelector('.loader');
        if (loader) {
            container.removeChild(loader);
        }
    }

    /**
     * Traps keyboard focus within a specified element.
     * @param {HTMLElement} element - The element to trap focus within.
     */
    function trapFocus(element) {
        const focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]),' +
            ' textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"],' +
            ' [contenteditable]';
        const focusableElements = element.querySelectorAll(focusableElementsString);
        const firstTabStop = focusableElements[0];
        const lastTabStop = focusableElements[focusableElements.length - 1];

        // Listen for and trap the keyboard
        element.addEventListener('keydown', trapTabKey);

        function trapTabKey(e) {
            // Check for TAB key press
            if (e.key === 'Tab') {
                // SHIFT + TAB
                if (e.shiftKey) {
                    if (document.activeElement === firstTabStop) {
                        e.preventDefault();
                        lastTabStop.focus();
                    }
                } else { // TAB
                    if (document.activeElement === lastTabStop) {
                        e.preventDefault();
                        firstTabStop.focus();
                    }
                }
            }
        }

        // Remove trap when modal is closed
        function removeTrapKey(e) {
            element.removeEventListener('keydown', trapTabKey);
        }

        // Store the function reference to remove it later
        element.removeTrapKey = removeTrapKey;
    }

    function removeTrapFocus() {
        if (elements.settings.modal.removeTrapKey) {
            elements.settings.modal.removeTrapKey();
        }
    }

    // === Initialization ===
    loadSettings();

    // === Event Listeners ===
    elements.music.loadButton.addEventListener('click', handleLoadMusic);
    elements.video.loadButton.addEventListener('click', handleLoadVideo);
    elements.controls.playButton.addEventListener('click', handlePlay);
    elements.controls.pauseButton.addEventListener('click', handlePause);
    elements.controls.resumeButton.addEventListener('click', handleResume);

    // Settings Modal Event Listeners
    elements.settings.button.addEventListener('click', openSettingsModal);
    elements.settings.closeButton.addEventListener('click', closeSettingsModal);
    window.addEventListener('click', (event) => {
        if (event.target === elements.settings.modal) {
            closeSettingsModal();
        }
    });
    document.addEventListener('keydown', (event) => {
        if (event.key === 'Escape' && !elements.settings.modal.hasAttribute('hidden')) {
            closeSettingsModal();
        }
    });
    elements.settings.fullscreenToggle.addEventListener('change', (event) => {
        state.fullscreenOnPlay = event.target.checked;
        saveSettings();
    });

    // === Handler Functions ===

    // Load Music Handler
    function handleLoadMusic() {
        const url = elements.music.urlInput.value.trim();
        const file = elements.music.fileInput.files[0];
        const start = parseInt(elements.music.startInput.value) || 0;

        // Show loading indicator
        showLoading(elements.music.playerContainer);

        // Unload existing music if any
        if (state.music) {
            unloadMedia('music');
        }

        if (file) {
            if (file.size > 10 * 1024 * 1024) { // 10MB limit
                showMessage('Audio file size exceeds 10MB limit.', 'error');
                hideLoading(elements.music.playerContainer);
                return;
            }

            // Handle local audio file
            const fileUrl = URL.createObjectURL(file);
            const audioElement = document.createElement('audio');
            audioElement.controls = true;
            audioElement.src = fileUrl;
            audioElement.id = 'loaded-music';
            audioElement.setAttribute('aria-label', 'Loaded Audio Player');
            audioElement.style.width = '100%';
            audioElement.style.height = 'auto';
            elements.music.playerContainer.innerHTML = '';
            elements.music.playerContainer.appendChild(audioElement);

            // Set start time if applicable
            if (start > 0) {
                audioElement.currentTime = start;
            }

            state.music = {
                type: 'file',
                element: audioElement,
                start: start
            };
            showMessage('Local audio file loaded.', 'success');
            hideLoading(elements.music.playerContainer);
        } else if (url && isValidMediaURL(url)) {
            const mediaInfo = extractMediaInfo(url);
            if (mediaInfo) {
                if (mediaInfo.platform === 'youtube') {
                    embedYouTubeIframe(mediaInfo.id, start, 'music');
                } else if (mediaInfo.platform === 'vimeo') {
                    embedVimeoPlayer(mediaInfo.id, start, 'music');
                }
                showMessage(`Loaded ${capitalize(mediaInfo.platform)} audio.`, 'success');
                hideLoading(elements.music.playerContainer);

                // Implement buffering: play briefly, then pause and set start time
                bufferAndPause(mediaInfo.platform, 'music', start);
            } else {
                showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
                hideLoading(elements.music.playerContainer);
            }
        } else {
            showMessage('Please enter a URL or select a local audio file.', 'error');
            hideLoading(elements.music.playerContainer);
        }

        checkReadyToPlay();
        saveSettings();
    }

    // Load Video Handler
    function handleLoadVideo() {
        const url = elements.video.urlInput.value.trim();
        const file = elements.video.fileInput.files[0];
        const start = parseInt(elements.video.startInput.value) || 0;

        // Show loading indicator
        showLoading(elements.video.playerContainer);

        // Unload existing video if any
        if (state.video) {
            unloadMedia('video');
        }

        if (file) {
            if (file.size > 50 * 1024 * 1024) { // 50MB limit
                showMessage('Video file size exceeds 50MB limit.', 'error');
                hideLoading(elements.video.playerContainer);
                return;
            }

            // Handle local video file
            const fileUrl = URL.createObjectURL(file);
            const videoElement = document.createElement('video');
            videoElement.controls = true;
            videoElement.src = fileUrl;
            videoElement.id = 'loaded-video';
            videoElement.setAttribute('aria-label', 'Loaded Video Player');
            videoElement.style.width = '100%';
            videoElement.style.height = 'auto';
            elements.video.playerContainer.innerHTML = '';
            elements.video.playerContainer.appendChild(videoElement);

            // Set start time if applicable
            if (start > 0) {
                videoElement.currentTime = start;
            }

            state.video = {
                type: 'file',
                element: videoElement,
                start: start
            };
            showMessage('Local video file loaded.', 'success');
            hideLoading(elements.video.playerContainer);
        } else if (url && isValidMediaURL(url)) {
            const mediaInfo = extractMediaInfo(url);
            if (mediaInfo) {
                if (mediaInfo.platform === 'youtube') {
                    embedYouTubeIframe(mediaInfo.id, start, 'video');
                } else if (mediaInfo.platform === 'vimeo') {
                    embedVimeoPlayer(mediaInfo.id, start, 'video');
                }
                showMessage(`Loaded ${capitalize(mediaInfo.platform)} video.`, 'success');
                hideLoading(elements.video.playerContainer);

                // Implement buffering: play briefly, then pause and set start time
                bufferAndPause(mediaInfo.platform, 'video', start);
            } else {
                showMessage('Invalid URL. Please enter a valid YouTube or Vimeo URL.', 'error');
                hideLoading(elements.video.playerContainer);
            }
        } else {
            showMessage('Please enter a URL or select a local video file.', 'error');
            hideLoading(elements.video.playerContainer);
        }

        checkReadyToPlay();
        saveSettings();
    }

    // Play Handler
    function handlePlay() {
        // Play Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.music.element);
                }
            } else if (state.music.type === 'vimeo') {
                state.music.element.play().catch(error => {
                    console.error('Error playing Vimeo audio:', error);
                    showMessage('Failed to play Vimeo audio.', 'error');
                });
            } else if (state.music.type === 'youtube') {
                // YouTube iframe without API cannot be controlled via JS
                // Users can manually control playback
                showMessage('YouTube playback controls are limited due to extension restrictions.', 'info');
            }
        }

        // Play Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.video.element);
                }
            } else if (state.video.type === 'vimeo') {
                state.video.element.play().catch(error => {
                    console.error('Error playing Vimeo video:', error);
                    showMessage('Failed to play Vimeo video.', 'error');
                });
            } else if (state.video.type === 'youtube') {
                // YouTube iframe without API cannot be controlled via JS
                // Users can manually control playback
                showMessage('YouTube playback controls are limited due to extension restrictions.', 'info');
            }
        }

        state.isPaused = false;
        elements.controls.pauseButton.disabled = false;
        elements.controls.resumeButton.disabled = true;
        elements.controls.pauseButton.textContent = 'Pause';
        showMessage('Playback started!', 'success');
    }

    // Pause Handler
    function handlePause() {
        if (state.isPaused) return;

        // Pause Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.pause();
            } else if (state.music.type === 'vimeo') {
                state.music.element.pause().catch(error => {
                    console.error('Error pausing Vimeo audio:', error);
                    showMessage('Failed to pause Vimeo audio.', 'error');
                });
            }
            // YouTube iframe without API cannot be controlled via JS
        }

        // Pause Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.pause();
            } else if (state.video.type === 'vimeo') {
                state.video.element.pause().catch(error => {
                    console.error('Error pausing Vimeo video:', error);
                    showMessage('Failed to pause Vimeo video.', 'error');
                });
            }
            // YouTube iframe without API cannot be controlled via JS
        }

        state.isPaused = true;
        elements.controls.resumeButton.disabled = false;
        elements.controls.pauseButton.disabled = true;
        elements.controls.pauseButton.textContent = 'Pause';
        showMessage('Playback paused.', 'info');
    }

    // Resume Handler
    function handleResume() {
        if (!state.isPaused) return;

        // Resume Music
        if (state.music) {
            if (state.music.type === 'file') {
                state.music.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.music.element);
                }
            } else if (state.music.type === 'vimeo') {
                state.music.element.play().catch(error => {
                    console.error('Error resuming Vimeo audio:', error);
                    showMessage('Failed to resume Vimeo audio.', 'error');
                });
            }
            // YouTube iframe without API cannot be controlled via JS
        }

        // Resume Video
        if (state.video) {
            if (state.video.type === 'file') {
                state.video.element.play();
                if (state.fullscreenOnPlay) {
                    enterFullscreen(state.video.element);
                }
            } else if (state.video.type === 'vimeo') {
                state.video.element.play().catch(error => {
                    console.error('Error resuming Vimeo video:', error);
                    showMessage('Failed to resume Vimeo video.', 'error');
                });
            }
            // YouTube iframe without API cannot be controlled via JS
        }

        state.isPaused = false;
        elements.controls.resumeButton.disabled = true;
        elements.controls.pauseButton.disabled = false;
        elements.controls.pauseButton.textContent = 'Pause';
        showMessage('Playback resumed.', 'success');
    }

    // === Settings Modal Functions ===
    function openSettingsModal() {
        elements.settings.modal.removeAttribute('hidden');
        elements.settings.modal.setAttribute('aria-hidden', 'false');
        elements.settings.modal.querySelector('.close-button').focus();
        trapFocus(elements.settings.modal);
    }

    function closeSettingsModal() {
        elements.settings.modal.setAttribute('hidden', '');
        elements.settings.modal.setAttribute('aria-hidden', 'true');
        elements.settings.button.focus();
        removeTrapFocus();
    }

    // === Media Embedding Functions ===

    /**
     * Embeds a YouTube video into the specified container using an iframe.
     * @param {string} videoId - The YouTube video ID.
     * @param {number} start - The start time in seconds.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function embedYouTubeIframe(videoId, start, mediaType) {
        const container = elements[mediaType].playerContainer;
        container.innerHTML = ''; // Clear previous content

        const src = `https://www.youtube.com/embed/${videoId}?start=${start}&autoplay=1&mute=1&controls=1&rel=0&enablejsapi=1`;
        const iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.width = '100%';
        iframe.height = '720'; // Increased height
        iframe.frameBorder = '0';
        iframe.allow = 'autoplay; fullscreen; picture-in-picture';

        iframe.setAttribute('title', 'YouTube video player');

        container.appendChild(iframe);

        state[mediaType] = {
            type: 'youtube',
            element: iframe,
            start: start
        };

        // Note: Without YouTube IFrame API, we cannot control playback via JS
    }

    /**
     * Embeds a Vimeo video into the specified container using the Player API.
     * @param {string} videoId - The Vimeo video ID.
     * @param {number} start - The start time in seconds.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function embedVimeoPlayer(videoId, start, mediaType) {
        const container = elements[mediaType].playerContainer;
        container.innerHTML = ''; // Clear previous content

        const iframe = document.createElement('iframe');
        const src = `https://player.vimeo.com/video/${videoId}?muted=1&autopause=0&background=0`;
        iframe.src = src;
        iframe.width = '100%';
        iframe.height = '720'; // Increased height
        iframe.frameBorder = '0';
        iframe.allow = 'autoplay; fullscreen; picture-in-picture';

        iframe.setAttribute('title', 'Vimeo video player');

        container.appendChild(iframe);

        const player = new Vimeo.Player(iframe, {
            id: videoId,
            width: container.clientWidth,
            muted: true,
            autoplay: false,
            start: start
        });

        state[mediaType] = {
            type: 'vimeo',
            element: player,
            start: start
        };
    }

    /**
     * Implements the buffering process: plays briefly, pauses, sets to start time.
     * @param {string} platform - 'youtube' or 'vimeo'.
     * @param {string} mediaType - 'music' or 'video'.
     * @param {number} startTime - The start time in seconds.
     */
    function bufferAndPause(platform, mediaType, startTime) {
        if (platform === 'vimeo') {
            // Vimeo Player API allows playback control
            const player = state[mediaType].element;
            player.play().then(() => {
                // Wait for at least 125ms
                setTimeout(() => {
                    player.pause().then(() => {
                        player.setCurrentTime(startTime).then(() => {
                            showMessage(`Vimeo ${mediaType} buffered and set to ${startTime} seconds.`, 'success');
                        }).catch(error => {
                            console.error(`Error setting start time for Vimeo ${mediaType}:`, error);
                            showMessage(`Failed to set start time for Vimeo ${mediaType}.`, 'error');
                        });
                    }).catch(error => {
                        console.error(`Error pausing Vimeo ${mediaType}:`, error);
                        showMessage(`Failed to pause Vimeo ${mediaType}.`, 'error');
                    });
                }, 125);
            }).catch(error => {
                console.error(`Error playing Vimeo ${mediaType}:`, error);
                showMessage(`Failed to play Vimeo ${mediaType}.`, 'error');
            });
        } else if (platform === 'youtube') {
            // Limited control without YouTube IFrame API
            showMessage('Buffering for YouTube is limited due to extension restrictions.', 'info');
            // Users need to manually adjust playback
        }
    }

    // === Settings Modal Functions ===
    function openSettingsModal() {
        elements.settings.modal.removeAttribute('hidden');
        elements.settings.modal.setAttribute('aria-hidden', 'false');
        elements.settings.modal.querySelector('.close-button').focus();
        trapFocus(elements.settings.modal);
    }

    function closeSettingsModal() {
        elements.settings.modal.setAttribute('hidden', '');
        elements.settings.modal.setAttribute('aria-hidden', 'true');
        elements.settings.button.focus();
        removeTrapFocus();
    }

    // === Settings Persistence ===

    /**
     * Loads settings from Chrome storage.
     */
    function loadSettings() {
        try {
            chrome.storage.local.get(['mediaSettings'], (result) => {
                if (chrome.runtime.lastError) {
                    throw new Error(chrome.runtime.lastError);
                }

                if (result.mediaSettings) {
                    const { music, video, fullscreenOnPlay: fsPlay } = result.mediaSettings;

                    if (music) {
                        if (music.type === 'youtube' || music.type === 'vimeo') {
                            const url = music.type === 'youtube'
                                ? `https://www.youtube.com/watch?v=${music.id}`
                                : `https://vimeo.com/${music.id}`;
                            elements.music.urlInput.value = url;
                            elements.music.startInput.value = music.start || 0;
                            // Optionally, auto-load the media by triggering the load button
                            // handleLoadMusic();
                        }
                        // Handle file-based music loading if necessary
                    }

                    if (video) {
                        if (video.type === 'youtube' || video.type === 'vimeo') {
                            const url = video.type === 'youtube'
                                ? `https://www.youtube.com/watch?v=${video.id}`
                                : `https://vimeo.com/${video.id}`;
                            elements.video.urlInput.value = url;
                            elements.video.startInput.value = video.start || 0;
                            // Optionally, auto-load the media by triggering the load button
                            // handleLoadVideo();
                        }
                        // Handle file-based video loading if necessary
                    }

                    if (typeof fsPlay === 'boolean') {
                        state.fullscreenOnPlay = fsPlay;
                        elements.settings.fullscreenToggle.checked = fsPlay;
                    }
                }
            });
        } catch (error) {
            console.error('Error loading settings:', error);
            showMessage('Failed to load settings.', 'error');
        }
    }

    /**
     * Saves settings to Chrome storage.
     */
    function saveSettings() {
        const settings = {
            music: state.music,
            video: state.video,
            fullscreenOnPlay: state.fullscreenOnPlay
        };
        try {
            chrome.storage.local.set({ mediaSettings: settings }, () => {
                if (chrome.runtime.lastError) {
                    throw new Error(chrome.runtime.lastError);
                }
                console.log('Settings saved.');
            });
        } catch (error) {
            console.error('Error saving settings:', error);
            showMessage('Error saving settings.', 'error');
        }
    }

    /**
     * Unloads media from the specified type.
     * @param {string} mediaType - 'music' or 'video'.
     */
    function unloadMedia(mediaType) {
        if (state[mediaType]) {
            if (state[mediaType].type === 'file') {
                if (state[mediaType].element.src) {
                    URL.revokeObjectURL(state[mediaType].element.src);
                    state[mediaType].element.src = '';
                    state[mediaType].element.remove();
                }
            } else if (state[mediaType].type === 'youtube') {
                const iframe = state[mediaType].element;
                iframe.src = ''; // Reset iframe src to stop the media
            } else if (state[mediaType].type === 'vimeo') {
                const player = state[mediaType].element;
                player.unload().catch(error => {
                    console.error(`Error unloading Vimeo ${mediaType}:`, error);
                });
            }
            state[mediaType] = null;
        }
    }

    // === Playback Controls ===

    /**
     * Enables or disables playback controls based on media loading state.
     */
    function checkReadyToPlay() {
        // Enable buttons only when at least one of audio or video is loaded
        const readyAudio = state.music
            && (state.music.type === 'file'
                || state.music.type === 'youtube'
                || state.music.type === 'vimeo');
        const readyVideo = state.video
            && (state.video.type === 'file'
                || state.video.type === 'youtube'
                || state.video.type === 'vimeo');
        const ready = readyAudio || readyVideo;

        elements.controls.playButton.disabled = !ready;
        elements.controls.pauseButton.disabled = !ready;
        elements.controls.resumeButton.disabled = true; // Start with Resume disabled
    }

    // === Media Embedding Functions ===

    /**
     * Validates whether the URL is a valid YouTube or Vimeo URL.
     * @param {string} url - The URL to validate.
     * @returns {boolean} True if valid, else false.
     */
    function isValidMediaURL(url) {
        try {
            const parsedUrl = new URL(url);
            const hostname = parsedUrl.hostname.toLowerCase();
            const pathname = parsedUrl.pathname;

            // YouTube RegEx Patterns
            const youtubeRegex = /^\/(?:watch\/|embed\/|v\/)?([a-zA-Z0-9_-]{11})$/;
            // Vimeo RegEx Patterns
            const vimeoRegex = /^\/(?:video\/)?(\d+)$/;

            if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
                // Extract YouTube video ID
                let videoId = '';
                if (hostname === 'youtu.be') {
                    videoId = pathname.slice(1);
                } else {
                    videoId = parsedUrl.searchParams.get('v') || '';
                }
                return youtubeRegex.test(`/${videoId}`);
            } else if (hostname.includes('vimeo.com')) {
                // Extract Vimeo video ID
                const match = pathname.match(vimeoRegex);
                return match && match[1].length > 0;
            }

            return false;
        } catch (e) {
            return false;
        }
    }

    /**
     * Extracts media information from the URL.
     * @param {string} url - The media URL.
     * @returns {Object|null} An object with platform and id, or null if invalid.
     */
    function extractMediaInfo(url) {
        try {
            const parsedUrl = new URL(url);
            const hostname = parsedUrl.hostname.toLowerCase();
            const pathname = parsedUrl.pathname;

            // YouTube Patterns
            if (hostname.includes('youtube.com') || hostname === 'youtu.be') {
                let videoId = '';
                if (hostname === 'youtu.be') {
                    videoId = pathname.slice(1);
                } else {
                    videoId = parsedUrl.searchParams.get('v') || '';
                }

                // Validate videoId length
                if (videoId.length === 11) {
                    return { platform: 'youtube', id: videoId };
                }
            }

            // Vimeo Patterns
            if (hostname.includes('vimeo.com')) {
                const vimeoMatch = pathname.match(/^\/(?:video\/)?(\d+)$/);
                if (vimeoMatch && vimeoMatch[1]) {
                    return { platform: 'vimeo', id: vimeoMatch[1] };
                }
            }

            return null;
        } catch (e) {
            return null;
        }
    }

    /**
     * Capitalize the first letter of a string.
     * @param {string} text - The string to capitalize.
     * @returns {string} Capitalized string.
     */
    function capitalize(text) {
        if (!text) return '';
        return text.charAt(0).toUpperCase() + text.slice(1);
    }

    /**
     * Enters fullscreen mode for the specified element.
     * @param {HTMLElement} element - The element to enter fullscreen.
     */
    function enterFullscreen(element) {
        if (element && element.requestFullscreen) {
            element.requestFullscreen().then(() => {
                showMessage('Entered fullscreen mode.', 'success');
            }).catch(err => {
                console.error(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
                showMessage('Failed to enter fullscreen mode.', 'error');
            });
        } else {
            showMessage('Fullscreen not supported on this element.', 'error');
        }
    }

    /**
     * Implements the buffering process: plays briefly, pauses, sets to start time.
     * @param {string} platform - 'youtube' or 'vimeo'.
     * @param {string} mediaType - 'music' or 'video'.
     * @param {number} startTime - The start time in seconds.
     */
    function bufferAndPause(platform, mediaType, startTime) {
        if (platform === 'vimeo') {
            // Vimeo Player API allows playback control
            const player = state[mediaType].element;
            player.play().then(() => {
                // Wait for at least 125ms
                setTimeout(() => {
                    player.pause().then(() => {
                        player.setCurrentTime(startTime).then(() => {
                            showMessage(`Vimeo ${mediaType} buffered and set to ${startTime} seconds.`, 'success');
                        }).catch(error => {
                            console.error(`Error setting start time for Vimeo ${mediaType}:`, error);
                            showMessage(`Failed to set start time for Vimeo ${mediaType}.`, 'error');
                        });
                    }).catch(error => {
                        console.error(`Error pausing Vimeo ${mediaType}:`, error);
                        showMessage(`Failed to pause Vimeo ${mediaType}.`, 'error');
                    });
                }, 125);
            }).catch(error => {
                console.error(`Error playing Vimeo ${mediaType}:`, error);
                showMessage(`Failed to play Vimeo ${mediaType}.`, 'error');
            });
        } else if (platform === 'youtube') {
            // Limited control without YouTube IFrame API
            showMessage('Buffering for YouTube is limited due to extension restrictions.', 'info');
            // Users need to manually adjust playback
        }
    }

    // Initialize ready state
    checkReadyToPlay();

    // Ensure buttons are correctly enabled/disabled on load
    if (state.music || state.video) {
        elements.controls.playButton.disabled = false;
    }
});

chrome.action.onClicked.addListener(() => {
    const dashboardURL = chrome.runtime.getURL("dashboard.html");

    // Query for any existing tabs with the dashboard URL
    chrome.tabs.query({ url: dashboardURL }, (tabs) => {
        if (chrome.runtime.lastError) {
            console.error("Tab Query Error:", chrome.runtime.lastError);
            return;
        }

        if (tabs.length > 0) {
            // Activate the first existing dashboard tab
            chrome.tabs.update(tabs[0].id, { active: true }, (updatedTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Update Error:", chrome.runtime.lastError);
                }
            });
        } else {
            // Create a new dashboard tab
            chrome.tabs.create({ url: dashboardURL, active: true }, (newTab) => {
                if (chrome.runtime.lastError) {
                    console.error("Tab Creation Error:", chrome.runtime.lastError);
                }
            });
        }
    });
});

/* General Styles */
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
}

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px;
    max-width: 1000px; /* Increased max-width for larger displays */
    margin: 0 auto;
}

.section {
    width: 100%;
    margin-bottom: 20px;
    background-color: #fff;
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

/* Header with Settings Button and Title */
.header {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center; /* Center the content */
    margin-bottom: 20px;
    position: relative;
}

.settings-button {
    position: absolute;
    left: 0;
    background: #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
    padding: 5px;
    cursor: pointer;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}

.settings-button:hover {
    background-color: #f0f0f0;
    border-color: #999;
}

.settings-icon {
    width: 24px;
    height: 24px;
}

/* Main Title */
.main-title {
    font-size: 2.5em; /* Increased font size for better visibility */
    font-weight: bold;
    margin: 0;
}

/* Section Header */
.section-header {
    display: flex;
    align-items: center;
    margin-bottom: 10px;
}

.section-header legend {
    font-size: 1.2em;
    font-weight: bold;
    margin: 0;
}

/* Controls */
.controls {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.controls button {
    padding: 12px 24px; /* Increased padding for better accessibility */
    cursor: pointer;
    border: none;
    border-radius: 5px;
    background-color: #4285f4;
    color: #fff;
    transition: background-color 0.3s ease;
    font-size: 1em;
}

.controls button:disabled {
    background-color: #a0c3ff;
    cursor: not-allowed;
}

.controls button:hover:not(:disabled) {
    background-color: #357ae8;
}

/* Play Button Specific Styles */
.play-button {
    background-color: #34a853; /* Green */
}

.play-button:hover:not(:disabled) {
    background-color: #2c8e46;
}

/* Pause Button Specific Styles */
.pause-button {
    background-color: #fbbc05; /* Yellow */
}

.pause-button:hover:not(:disabled) {
    background-color: #e0a800;
}

/* Resume Button Specific Styles */
.resume-button {
    background-color: #ea4335; /* Red */
}

.resume-button:hover:not(:disabled) {
    background-color: #c33c2c;
}

/* Modal Styles */
.modal[hidden] {
    display: none;
}

.modal {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex; /* Visible when not hidden */
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.modal-content {
    background-color: #fff;
    padding: 20px 30px;
    border-radius: 8px;
    width: 90%;
    max-width: 500px; /* Increased max-width for better layout */
    position: relative;
}

.close-button {
    position: absolute;
    top: 10px;
    right: 15px;
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
}

.modal-content h2 {
    margin-top: 0;
}

/* Form Elements */
fieldset {
    border: none;
    padding: 0;
}

fieldset label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

fieldset input[type="text"],
fieldset input[type="number"],
fieldset input[type="file"] {
    width: 100%;
    padding: 10px; /* Increased padding for better usability */
    margin-bottom: 15px;
    box-sizing: border-box;
    border: 1px solid #ccc;
    border-radius: 4px;
}

fieldset .load-button {
    width: 100%;
    padding: 12px;
    background-color: #4285f4; /* Blue */
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s ease;
    font-size: 1em;
}

fieldset .load-button:hover {
    background-color: #357ae8;
}

/* Player Containers */
.player-container {
    margin-top: 10px;
    width: 100%;
    max-width: 100%;
    min-height: 100px; /* Increased minimum height */
    box-sizing: border-box;
    overflow: hidden; /* Prevent overflow */
}

/* Responsive Video and Audio Elements */
.player-container video,
.player-container iframe {
    width: 100%;
    height: 720px; /* Fixed height for larger displays */
    border-radius: 8px;
    /* Ensure the iframe fills the container */
    display: block;
}

/* Messages */
.message-container {
    position: fixed;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1001; /* Above other content */
    width: 90%;
    max-width: 600px;
}

.message {
    padding: 12px 20px;
    border-radius: 5px;
    margin-bottom: 10px;
    color: #fff;
    font-size: 1em;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    opacity: 0.95;
}

.message.success {
    background-color: #4caf50;
}

.message.error {
    background-color: #f44336;
}

.message.info {
    background-color: #2196f3;
}

/* Loader */
.loader {
    border: 8px solid #f3f3f3; /* Light grey */
    border-top: 8px solid #4285f4; /* Blue */
    border-radius: 50%;
    width: 60px; /* Increased size for better visibility */
    height: 60px; /* Increased size for better visibility */
    animation: spin 1s linear infinite;
    margin: 0 auto;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Responsive Design */
@media (max-width: 800px) {
    .container {
        padding: 15px;
    }

    .modal-content {
        padding: 15px 20px;
    }

    .controls {
        flex-direction: column;
        width: 100%;
    }

    .controls button {
        width: 100%;
    }

    .settings-button {
        width: 35px;
        height: 35px;
    }

    .settings-icon {
        width: 18px;
        height: 18px;
    }

    .main-title {
        font-size: 2em;
    }

    .player-container video,
    .player-container iframe {
        height: 480px; /* Adjusted height for smaller screens */
    }

    .loader {
        width: 50px; /* Adjusted size for smaller screens */
        height: 50px; /* Adjusted size for smaller screens */
    }
}

@media (max-width: 500px) {
    .container {
        padding: 10px;
    }

    .controls button {
        padding: 10px;
        font-size: 0.9em;
    }

    .modal-content {
        padding: 10px 15px;
    }

    .main-title {
        font-size: 1.8em;
    }

    .player-container video,
    .player-container iframe {
        height: 360px; /* Further adjusted height for very small screens */
    }

    .loader {
        width: 40px; /* Further adjusted size for very small screens */
        height: 40px; /* Further adjusted size for very small screens */
    }
}

make the master play button say "play from start". youtube videos loaded and played but did not get paused and set to user set start time. load local audio file did not show the audio player. load local video file came up with an error: file is over 50mb, can we set this to unrestricted size?