CineBusca Pro

O seu assistente de mídia definitivo. Busque informações detalhadas, trailers e torrents para qualquer filme ou série com um simples atalho (Ctrl+1). Explore lançamentos, veja os títulos mais populares e organize sua lista de favoritos com facilidade.

// ==UserScript==
// @name         CineBusca Pro
// @namespace    https://github.com/estudiobrisacriativa/CineBusca-Pro
// @version      1.0.0
// @license      MIT
// @description  O seu assistente de mídia definitivo. Busque informações detalhadas, trailers e torrents para qualquer filme ou série com um simples atalho (Ctrl+1). Explore lançamentos, veja os títulos mais populares e organize sua lista de favoritos com facilidade.
// @author       Estudio Brisa Criativa
// @match        *://*/*
// @match       https://www.netflix.com/*
// @match       https://www.primevideo.com/*
// @match       https://www.disneyplus.com/*
// @icon        https://raw.githubusercontent.com/estudiobrisacriativa/CineBusca-Pro/refs/heads/main/assets/icon.png
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @connect      api.themoviedb.org
// @connect      image.tmdb.org
// @connect      yts.mx
// @connect      apibay.org
// ==/UserScript==

(function() {
    'use strict';

    // --- SUA API KEY ---
    const tmdbApiKey = '4514ec3b323c023dd7772b82a3772435';

    // --- CRIAÇÃO DO SHADOW DOM PARA ISOLAMENTO TOTAL ---
    const host = document.createElement('div');
    host.id = 'smart-search-host';
    document.body.appendChild(host);
    const shadowRoot = host.attachShadow({ mode: 'open' });


    // --- ESTILOS (INJETADOS DIRETAMENTE NO SHADOW DOM) ---
    const styles = `
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap');

        :host {
            --c-text: #e0e0e0; --c-background: #212121; --c-surface: #333333;
            --c-primary: #a89166; --c-secondary: #8a8a8a; --c-tertiary: #5f5f5f;
            --c-border: #424242; --c-text-dark: #212121; --c-light-bg: #f5f5f5;
            --c-favorite: #DC143C; /* Crimson */
            --c-success: #5a9e5e;
        }

        /* --- CSS Reset robusto para isolamento --- */
        *, *::before, *::after {
            box-sizing: border-box; margin: 0; padding: 0; border: 0;
            font-family: 'Inter', sans-serif;
            font-size: 16px;
            line-height: 1.4;
            color: var(--c-text);
            font-weight: 400;
        }
         a { text-decoration: none; color: inherit; }
         button { cursor: pointer; background: transparent; font-family: inherit; }
         img { display: block; max-width: 100%; }
         h3 { font-weight: 700; font-size: 1.05em;}
        /* --- Fim do Reset --- */


        #smart-search-container {
            position: fixed; top: 20px; right: 20px; width: 450px; height: 600px;
            background-color: var(--c-background);
            border-radius: 12px; box-shadow: 0 8px 30px rgba(0,0,0,0.5);
            z-index: 2147483647;
            display: none; flex-direction: column;
            border: 1px solid var(--c-border); overflow: hidden;
        }
        #smart-search-header {
            padding: 10px; background-color: var(--c-background); display: flex;
            align-items: center; gap: 8px; border-bottom: 1px solid var(--c-border); position: relative; flex-shrink: 0;
        }
        #search-input-wrapper {
            flex-grow: 1; display: flex; align-items: center; gap: 8px; background-color: var(--c-surface);
            border-radius: 20px; padding: 0 15px; border: 1px solid var(--c-border);
        }
        #smart-search-input {
            width: 100%; padding: 10px 0; background: none;
            font-size: 14px; outline: none;
            color: var(--c-text);
            flex-grow: 1;
        }
        #smart-search-input::placeholder, #year-filter-input::placeholder { color: var(--c-secondary); }
        #year-filter-input {
            width: 60px;
            background: none;
            border: none;
            outline: none;
            color: var(--c-text);
            font-size: 14px;
            text-align: center;
            flex-shrink: 0;
        }
        #year-filter-input::-webkit-outer-spin-button,
        #year-filter-input::-webkit-inner-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }
        #year-filter-input[type=number] {
            -moz-appearance: textfield;
        }

        .header-btn { cursor: pointer; padding: 5px; display: flex; align-items: center; flex-shrink: 0; }
        .header-btn svg { fill: #AAAAAA; width: 22px; height: 22px; transition: fill 0.2s; }
        .header-btn:hover svg { fill: var(--c-text); }
        #back-btn { display: none; }

        #panel-container {
            flex-grow: 1;
            position: relative;
        }

        .panel {
            position: absolute;
            top: 0; left: 0; right: 0; bottom: 0;
            opacity: 0;
            visibility: hidden;
            transition: opacity 0.2s ease-in-out, visibility 0s 0.2s;
            overflow-y: auto;
            padding: 15px;
        }
        .panel.active {
            opacity: 1;
            visibility: visible;
            transition-delay: 0s;
        }

        .panel::-webkit-scrollbar { width: 5px; }
        .panel::-webkit-scrollbar-track { background: var(--c-surface); }
        .panel::-webkit-scrollbar-thumb { background-color: var(--c-tertiary); border-radius: 10px; }

        .section-title { font-size: 1.1em; font-weight: 700; color: var(--c-primary); margin: 15px 0 10px 0; padding-bottom: 5px; border-bottom: 1px solid var(--c-border); display: flex; justify-content: space-between; align-items: center; }
        .section-title:first-child { margin-top: 0; }

        #home-nav { display: flex; flex-wrap: wrap; gap: 10px; border-bottom: 1px solid var(--c-border); padding-bottom: 10px; margin-bottom: 10px;}
        .home-nav-btn { font-size: 0.9em; color: var(--c-secondary); padding: 5px 10px; border-radius: 6px; transition: all 0.2s; }
        .home-nav-btn.active, .home-nav-btn:hover { color: var(--c-text); background-color: var(--c-surface); }

        #recent-searches-list { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
        .recent-search-tag { font-size: 0.75em; font-weight: 500; color: var(--c-text); background-color: var(--c-border); border: 1px solid var(--c-surface); padding: 4px 10px; border-radius: 15px; cursor: pointer; transition: all 0.2s ease; }
        .recent-search-tag:hover { background-color: var(--c-primary); border-color: var(--c-primary); color: var(--c-text-dark); }
        #clear-recents-btn { font-size: 0.75em; color: var(--c-secondary); background-color: transparent; border: 1px solid var(--c-border); padding: 4px 10px; border-radius: 15px; cursor: pointer; transition: all 0.2s; }
        #clear-recents-btn:hover { background-color: var(--c-primary); color: var(--c-text-dark); }


        .search-result-item { position: relative; display: flex; margin-bottom: 12px; padding: 10px; background-color: var(--c-surface); border-radius: 8px; transition: background-color 0.2s ease, border-left-color 0.3s ease; align-items: flex-start; border-left: 4px solid transparent; }
        .search-result-item:hover { background-color: var(--c-border); }
        .search-result-item.movie-item { cursor: pointer; }
        .search-result-item.favorited-item { border-left-color: var(--c-favorite); }

        .fav-btn-item {
            position: absolute; top: 15px; right: 15px; width: 32px; height: 32px;
            display: flex; justify-content: center; align-items: center; cursor: pointer;
            background-color: rgba(33, 33, 33, 0.7); border-radius: 50%;
            transition: all 0.2s ease-in-out; z-index: 2;
        }
        .fav-btn-item:hover { background-color: rgba(0, 0, 0, 0.9); transform: scale(1.1); }
        .fav-btn-item svg { width: 18px; height: 18px; fill: var(--c-secondary); transition: all 0.2s; }
        .fav-btn-item:hover svg { fill: var(--c-text); }
        @keyframes pulseFavorite { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } }
        .fav-btn-item.favorited svg { animation: pulseFavorite 0.3s ease-in-out; fill: var(--c-favorite); }

        .result-poster { width: 80px; height: 120px; border-radius: 8px; margin-right: 15px; object-fit: cover; background-color: var(--c-background); flex-shrink: 0; }
        .result-info { flex: 1; min-width: 0; display: flex; flex-direction: column; }
        .result-title { font-size: 1.1em; font-weight: 700; color: var(--c-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 50px; }
        .result-meta { font-size: 0.85em; color: var(--c-secondary); margin-top: 4px; display: flex; align-items: center; }
        .result-meta .star-icon { color: #ffc107; margin-right: 4px; }
        .result-overview { font-size: 0.9em; line-height: 1.5; margin-top: 8px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; padding-right: 50px; }

        .search-message, .search-spinner { text-align: center; padding: 20px; color: var(--c-secondary); }
        .search-spinner { border: 4px solid var(--c-surface); border-top: 4px solid var(--c-primary); border-radius: 50%; width: 30px; height: 30px; animation: spin 1s linear infinite; margin: 20px auto; }
        @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }

        #trailer-modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.8); z-index: 2147483647; justify-content: center; align-items: center; }
        #trailer-modal-content { position: relative; width: 90%; max-width: 800px; aspect-ratio: 16 / 9; background-color: black; }
        #trailer-modal-close { position: absolute; top: -30px; right: 0; background: none; border: none; font-size: 2em; color: white; cursor: pointer; }
        #trailer-iframe { width: 100%; height: 100%; border: none; }
        #details-panel { padding: 0; }
        .details-header { position: relative; padding: 20px; color: white; min-height: 200px; display: flex; align-items: flex-end; background-size: cover; background-position: center; }
        .details-header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(to top, rgba(33, 33, 33, 1) 10%, rgba(33, 33, 33, 0.7) 50%, rgba(33, 33, 33, 0.3) 100%); }
        .details-header-content { position: relative; z-index: 2; display: flex; gap: 20px; width: 100%; align-items: flex-end;}
        .details-poster { width: 100px; height: 150px; border-radius: 8px; object-fit: cover; flex-shrink: 0; border: 2px solid white; }
        .details-title-section { flex-grow: 1; }
        .details-title { font-size: 1.6em; margin: 0 0 5px 0; font-weight: 700; line-height: 1.2; color: white;}
        .details-original-title { font-size: 0.9em; font-style: italic; opacity: 0.8; color: white;}
        .details-rating { display: flex; align-items: center; gap: 5px; margin-top: 10px; font-size: 1.1em; font-weight: 500; color: white;}
        .details-rating .star-icon { color: #ffc107; }
        .details-body { padding: 20px; background-color: var(--c-light-bg);}
        .details-section-title { font-size: 1.2em; font-weight: 700; color: var(--c-text-dark); margin: 20px 0 10px 0; padding-bottom: 5px; border-bottom: 1px solid #dcdcdc; }
        .details-section-title:first-child { margin-top: 0; }
        .details-overview, .details-body p { line-height: 1.6; font-size: 0.9em; color: var(--c-text-dark);}
        .cast-list { display: flex; overflow-x: auto; gap: 15px; padding-bottom: 10px; }
        .cast-list::-webkit-scrollbar { height: 5px; }
        .cast-list::-webkit-scrollbar-track { background: #e0e0e0; }
        .cast-list::-webkit-scrollbar-thumb { background-color: var(--c-tertiary); border-radius: 10px; }
        .cast-member { text-align: center; width: 80px; flex-shrink: 0; }
        .cast-photo { width: 70px; height: 70px; border-radius: 50%; object-fit: cover; background-color: #eee; margin: 0 auto 5px; border: 2px solid #ddd; }
        .cast-name { font-size: 0.8em; font-weight: 500; color: var(--c-text-dark);}
        .cast-character { font-size: 0.75em; color: #666; }
        .social-links { display: flex; gap: 15px; align-items: center; }
        .social-link svg { width: 24px; height: 24px; fill: var(--c-text-dark); transition: fill 0.2s, transform 0.2s; }
        .social-link:hover svg { fill: var(--c-primary); transform: scale(1.1); }
        .result-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px;}
        .result-actions button, .result-actions a { font-size: 0.75em; font-weight: 500; color: var(--c-text); background-color: var(--c-border); border: 1px solid var(--c-surface); padding: 4px 10px; border-radius: 15px; cursor: pointer; transition: all 0.2s ease; display: inline-block; text-align: center; }
        .result-actions button:hover, .result-actions a:hover { background-color: var(--c-primary); border-color: var(--c-primary); color: var(--c-text-dark); }

        #torrents-container { margin-top: 20px; }
        .torrent-list { display: flex; flex-direction: column; gap: 10px; }
        .torrent-item { display: flex; justify-content: space-between; align-items: center; padding: 10px; background-color: #f0f0f0; border-radius: 6px; border-left: 4px solid var(--c-primary); }
        .torrent-item.hidden { display: none; }
        .torrent-quality { font-weight: 700; font-size: 0.9em; color: var(--c-text-dark); max-width: 250px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; }
        .torrent-info { font-size: 0.8em; color: #555; }
        .torrent-action-btn { font-size: 0.8em; font-weight: 700; color: white; background-color: var(--c-primary); padding: 6px 12px; border-radius: 15px; text-decoration: none; transition: background-color 0.2s; white-space: nowrap; }
        .torrent-action-btn:hover { background-color: #8c754e; }
        .torrent-action-btn:disabled { background-color: var(--c-success); cursor: default; }
        .ver-mais-btn {
            font-size: 0.85em; font-weight: 700; color: var(--c-text-dark);
            background-color: #e0e0e0; padding: 8px 15px; border-radius: 20px;
            text-decoration: none; transition: background-color 0.2s;
            margin-top: 10px; text-align: center; width: 100%;
        }
        .ver-mais-btn:hover { background-color: #cccccc; }
        .brazil-flag { margin-left: 8px; font-size: 1.2em; }

        #pagination-controls { display: flex; justify-content: center; align-items: center; gap: 15px; margin-top: 15px; }
        .page-btn { font-size: 0.85em; background-color: var(--c-surface); padding: 8px 15px; border-radius: 20px; }
        .page-info { font-size: 0.9em; font-weight: 500; }
    `;
    const styleSheet = document.createElement('style');
    styleSheet.innerText = styles;
    shadowRoot.appendChild(styleSheet);


    // --- ESTRUTURA HTML ---
    const appContainer = document.createElement('div');
    appContainer.innerHTML = `
        <div id="smart-search-container">
            <div id="smart-search-header">
                 <button id="back-btn" class="header-btn" title="Voltar">
                    <svg viewBox="0 0 24 24"><path fill="currentColor" d="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z"></path></svg>
                 </button>
                 <button id="home-btn" class="header-btn" title="Início">
                    <svg viewBox="0 0 24 24"><path fill="currentColor" d="M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z"></path></svg>
                 </button>
                <div id="search-input-wrapper">
                    <input id="smart-search-input" type="text" placeholder="Buscar Filmes e Séries...">
                    <input id="year-filter-input" type="number" placeholder="Ano" min="1900" max="2099">
                </div>
                <button id="favorites-btn" class="header-btn" title="Favoritos">
                     <svg viewBox="0 0 24 24"><path fill="currentColor" d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"></path></svg>
                </button>
            </div>
            <div id="panel-container">
                <div id="smart-search-results" class="panel active"></div>
                <div id="favorites-panel" class="panel"></div>
                <div id="details-panel" class="panel"></div>
            </div>
        </div>
        <div id="trailer-modal-overlay">
            <div id="trailer-modal-content">
                <button id="trailer-modal-close">&times;</button>
                <iframe id="trailer-iframe" allow="autoplay; encrypted-media" allowfullscreen></iframe>
            </div>
        </div>
    `;
    shadowRoot.appendChild(appContainer);

    // --- VARIÁVEIS GLOBAIS E ELEMENTOS DO DOM (referenciando o Shadow DOM) ---
    const searchBar = shadowRoot.getElementById('smart-search-container');
    const searchInput = shadowRoot.getElementById('smart-search-input');
    const yearFilterInput = shadowRoot.getElementById('year-filter-input');
    const resultsDiv = shadowRoot.getElementById('smart-search-results');
    const favoritesPanel = shadowRoot.getElementById('favorites-panel');
    const detailsPanel = shadowRoot.getElementById('details-panel');
    const favoritesBtn = shadowRoot.getElementById('favorites-btn');
    const homeBtn = shadowRoot.getElementById('home-btn');
    const backBtn = shadowRoot.getElementById('back-btn');
    const trailerModal = shadowRoot.getElementById('trailer-modal-overlay');
    const closeModalBtn = shadowRoot.getElementById('trailer-modal-close');

    let isBarVisible = false;
    let favorites = [];
    let viewHistory = ['home'];
    let homeViewCache = { releases: [], top: [], topSeries: [] };
    let currentHomePage = { view: 'releases', page: 1 };
    const ITEMS_PER_PAGE = 4;
    const socialSVGs = { facebook: `<svg viewBox="0 0 24 24"><path d="M12 2.04C6.5 2.04 2 6.53 2 12s4.5 9.96 10 9.96c5.5 0 10-4.46 10-9.96S17.5 2.04 12 2.04zm3.5 6.74h-2.1c-.5 0-.6.4-.6 1v1.36h2.7l-.4 2.1H12.8V19h-2.8v-5.76H8v-2.1h2V9.8c0-1.7 1.1-2.8 2.7-2.8h2v2.1z"/></svg>`, twitter: `<svg viewBox="0 0 24 24"><path d="M22.46 6c-.77.35-1.6.58-2.46.67.88-.53 1.56-1.37 1.88-2.38-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29 0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15 0 1.49.75 2.81 1.91 3.56-.71 0-1.37-.22-1.95-.55v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07 4.28 4.28 0 0 0 4 2.98 8.52 8.52 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21c7.34 0 11.35-6.08 11.35-11.35 0-.17 0-.34-.01-.51.78-.57 1.45-1.28 1.99-2.08z"/></svg>`, instagram: `<svg viewBox="0 0 24 24"><path d="M7.8 2h8.4C19.4 2 22 4.6 22 7.8v8.4a5.8 5.8 0 0 1-5.8 5.8H7.8C4.6 22 2 19.4 2 16.2V7.8A5.8 5.8 0 0 1 7.8 2m-.2 2A3.6 3.6 0 0 0 4 7.6v8.8A3.6 3.6 0 0 0 7.6 20h8.8A3.6 3.6 0 0 0 20 16.4V7.6A3.6 3.6 0 0 0 16.4 4H7.6m9.65 1.5a1.25 1.25 0 0 1 1.25 1.25A1.25 1.25 0 0 1 17.25 8 1.25 1.25 0 0 1 16 6.75a1.25 1.25 0 0 1 1.25-1.25M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3z"/></svg>` };
    let originalBodyOverflow;

    // --- ATIVAÇÃO E CONTROLES GERAIS ---
    document.addEventListener('keydown', e => {
        if (e.ctrlKey && e.key === '1') {
            e.preventDefault();
            isBarVisible = !isBarVisible;
            searchBar.style.display = isBarVisible ? 'flex' : 'none';
            if (isBarVisible) {
                searchInput.focus();
                if(!resultsDiv.innerHTML.trim()) {
                     renderHomePage();
                }
            }
        }
    });

    searchBar.addEventListener('mouseover', () => {
        originalBodyOverflow = document.body.style.overflow;
        document.body.style.overflow = 'hidden';
    });
    searchBar.addEventListener('mouseout', () => {
        document.body.style.overflow = originalBodyOverflow;
    });

    closeModalBtn.addEventListener('click', hideTrailer);
    trailerModal.addEventListener('click', e => { if (e.target === trailerModal) hideTrailer(); });

    homeBtn.addEventListener('click', () => {
        renderHomePage();
        showPanel('smart-search-results');
    });

    backBtn.addEventListener('click', () => {
        if(viewHistory.length <= 1) return;
        viewHistory.pop();
        const previousView = viewHistory[viewHistory.length - 1] || 'home';
        const panelId = previousView.includes('details') ? 'details-panel'
                      : (previousView === 'favorites' ? 'favorites-panel'
                      : 'smart-search-results');
        showPanel(panelId, false);
    });

    [resultsDiv, favoritesPanel].forEach(panel => {
        panel.addEventListener('click', e => {
            const favButton = e.target.closest('.fav-btn-item');
            if (favButton) {
                e.stopPropagation();
                const itemData = JSON.parse(decodeURIComponent(favButton.dataset.item));
                toggleFavorite(itemData);
                return;
            }

            const movieItem = e.target.closest('.search-result-item.movie-item');
            if (movieItem) {
                const { id, type } = movieItem.dataset;
                renderDetailsView(id, type);
            }
        });
    });

    detailsPanel.addEventListener('click', e => {
        const trailerBtn = e.target.closest('.trailer-btn');
        if (trailerBtn) {
            e.stopPropagation();
            showTrailer(trailerBtn.dataset.key);
            return;
        }

        const copyBtn = e.target.closest('.torrent-copy-btn');
        if (copyBtn && !copyBtn.disabled) {
            const magnetLink = copyBtn.dataset.magnetLink;
            const textArea = document.createElement('textarea');
            textArea.value = magnetLink;

            textArea.style.position = 'fixed';
            textArea.style.top = '-9999px';
            textArea.style.left = '-9999px';

            shadowRoot.appendChild(textArea);
            textArea.focus();
            textArea.select();

            try {
                document.execCommand('copy');
                copyBtn.textContent = 'Copiado!';
                copyBtn.disabled = true;
                setTimeout(() => {
                    copyBtn.textContent = 'Copiar';
                    copyBtn.disabled = false;
                }, 2000);
            } catch (err) {
                console.error('Falha ao copiar o link magnético: ', err);
                copyBtn.textContent = 'Erro!';
                 setTimeout(() => {
                    copyBtn.textContent = 'Copiar';
                    copyBtn.disabled = false;
                }, 2000);
            }
            shadowRoot.removeChild(textArea);
        }
    });


    favoritesBtn.addEventListener('click', () => {
        showPanel('favorites-panel');
        renderFavoritesPanel();
    });

    function handleSearch() {
        const query = searchInput.value.trim();
        const year = yearFilterInput.value.trim();
        if (query) {
            performSearch(query, year);
        } else {
            renderHomePage();
        }
    }

    searchInput.addEventListener('keyup', e => {
        if (e.key === 'Enter') handleSearch();
    });
    yearFilterInput.addEventListener('keyup', e => {
        if (e.key === 'Enter') handleSearch();
    });

    function showPanel(panelId, pushToHistory = true) {
        shadowRoot.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
        shadowRoot.getElementById(panelId).classList.add('active');

        let currentView = 'home';
        if (panelId === 'details-panel') currentView = `details-${detailsPanel.dataset.id}`;
        else if (panelId === 'favorites-panel') currentView = 'favorites';
        else if (searchInput.value.trim()) currentView = `search-${searchInput.value.trim()}`;

        if (pushToHistory && viewHistory[viewHistory.length - 1] !== currentView) {
            viewHistory.push(currentView);
        }
        backBtn.style.display = viewHistory.length > 1 ? 'flex' : 'none';
    }


     // --- LÓGICA DE RENDERIZAÇÃO DE CONTEÚDO ---
    async function renderHomePage() {
        resultsDiv.innerHTML = `<div class="search-spinner"></div>`;
        const recentSearches = await GM_getValue('recentSearches', []);

        let recentSearchesHTML = '';
        if (recentSearches.length > 0) {
            recentSearchesHTML = `
                <div class="section-title">
                    <span>Buscas Recentes</span>
                    <button id="clear-recents-btn" title="Limpar buscas recentes">Apagar</button>
                </div>
                <div id="recent-searches-list">
                    ${recentSearches.map(term => `<button class="recent-search-tag" data-term="${term}">${term}</button>`).join('')}
                </div>`;
        }

        resultsDiv.innerHTML = `
            ${recentSearchesHTML}
            <div id="home-nav">
                <button class="home-nav-btn ${currentHomePage.view === 'releases' ? 'active' : ''}" data-view="releases">Lançamentos</button>
                <button class="home-nav-btn ${currentHomePage.view === 'top' ? 'active' : ''}" data-view="top">Top 10 Filmes</button>
                <button class="home-nav-btn ${currentHomePage.view === 'topSeries' ? 'active' : ''}" data-view="topSeries">Top 10 Séries</button>
            </div>
            <div id="movie-list-container"></div>
            <div id="pagination-controls"></div>
        `;

        await renderHomeSubPage();

        resultsDiv.querySelectorAll('.home-nav-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                currentHomePage.view = btn.dataset.view;
                currentHomePage.page = 1;
                renderHomeSubPage();
            });
        });

        resultsDiv.querySelectorAll('.recent-search-tag').forEach(tag => {
            tag.onclick = () => {
                searchInput.value = tag.dataset.term;
                yearFilterInput.value = '';
                performSearch(tag.dataset.term);
            };
        });

        const clearBtn = resultsDiv.querySelector('#clear-recents-btn');
        if (clearBtn) {
            clearBtn.addEventListener('click', async () => {
                await GM_setValue('recentSearches', []);
                renderHomePage();
            });
        }
    }

    async function renderHomeSubPage() {
        const listContainer = shadowRoot.getElementById('movie-list-container');
        const paginationContainer = shadowRoot.getElementById('pagination-controls');
        listContainer.innerHTML = `<div class="search-spinner"></div>`;
        paginationContainer.innerHTML = '';

        shadowRoot.querySelectorAll('#home-nav .home-nav-btn').forEach(btn => {
            btn.classList.toggle('active', btn.dataset.view === currentHomePage.view);
        });

        if (currentHomePage.view === 'releases') {
            if (homeViewCache.releases.length === 0) {
                const data = await tmdbRequest('/movie/upcoming', '', 'pt-BR');
                homeViewCache.releases = data.results || [];
            }
            const itemsToDisplay = paginate(homeViewCache.releases, ITEMS_PER_PAGE);
            listContainer.innerHTML = '';
            itemsToDisplay.forEach(item => renderItem(item, listContainer));
            renderPaginationControls(homeViewCache.releases.length, resultsDiv, renderHomeSubPage, ITEMS_PER_PAGE);
        } else if (currentHomePage.view === 'top') {
            if (homeViewCache.top.length === 0) {
                const data = await tmdbRequest('/movie/top_rated', '', 'pt-BR');
                homeViewCache.top = data.results || [];
            }
            const itemsToDisplay = paginate(homeViewCache.top, 10);
            listContainer.innerHTML = '';
            itemsToDisplay.forEach(item => renderItem(item, listContainer));
            renderPaginationControls(homeViewCache.top.length, resultsDiv, renderHomeSubPage, 10);
        } else if (currentHomePage.view === 'topSeries') {
            if (homeViewCache.topSeries.length === 0) {
                const data = await tmdbRequest('/tv/top_rated', '', 'pt-BR');
                homeViewCache.topSeries = data.results || [];
            }
            const itemsToDisplay = paginate(homeViewCache.topSeries, 10);
            listContainer.innerHTML = '';
            itemsToDisplay.forEach(item => renderItem(item, listContainer));
            renderPaginationControls(homeViewCache.topSeries.length, resultsDiv, renderHomeSubPage, 10);
        }
    }

    function paginate(list, itemsPerPage) {
        const startIndex = (currentHomePage.page - 1) * itemsPerPage;
        const endIndex = startIndex + itemsPerPage;
        return list.slice(startIndex, endIndex);
    }

    function renderPaginationControls(totalItems, container, pageChangeCallback, itemsPerPage) {
        const paginationContainer = container.querySelector('#pagination-controls');
        paginationContainer.innerHTML = '';
        const totalPages = Math.ceil(totalItems / itemsPerPage);

        if (totalPages <= 1) return;

        const prevBtn = document.createElement('button');
        prevBtn.textContent = 'Anterior';
        prevBtn.className = 'page-btn';
        prevBtn.disabled = currentHomePage.page === 1;
        prevBtn.addEventListener('click', () => {
            if (currentHomePage.page > 1) {
                currentHomePage.page--;
                pageChangeCallback();
            }
        });

        const pageInfo = document.createElement('span');
        pageInfo.className = 'page-info';
        pageInfo.textContent = `Página ${currentHomePage.page} de ${totalPages}`;

        const nextBtn = document.createElement('button');
        nextBtn.textContent = 'Próximo';
        nextBtn.className = 'page-btn';
        nextBtn.disabled = currentHomePage.page === totalPages;
        nextBtn.addEventListener('click', () => {
            if (currentHomePage.page < totalPages) {
                currentHomePage.page++;
                pageChangeCallback();
            }
        });

        paginationContainer.appendChild(prevBtn);
        paginationContainer.appendChild(pageInfo);
        paginationContainer.appendChild(nextBtn);
    }


    // --- LÓGICA DE BUSCA ---
    async function performSearch(query, year = null, save = true) {
        if (save) await saveSearchTerm(query);
        resultsDiv.innerHTML = `<div class="search-spinner"></div>`;
        const movieResults = await performMovieSearch(query, year);
        showPanel('smart-search-results');
        renderUnifiedResults({ movieResults });
    }

    async function performMovieSearch(query, year) {
        const yearParam = year ? `&year=${year}` : '';
        const initialResults = await tmdbRequest(`/search/multi`, `&query=${encodeURIComponent(query)}${yearParam}`);
        if (!initialResults || !initialResults.results) return [];
        const validResults = initialResults.results.filter(item => (item.media_type === 'movie' || item.media_type === 'tv') && item.poster_path).slice(0, 10);
        if (validResults.length === 0) return [];

        const detailPromises = validResults.map(async (item) => {
            try {
                const details = await tmdbRequest(`/${item.media_type}/${item.id}`, `&append_to_response=videos`, 'pt-BR');
                if (details) {
                    details.media_type = item.media_type;
                    return details;
                }
            } catch (error) { console.error(`Erro ao buscar detalhes para ${item.id}:`, error); }
            return null;
        });
        return (await Promise.all(detailPromises)).filter(Boolean);
    }

    function renderUnifiedResults(results) {
        resultsDiv.innerHTML = '';
        let foundResults = false;

        if (results.movieResults && results.movieResults.length > 0) {
            foundResults = true;
            resultsDiv.innerHTML += `<h3 class="section-title"><span>Resultados</span></h3>`;
            results.movieResults.forEach(item => renderItem(item, resultsDiv));
        }

        if (!foundResults) {
            resultsDiv.innerHTML = `<div class="search-message">Nenhum resultado encontrado.</div>`;
        }
    }

    function renderItem(item, container) {
       if (!item.media_type && (item.title || item.name)) {
           item.media_type = item.title ? 'movie' : 'tv';
       }

       if (item.media_type === 'movie' || item.media_type === 'tv') {
            renderMovieItem(item, container);
       }
    }

    function renderMovieItem(item, container) {
        const title = item.title || item.name;
        const releaseDate = item.release_date || item.first_air_date;
        const year = releaseDate ? new Date(releaseDate).getFullYear() : 'N/D';
        const posterPath = item.poster_path ? `https://image.tmdb.org/t/p/w200${item.poster_path}` : 'https://placehold.co/80x120/5a6e4e/f0f0f0?text=Capa';
        const overview = item.overview || "Sinopse não disponível.";
        const rating = item.vote_average ? item.vote_average.toFixed(1) : "N/D";
        const isFav = isFavorited(item);
        const itemData = encodeURIComponent(JSON.stringify({id: item.id, title, name: item.name, poster_path: item.poster_path, media_type: item.media_type, overview, vote_average: item.vote_average, release_date: item.release_date, first_air_date: item.first_air_date, type: item.media_type}));

        const itemDiv = document.createElement('div');
        itemDiv.className = `search-result-item movie-item ${isFav ? 'favorited-item' : ''}`;
        itemDiv.dataset.id = item.id;
        itemDiv.dataset.type = item.media_type;
        itemDiv.innerHTML = `
            <img src="${posterPath}" alt="Capa de ${title}" class="result-poster">
            <div class="result-info">
                <div>
                    <h3 class="result-title">${title}</h3>
                    <div class="result-meta"><span>${year}</span><span class="star-icon" style="margin-left: 10px;">⭐</span><span>${rating}</span></div>
                    <p class="result-overview">${overview}</p>
                </div>
            </div>
            <button class="fav-btn-item ${isFav ? 'favorited' : ''}" title="Adicionar/Remover dos Favoritos" data-item="${itemData}">
                <svg viewBox="0 0 24 24"><path fill="currentColor" d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"></path></svg>
            </button>
        `;
        container.appendChild(itemDiv);
    }


    // --- LÓGICA DE DETALHES, FAVORITOS E UTILITÁRIOS ---
    async function renderDetailsView(itemId, mediaType) {
        detailsPanel.dataset.id = `${mediaType}-${itemId}`;
        showPanel('details-panel');
        detailsPanel.innerHTML = `<div class="search-spinner"></div>`;

        try {
            const data = await tmdbRequest(`/${mediaType}/${itemId}`, `&append_to_response=credits,external_ids,videos`, 'pt-BR');
            if (!data) throw new Error("Não foi possível obter os dados da API");

            const backdropUrl = data.backdrop_path ? `https://image.tmdb.org/t/p/w500${data.backdrop_path}` : '';
            const posterUrl = data.poster_path ? `https://image.tmdb.org/t/p/w200${data.poster_path}` : 'https://placehold.co/100x150/5a6e4e/f0f0f0?text=Capa';
            const title = data.title || data.name;
            const originalTitle = data.original_title || data.original_name;
            const rating = data.vote_average ? data.vote_average.toFixed(1) : "N/D";
            const imdbId = data.external_ids?.imdb_id;

            let creatorsHTML = 'Não informado';
            if (mediaType === 'tv' && data.created_by?.length > 0) {
                creatorsHTML = data.created_by.map(c => c.name).join(', ');
            } else if (mediaType === 'movie' && data.credits?.crew) {
                const director = data.credits.crew.find(c => c.job === 'Director');
                if (director) creatorsHTML = director.name;
            }

            const cast = data.credits?.cast?.slice(0, 10) || [];
            const castHTML = cast.map(member => `
                <div class="cast-member">
                    <img src="${member.profile_path ? `https://image.tmdb.org/t/p/w200${member.profile_path}` : 'https://placehold.co/70x70/ccc/fff?text=?'}" class="cast-photo" alt="${member.name}">
                    <div class="cast-name">${member.name}</div>
                    <div class="cast-character">${member.character}</div>
                </div>
            `).join('');

            const social = data.external_ids || {};
            let socialHTML = ['instagram', 'twitter', 'facebook']
              .map(platform => ({ platform, id: social[`${platform}_id`] }))
              .filter(p => p.id)
              .map(p => `<a href="https://www.${p.platform}.com/${p.id}" target="_blank" class="social-link" title="${p.platform}" rel="noopener noreferrer">${socialSVGs[p.platform]}</a>`)
              .join('');

            if (!socialHTML) socialHTML = 'Nenhuma rede social oficial encontrada.';

            const trailer = findBestTrailer(data.videos);
            const trailerHTML = trailer ? `<button class="trailer-btn" data-key="${trailer.key}">Assistir Trailer</button>` : '';

            detailsPanel.innerHTML = `
                <div class="details-header" style="background-image: url('${backdropUrl}')">
                    <div class="details-header-content">
                        <img src="${posterUrl}" class="details-poster" alt="Pôster de ${title}">
                        <div class="details-title-section">
                            <h2 class="details-title">${title}</h2>
                            <p class="details-original-title">Título Original: ${originalTitle}</p>
                            <div class="details-rating"><span class="star-icon">⭐</span> ${rating} / 10</div>
                            <div class="result-actions" style="margin-top: 10px;">${trailerHTML}</div>
                        </div>
                    </div>
                </div>
                <div class="details-body">
                    <h3 class="details-section-title">Sinopse Completa</h3>
                    <p class="details-overview">${data.overview || "Sinopse não disponível."}</p>
                    <div id="torrents-container"></div>
                    <h3 class="details-section-title">Criação</h3>
                    <p>${creatorsHTML}</p>
                    <h3 class="details-section-title">Elenco Principal</h3>
                    <div class="cast-list">${castHTML || 'Elenco não informado.'}</div>
                    <h3 class="details-section-title">Redes Sociais Oficiais</h3>
                    <div class="social-links">${socialHTML}</div>
                </div>
            `;

            const torrentsContainer = shadowRoot.querySelector('#torrents-container');
            torrentsContainer.innerHTML = `<h3 class="details-section-title">Downloads (Torrents)</h3><div id="aggregated-torrents"></div><div id="yts-torrents" style="margin-top:15px;"></div>`;

            // Prioriza buscas brasileiras
            if (mediaType === 'movie') {
                fetchAndRenderAggregatedTorrents(originalTitle, 'movie');
                fetchAndRenderYTSTorrents(imdbId, title);
            } else if (mediaType === 'tv') {
                 fetchAndRenderAggregatedTorrents(originalTitle, 'tv');
            }

        } catch (error) {
            console.error("Erro ao carregar detalhes:", error);
            detailsPanel.innerHTML = `<p class="search-message">Não foi possível carregar os detalhes.</p>`;
        }
    }

    async function fetchAndRenderYTSTorrents(imdbId, title) {
        const ytsContainer = shadowRoot.querySelector('#yts-torrents');
        if (!imdbId) {
            ytsContainer.innerHTML = '';
            return;
        }

        ytsContainer.innerHTML = `<p style="color: var(--c-text-dark); font-size: 0.9em; font-weight: 500;">Buscando em YTS (Áudio Original)...</p><div class="search-spinner" style="margin: 10px 0;"></div>`;

        try {
            const ytsData = await apiRequest(`https://yts.mx/api/v2/list_movies.json?query_term=${imdbId}`);
            if (ytsData && ytsData.data.movie_count > 0 && ytsData.data.movies[0].torrents) {
                const torrents = ytsData.data.movies[0].torrents;
                const encodedTitle = encodeURIComponent(title);
                const trackers = '&tr=udp://open.demonii.com:1337/announce&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.coppersurfer.tk:6969&tr=udp://glotorrents.pw:6969/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://torrent.gresille.org:80/announce&tr=udp://p4p.arenabg.com:1337&tr=udp://tracker.leechers-paradise.org:6969';

                const torrentList = document.createElement('div');
                torrentList.className = 'torrent-list';

                torrents.forEach(t => {
                    const magnetLink = `magnet:?xt=urn:btih:${t.hash}&dn=${encodedTitle}${trackers}`;
                    const torrentItem = document.createElement('div');
                    torrentItem.className = 'torrent-item';
                    torrentItem.innerHTML = `
                        <div title="YTS - ${t.quality} (${t.type})">
                            <div class="torrent-quality">YTS - ${t.quality} (${t.type})</div>
                            <div class="torrent-info">Tamanho: ${t.size} / Seeds: ${t.seeds} / Peers: ${t.peers}</div>
                        </div>
                        <button class="torrent-action-btn torrent-copy-btn" data-magnet-link="${magnetLink}">Copiar</button>
                    `;
                    torrentList.appendChild(torrentItem);
                });

                ytsContainer.innerHTML = '';
                ytsContainer.appendChild(torrentList);

            } else {
                 ytsContainer.innerHTML = `<p style="color: var(--c-text-dark); font-size: 0.9em;">Nenhum torrent encontrado em YTS para este filme.</p>`;
            }
        } catch (error) {
            console.error("Erro ao buscar torrents YTS:", error);
            ytsContainer.innerHTML = `<p style="color: var(--c-text-dark); font-size: 0.9em;">Não foi possível buscar torrents em YTS.</p>`;
        }
    }

    function isBrazilianTorrent(name) {
        const lowerName = name.toLowerCase();
        const keywords = ['dublado', 'dual audio', 'nacional', 'pt-br', 'portugues', 'legendado'];
        return keywords.some(keyword => lowerName.includes(keyword));
    }

    async function fetchAndRenderAggregatedTorrents(originalTitle, type) {
        const container = shadowRoot.querySelector('#aggregated-torrents');
        const queries = [ type === 'movie' ? `${originalTitle} dual audio` : `${originalTitle} dublado`, originalTitle ];

        container.innerHTML = `<p style="color: var(--c-text-dark); font-size: 0.9em; font-weight: 500;">Buscando em fontes BR e Internacionais...</p><div class="search-spinner" style="margin: 10px 0;"></div>`;

        try {
            const searchPromises = queries.map(query => apiRequest(`https://apibay.org/q.php?q=${encodeURIComponent(query)}&cat=200`));
            const resultsArrays = await Promise.all(searchPromises);
            const combinedResults = [].concat(...resultsArrays);
            const uniqueResults = [];
            const seenHashes = new Set();

            for (const result of combinedResults) {
                if (result.name && result.name !== 'No results returned' && !seenHashes.has(result.info_hash)) {
                    uniqueResults.push(result);
                    seenHashes.add(result.info_hash);
                }
            }
            uniqueResults.sort((a, b) => parseInt(b.seeders, 10) - parseInt(a.seeders, 10));

            if (uniqueResults.length > 0) {
                const trackers = '&tr=udp://open.demonii.com:1337/announce&tr=udp://tracker.openbittorrent.com:80&tr=udp://tracker.coppersurfer.tk:6969&tr=udp://glotorrents.pw:6969/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://torrent.gresille.org:80/announce&tr=udp://p4p.arenabg.com:1337&tr=udp://tracker.leechers-paradise.org:6969';

                const torrentList = document.createElement('div');
                torrentList.className = 'torrent-list';

                uniqueResults.forEach((t, index) => {
                    const isBR = isBrazilianTorrent(t.name);
                    const flag = isBR ? `<span class="brazil-flag">🇧🇷</span>` : '';
                    const magnetLink = `magnet:?xt=urn:btih:${t.info_hash}&dn=${encodeURIComponent(t.name)}${trackers}`;
                    const torrentItem = document.createElement('div');
                    torrentItem.className = 'torrent-item';
                     if (index >= 5) {
                        torrentItem.classList.add('hidden');
                    }
                    torrentItem.innerHTML = `
                        <div title="${t.name}">
                            <div class="torrent-quality">${t.name}${flag}</div>
                            <div class="torrent-info">Tamanho: ${(t.size / 1073741824).toFixed(2)} GB / Seeds: ${t.seeders} / Peers: ${t.leechers}</div>
                        </div>
                        <button class="torrent-action-btn torrent-copy-btn" data-magnet-link="${magnetLink}">Copiar</button>
                    `;
                    torrentList.appendChild(torrentItem);
                });

                container.innerHTML = '';
                container.appendChild(torrentList);

                if (uniqueResults.length > 5) {
                    const verMaisBtn = document.createElement('button');
                    verMaisBtn.className = 'ver-mais-btn';
                    verMaisBtn.textContent = `Ver mais ${uniqueResults.length - 5} resultados`;
                    verMaisBtn.onclick = function() {
                        torrentList.querySelectorAll('.torrent-item.hidden').forEach(item => item.classList.remove('hidden'));
                        verMaisBtn.remove();
                    };
                    container.appendChild(verMaisBtn);
                }
            } else {
                container.innerHTML = `<p style="color: var(--c-text-dark); font-size: 0.9em;">Nenhum torrent encontrado em fontes adicionais.</p>`;
            }
        } catch (error) {
            console.error("Erro ao buscar torrents agregados:", error);
            container.innerHTML = `<p style="color: var(--c-text-dark); font-size: 0.9em;">Não foi possível buscar em fontes adicionais.</p>`;
        }
    }

    async function saveSearchTerm(term) {
        let searches = await GM_getValue(`recentSearches`, []);
        searches = searches.filter(s => s.toLowerCase() !== term.toLowerCase());
        searches.unshift(term);
        if (searches.length > 8) searches.length = 8;
        await GM_setValue(`recentSearches`, searches);
    }

    function findBestTrailer(videos) {
        if (!videos?.results?.length) return null;
        const allTrailers = videos.results.filter(v => v.type === "Trailer" && v.site === "YouTube");
        return allTrailers.find(v => v.iso_639_1 === 'pt') || allTrailers.find(v => v.iso_639_1 === 'en') || allTrailers[0];
    }

    async function loadFavorites() { favorites = await GM_getValue('favoritesList', []); }
    async function saveFavorites() { await GM_setValue('favoritesList', favorites); }

    async function toggleFavorite(itemData) {
        const uniqueId = `${itemData.type}-${itemData.id}`;
        const favIndex = favorites.findIndex(fav => `${fav.type}-${fav.id}` === uniqueId);

        if (favIndex > -1) {
            favorites.splice(favIndex, 1);
        } else {
            favorites.unshift(itemData);
        }
        await saveFavorites();

        const currentPanel = shadowRoot.querySelector('.panel.active');
        const currentQuery = searchInput.value.trim();

        if (currentPanel.id === 'smart-search-results') {
            if (currentQuery) {
                performSearch(currentQuery, false);
            } else {
                renderHomeSubPage();
            }
        } else if (currentPanel.id === 'favorites-panel') {
            renderFavoritesPanel();
        }
    }

    function isFavorited(item) {
        const uniqueId = `${item.media_type}-${item.id}`;
        return favorites.some(fav => `${fav.type}-${fav.id}` === uniqueId);
    }

    function renderFavoritesPanel() {
        favoritesPanel.innerHTML = '';
        if (favorites.length === 0) {
            favoritesPanel.innerHTML = `<div class="search-message">Sua lista de favoritos está vazia.</div>`;
            return;
        }
        favoritesPanel.innerHTML = `<h3 class="section-title"><span>Meus Favoritos</span></h3>`;
        favorites.forEach(item => renderItem(item, favoritesPanel));
    }

    function showTrailer(youtubeKey) {
        const trailerIframe = shadowRoot.getElementById('trailer-iframe');
        trailerIframe.src = `https://www.youtube.com/embed/${youtubeKey}?autoplay=1&rel=0`;
        trailerModal.style.display = 'flex';
    }

    function hideTrailer() {
        const trailerIframe = shadowRoot.getElementById('trailer-iframe');
        trailerModal.style.display = 'none';
        trailerIframe.src = '';
    }

    function apiRequest(url) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: "GET", url: url,
                onload: resp => {
                    try { resolve(JSON.parse(resp.responseText)); }
                    catch(e) { console.error("Falha na requisição à API para", url, e); reject(e); }
                },
                onerror: reject
            });
        });
    }

    function tmdbRequest(endpoint, params = '', lang = null) {
        const langParam = lang ? `&language=${lang}` : '';
        return apiRequest(`https://api.themoviedb.org/3${endpoint}?api_key=${tmdbApiKey}${langParam}${params}`);
    }

    // --- INICIALIZAÇÃO ---
    loadFavorites();
})();