let trendingBooks = []; let currentHeroIndex = 0; let heroInterval; let availableExtensions = []; window.addEventListener('scroll', () => { const nav = document.getElementById('navbar'); if (window.scrollY > 50) nav.classList.add('scrolled'); else nav.classList.remove('scrolled'); }); const searchInput = document.getElementById('search-input'); const searchResults = document.getElementById('search-results'); let searchTimeout; searchInput.addEventListener('input', (e) => { const query = e.target.value; clearTimeout(searchTimeout); if (query.length < 2) { searchResults.classList.remove('active'); searchResults.innerHTML = ''; searchInput.style.borderRadius = '99px'; return; } searchTimeout = setTimeout(() => { fetchBookSearch(query); }, 300); }); document.addEventListener('click', (e) => { if (!e.target.closest('.search-wrapper')) { searchResults.classList.remove('active'); searchInput.style.borderRadius = '99px'; } }); async function fetchBookSearch(query) { try { let apiUrl = `/api/search/books?q=${encodeURIComponent(query)}`; let extensionName = null; let finalQuery = query; const parts = query.split(':'); if (parts.length >= 2) { const potentialExtension = parts[0].trim().toLowerCase(); const foundExtension = availableExtensions.find(ext => ext.toLowerCase() === potentialExtension); if (foundExtension) { extensionName = foundExtension; finalQuery = parts.slice(1).join(':').trim(); if (finalQuery.length === 0) { renderSearchResults([]); return; } apiUrl = `/api/search/books/${extensionName}?q=${encodeURIComponent(finalQuery)}`; } } const res = await fetch(apiUrl); const data = await res.json(); const resultsWithExtension = data.results.map(book => { if (extensionName) { return { ...book, isExtensionResult: true, extensionName: extensionName }; } return book; }); renderSearchResults(resultsWithExtension || []); } catch (err) { console.error("Search Error:", err); renderSearchResults([]); } } function renderSearchResults(results) { searchResults.innerHTML = ''; if (!results || results.length === 0) { searchResults.innerHTML = '
No results found
'; } else { results.forEach(book => { const title = book.title.english || book.title.romaji || "Unknown"; const img = (book.coverImage && (book.coverImage.medium || book.coverImage.large)) || ''; const rating = Number.isInteger(book.averageScore) ? `${book.averageScore}%` : book.averageScore || 'N/A'; const year = book.seasonYear || (book.startDate ? book.startDate.year : '') || '????'; const format = book.format || 'MANGA'; const item = document.createElement('a'); item.className = 'search-item'; let href; if (book.isExtensionResult) { href = `/book/${book.extensionName}/${book.id}`; } else { href = `/book/${book.id}`; } item.href = href; item.innerHTML = ` ${title}
${title}
${rating} • ${year} • ${format}
`; searchResults.appendChild(item); }); } searchResults.classList.add('active'); searchInput.style.borderRadius = '12px 12px 0 0'; } function scrollCarousel(id, direction) { const container = document.getElementById(id); if(container) { const scrollAmount = container.clientWidth * 0.75; container.scrollBy({ left: direction * scrollAmount, behavior: 'smooth' }); } } async function init() { try { const resExt = await fetch('/api/extensions/book'); const dataExt = await resExt.json(); if (dataExt.extensions) { availableExtensions = dataExt.extensions; console.log("Extensiones disponibles cargadas:", availableExtensions); } const res = await fetch('/api/books/trending'); const data = await res.json(); if (data.results && data.results.length > 0) { trendingBooks = data.results; updateHeroUI(trendingBooks[0]); renderList('trending', trendingBooks); startHeroCycle(); } const resPop = await fetch('/api/books/popular'); const dataPop = await resPop.json(); if (dataPop.results) renderList('popular', dataPop.results); } catch (e) { console.error("Books Error:", e); } } function startHeroCycle() { if(heroInterval) clearInterval(heroInterval); heroInterval = setInterval(() => { if(trendingBooks.length > 0) { currentHeroIndex = (currentHeroIndex + 1) % trendingBooks.length; updateHeroUI(trendingBooks[currentHeroIndex]); } }, 8000); } function updateHeroUI(book) { if(!book) return; const title = book.title.english || book.title.romaji; const desc = book.description || "No description available."; const poster = (book.coverImage && (book.coverImage.extraLarge || book.coverImage.large)) || ''; const banner = book.bannerImage || poster; document.getElementById('hero-title').innerText = title; document.getElementById('hero-desc').innerHTML = desc; document.getElementById('hero-score').innerText = (book.averageScore || '?') + '% Score'; document.getElementById('hero-year').innerText = (book.startDate && book.startDate.year) ? book.startDate.year : '????'; document.getElementById('hero-type').innerText = book.format || 'MANGA'; const heroPoster = document.getElementById('hero-poster'); if(heroPoster) heroPoster.src = poster; const bg = document.getElementById('hero-bg-media'); if(bg) bg.src = banner; const readBtn = document.getElementById('read-btn'); if (readBtn) { readBtn.onclick = () => window.location.href = `/book/${book.id}`; } } function renderList(id, list) { const container = document.getElementById(id); container.innerHTML = ''; list.forEach(book => { const title = book.title.english || book.title.romaji; const cover = book.coverImage ? book.coverImage.large : ''; const score = book.averageScore || '--'; const type = book.format || 'Book'; const el = document.createElement('div'); el.className = 'card'; el.onclick = () => { window.location.href = `/book/${book.id}`; }; el.innerHTML = `

${title}

${score}% • ${type}

`; container.appendChild(el); }); } init();