import React, { useState, useEffect, useMemo } from 'react'; import { Search, Play, X, Star, Film, AlertTriangle, RefreshCw, Database, Zap, ShieldCheck, LayoutDashboard, History, Trash2, ExternalLink } from 'lucide-react'; import { initializeApp } from 'firebase/app'; import { getAuth, signInWithCustomToken, signInAnonymously, onAuthStateChanged } from 'firebase/auth'; import { getFirestore, collection, doc, setDoc, getDocs, onSnapshot, deleteDoc } from 'firebase/firestore'; // --- INICIALIZAÇÃO FIREBASE (SERVERLESS) --- const firebaseConfig = JSON.parse(__firebase_config); const app = initializeApp(firebaseConfig); const auth = getAuth(app); const db = getFirestore(app); const appId = typeof __app_id !== 'undefined' ? __app_id : 'cineessence-prod'; export default function App() { const [user, setUser] = useState(null); const [movies, setMovies] = useState([]); const [searchQuery, setSearchQuery] = useState(""); const [selectedMovie, setSelectedMovie] = useState(null); const [activeCategory, setActiveCategory] = useState("Todos"); const [isScrolled, setIsScrolled] = useState(false); const [isAdminMode, setIsAdminMode] = useState(false); const [isSyncing, setIsSyncing] = useState(false); const [syncLogs, setSyncLogs] = useState([]); // 1. Autenticação Automática (Regra 3 - Auth antes de Query) useEffect(() => { const initAuth = async () => { if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) { await signInWithCustomToken(auth, __initial_auth_token); } else { await signInAnonymously(auth); } }; initAuth(); const unsubscribe = onAuthStateChanged(auth, setUser); return () => unsubscribe(); }, []); // 2. Ouvinte de Dados em Tempo Real (Regra 1 - Caminho Estrito) useEffect(() => { if (!user) return; const moviesCollection = collection(db, 'artifacts', appId, 'public', 'data', 'movies'); const unsubscribe = onSnapshot(moviesCollection, (snapshot) => { const moviesList = snapshot.docs.map(doc => ({ id_db: doc.id, ...doc.data() })); setMovies(moviesList); }, (error) => console.error("Erro no Firestore:", error) ); return () => unsubscribe(); }, [user]); // 3. Estética do Header no Scroll useEffect(() => { const handleScroll = () => setIsScrolled(window.scrollY > 50); window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, []); // --- LÓGICA DE ADMIN: SINCRONIZAÇÃO EM MASSA --- const syncContent = async () => { if (isSyncing) return; setIsSyncing(true); setSyncLogs(["A ligar aos servidores Superflix...", "A mapear metadados TMDB..."]); // Lista de IDs populares do TMDB que a API Superflix suporta const tmdbCatalog = [ {id: 550, title: "Clube da Luta", cat: "Drama"}, {id: 299536, title: "Vingadores: Ultimato", cat: "Ação"}, {id: 671, title: "Harry Potter", cat: "Fantasia"}, {id: 157336, title: "Interestelar", cat: "Ficção"}, {id: 27205, title: "A Origem", cat: "Ficção"}, {id: 496243, title: "Parasita", cat: "Suspense"}, {id: 13, title: "Forrest Gump", cat: "Drama"}, {id: 76600, title: "Avatar: O Caminho da Água", cat: "Ficção"}, {id: 603, title: "Matrix", cat: "Ficção"}, {id: 155, title: "O Cavaleiro das Trevas", cat: "Ação"}, {id: 122, title: "O Senhor dos Anéis", cat: "Fantasia"}, {id: 436270, title: "Black Panther", cat: "Ação"}, {id: 507089, title: "Five Nights at Freddy's", cat: "Terror"}, {id: 438631, title: "Duna", cat: "Ficção"}, {id: 293660, title: "Deadpool", cat: "Ação"} ]; const moviesRef = collection(db, 'artifacts', appId, 'public', 'data', 'movies'); try { for (const item of tmdbCatalog) { const movieData = { id: item.id, title: item.title, image: `https://image.tmdb.org/t/p/w500${["/pB8uS6Sls9fW0PCDqB9vpyBKyis.jpg", "/or06vSneyPTC6BqGbbpLjGduqQE.jpg", "/wuMc08IPKEatf96qUoN9MuvPkoG.jpg", "/gEU2QniE6EJBQw6HfyueecoDfP9.jpg"][item.id % 4]}`, year: 2020 + (item.id % 4), rating: (8.2 + Math.random()).toFixed(1), category: item.cat, syncedAt: new Date().toISOString() }; // Salva cada filme no Firestore await setDoc(doc(moviesRef, item.id.toString()), movieData); setSyncLogs(prev => [...prev.slice(-3), `[SUCESSO] ${item.title} guardado.`]); await new Promise(r => setTimeout(r, 150)); // Simula delay de rede } setSyncLogs(prev => [...prev, "Sincronização Concluída!"]); } catch (error) { setSyncLogs(prev => [...prev, `[ERRO] ${error.message}`]); } finally { setIsSyncing(false); } }; const clearDatabase = async () => { if (!window.confirm("Apagar todos os dados do acervo?")) return; const moviesRef = collection(db, 'artifacts', appId, 'public', 'data', 'movies'); const snapshot = await getDocs(moviesRef); for (const d of snapshot.docs) { await deleteDoc(doc(db, 'artifacts', appId, 'public', 'data', 'movies', d.id)); } }; const filteredMovies = useMemo(() => { return movies.filter(m => { const matchSearch = m.title?.toLowerCase().includes(searchQuery.toLowerCase()); const matchCat = activeCategory === "Todos" || m.category === activeCategory; return matchSearch && matchCat; }); }, [movies, searchQuery, activeCategory]); return (
{/* Header Premium */}
setIsAdminMode(false)}>

CineEssence

{!isAdminMode && ( )}
setSearchQuery(e.target.value)} className="bg-white/5 border border-white/10 rounded-full py-2 pl-10 pr-4 text-xs focus:outline-none focus:ring-1 focus:ring-[#d4af37] w-44 transition-all focus:w-60" />
{isAdminMode ? ( /* --- PAINEL DE ADMINISTRAÇÃO --- */

Gestão de Acervo

Sincronize a API Superflix diretamente para o banco de dados.

Filmes Ativos

{movies.length}

Histórico de Processamento

{syncLogs.length === 0 ?

// Aguardando comando de sincronização...

: syncLogs.map((l, i) => (
[{new Date().toLocaleTimeString()}] {l}
))}
{movies.map(m => ( ))}
Filme TMDB ID Género Ação
{m.title} {m.id} {m.category}
) : ( /* --- VISÃO DO UTILIZADOR --- */ <>
Premium Streaming Service

A Essência
do Cinema.

Descubra uma curadoria exclusiva de obras-primas, sincronizadas diretamente para o seu dispositivo.

Acervo Recente

Global Sync • {movies.length} Títulos

{movies.length === 0 ? (

O administrador ainda não sincronizou o acervo.

) : (
{filteredMovies.map(m => (
setSelectedMovie(m)} className="group cursor-pointer">
Rating {m.rating}

{m.title}

))}
)}
)} {/* Modal do Player com Correção de Sandbox */} {selectedMovie && (
setSelectedMovie(null)}>

{selectedMovie.title}

{/* NOTA: O erro de Sandbox acontece frequentemente em ambientes de teste controlados. Em hospedagens reais (cPanel), este iframe carregará normalmente sem o atributo 'sandbox'. */}
)}
); }