/**
 * episodes.js — YouTube Player
 * Virtual Scroll לסרטוני ערוץ, חיפוש, מיון + מנגנון מניעת כפילויות
 */

const VS_PAGE_SIZE = 60;
let vsState    = null;
let vsObserver = null;

// ─── Helpers ──────────────────────────────────────────────────

/** מפיק מזהה ייחודי ונקי להשוואה (Video ID) */
function getNormalizedId(ep) {
    // עדיפות ל-guid (שבשרת החדש הוא ה-ID), אחרת חילוץ מה-URL
    const vid = ep.guid || (typeof extractYouTubeVideoId === 'function' ? extractYouTubeVideoId(ep.audioUrl) : null);
    return (vid || ep.audioUrl || ep.title || '').toString().trim();
}

// ─── Sort ─────────────────────────────────────────────────────

let currentSort = 'dateDesc';
const SORT_LABELS = {
    dateDesc:     'תאריך (חדש קודם)',
    dateAsc:      'תאריך (ישן קודם)',
    durationDesc: 'זמן (ארוך קודם)',
    durationAsc:  'זמן (קצר קודם)',
};

function durationToSeconds(dur) {
    if (!dur) return 0;
    const parts = dur.split(':').map(Number);
    if (parts.length === 3) return parts[0] * 3600 + parts[1] * 60 + parts[2];
    if (parts.length === 2) return parts[0] * 60 + parts[1];
    return parts[0] || 0;
}

function sortEpisodes(episodes) {
    const arr = [...episodes];
    switch (currentSort) {
        case 'dateAsc':      return arr.sort((a, b) => new Date(a.pubDate) - new Date(b.pubDate));
        case 'durationDesc': return arr.sort((a, b) => durationToSeconds(b.duration) - durationToSeconds(a.duration));
        case 'durationAsc':  return arr.sort((a, b) => durationToSeconds(a.duration) - durationToSeconds(b.duration));
        default:             return arr.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate));
    }
}

function toggleSortMenu() {
    document.getElementById('sortMenu').classList.toggle('hidden');
}

async function applySort(sortKey) {
    currentSort = sortKey;
    document.getElementById('currentSortLabel').textContent = SORT_LABELS[sortKey] || '';
    document.getElementById('sortMenu').classList.add('hidden');
    
    if (!vsState?.channelId) return;
    const { channelId, categoryName, channelTitle, mainImage } = vsState;

    const container = document.getElementById('videosList');
    container.innerHTML = '<div class="col-span-full text-center py-12"><i class="fas fa-spinner fa-spin text-violet-400 text-xl"></i></div>';

    const allData = getChannelEpisodes(channelId, 0, 999999);
    const sorted  = sortEpisodes(allData.episodes);
    renderVideosList(sorted, categoryName, channelTitle, mainImage);
}

// ─── Virtual Scroll ───────────────────────────────────────────

function vsDetachObserver() {
    if (vsObserver) { vsObserver.disconnect(); vsObserver = null; }
    const s = document.getElementById('vs-sentinel');
    if (s) s.remove();
}

function vsAttachObserver() {
    vsDetachObserver();
    const container = document.getElementById('videosList');
    const sentinel  = document.createElement('div');
    sentinel.id        = 'vs-sentinel';
    sentinel.className = 'h-1';
    container.parentElement.appendChild(sentinel);

    vsObserver = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting && vsState && vsState.hasMore && !vsState.loading) {
            loadVideosPage(vsState.channelId, vsState.offset, vsState.categoryName, vsState.channelTitle, vsState.mainImage, false);
        }
    }, { rootMargin: '300px' });
    vsObserver.observe(sentinel);
}

function loadVideosPage(channelId, offset, categoryName, channelTitle, mainImage, isFirst) {
    if (vsState && vsState.loading) return;
    const container = document.getElementById('videosList');

    if (isFirst) {
        vsDetachObserver();
        currentSort = 'dateDesc';
        container.innerHTML = '<div class="col-span-full text-center py-12"><i class="fas fa-spinner fa-spin text-violet-400 text-xl"></i></div>';
        
        // --- תוספת: שולפים את כל הסרטונים פעם אחת לזיכרון עבור הנגן הרציף ---
        let allEps = [];
        try {
            const allData = typeof getChannelEpisodes === 'function' ? getChannelEpisodes(channelId, 0, 999999) : { episodes: [] };
            allEps = typeof sortEpisodes === 'function' ? sortEpisodes(allData.episodes) : allData.episodes;
        } catch(e) {}

        vsState = { channelId, categoryName, channelTitle, mainImage, offset: 0, total: 0, loading: true, hasMore: false, allEpisodes: allEps };
    } else {
        vsState.loading = true;
        const spinner = document.createElement('div');
        spinner.id        = 'vs-spinner';
        spinner.className = 'col-span-full text-center py-4';
        spinner.innerHTML = '<i class="fas fa-spinner fa-spin text-violet-400"></i>';
        container.appendChild(spinner);
    }

    const data = getChannelEpisodes(channelId, offset, VS_PAGE_SIZE);
    document.getElementById('vs-spinner')?.remove();

    if (isFirst) {
        container.innerHTML = '';
    }

    if (data.episodes.length === 0 && isFirst) {
        container.innerHTML = '<div class="col-span-full text-center text-gray-400 py-16 text-sm">אין סרטונים להצגה</div>';
        vsState.loading = false;
        return;
    }

    data.episodes.forEach(ep => container.appendChild(createVideoCard(ep, categoryName, channelTitle, mainImage)));

    vsState.offset  = offset + data.episodes.length;
    vsState.total   = data.total;
    vsState.hasMore = data.hasMore;
    vsState.loading = false;

    if (data.hasMore) vsAttachObserver(); else vsDetachObserver();
}

function renderVideosList(episodes, categoryName, channelTitle, mainImage) {
    vsDetachObserver();
    // --- תוספת: שומרים את הרשימה במלואה לטובת הנגן ---
    vsState = { isSearch: true, allEpisodes: episodes, channelId: vsState?.channelId, categoryName, channelTitle, mainImage };
    const container = document.getElementById('videosList');
    container.innerHTML = '';
    if (!episodes || episodes.length === 0) {
        container.innerHTML = '<div class="col-span-full text-center text-gray-400 py-16 text-sm">אין סרטונים להצגה</div>';
        return;
    }
    episodes.forEach(ep => container.appendChild(createVideoCard(ep, categoryName, channelTitle, mainImage)));
}

// ─── Video Card ───────────────────────────────────────────────

function createVideoCard(ep, categoryName, channelTitle, mainImage) {
    const card      = document.createElement('div');
    const ytVideoId = extractYouTubeVideoId(ep.audioUrl) || extractYouTubeVideoId(ep.guid) || ep.guid;
    if (!ytVideoId) return card;

    const thumbUrl  = `https://img.youtube.com/vi/${ytVideoId}/mqdefault.jpg`;
    const safeTitle = (ep.title || '').replace(/'/g, "\\'").replace(/"/g, '&quot;');
    let dateStr = '';
    try { dateStr = new Date(ep.pubDate).toLocaleDateString('he-IL'); } catch(e) {}

    const epId       = (ep.guid || ep.audioUrl || ep.title || '').toString().trim();
    const isFav      = typeof isFavorite === 'function' && isFavorite(epId);
    const starClass  = isFav ? 'fas fa-star text-amber-400' : 'far fa-star text-zinc-400';
    const safeCh     = encodeURIComponent(channelTitle  || '');
    const safeImg    = encodeURIComponent(mainImage     || '');
    const safeCat    = encodeURIComponent(categoryName  || '');

    card.className = 'group relative rounded-xl overflow-hidden bg-white border border-gray-200 hover:border-gray-400 shadow-sm hover:shadow-md transition-all duration-300 animate-fade-in';
    card.innerHTML = `
        <div class="relative cursor-pointer" style="aspect-ratio:16/9;"
             data-vid="${ytVideoId}"
             data-title="${safeTitle}"
             onclick="openYTModal('${ytVideoId}', '${safeTitle}')">
            <img src="${thumbUrl}" class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
                 loading="lazy" onerror="this.src='${ep.image || mainImage || ''}'">
            <div class="absolute inset-0 flex items-center justify-center bg-black/5 group-hover:bg-black/20 transition-colors">
                <div class="w-10 h-10 rounded-full bg-red-600/90 flex items-center justify-center shadow-lg opacity-0 group-hover:opacity-100 scale-90 group-hover:scale-100 transition-all duration-200">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" class="w-5 h-5 ml-0.5"><path d="M8 5v14l11-7z"/></svg>
                </div>
            </div>
            ${ep.isNew ? '<span class="absolute top-2 right-2 text-[9px] bg-red-500 text-white px-1.5 py-0.5 rounded-full shadow font-bold">חדש</span>' : ''}
            ${ep.duration ? `<span class="absolute bottom-1.5 left-1.5 bg-black/60 text-white text-[9px] px-1.5 py-0.5 rounded-md font-mono">${ep.duration}</span>` : ''}
        </div>
        <div class="p-2.5 relative">
            <!-- pl-14 to make room for both buttons -->
            <p class="text-gray-800 text-[11px] font-medium leading-snug line-clamp-2 mb-1 pl-14">${ep.title}</p>
            <p class="text-gray-400 text-[10px]">${dateStr}</p>
            
            <div class="absolute top-2 left-2 flex gap-0.5">
                <button class="download-btn w-6 h-6 flex items-center justify-center rounded-full
                               opacity-0 group-hover:opacity-100 transition-all duration-200
                               hover:bg-violet-50 hover:scale-110"
                        title="הורד סרטון (MP4)"
                        data-dl-vid="${ytVideoId}"
                        onclick="event.stopPropagation(); window.startVideoDownload && startVideoDownload('${ytVideoId}', '${safeCat}', '${safeCh}')">
                    <i class="fas fa-download text-zinc-400 hover:text-violet-600 text-xs transition-all duration-200"></i>
                </button>
                <button class="fav-star-btn w-6 h-6 flex items-center justify-center rounded-full
                               opacity-0 group-hover:opacity-100 transition-all duration-200
                               hover:bg-amber-50 hover:scale-110"
                        title="${isFav ? 'הסר ממועדפים' : 'הוסף למועדפים'}"
                        data-fav-id="${epId}"
                        onclick="event.stopPropagation(); _toggleFavFromCard(this, event)">
                    <i class="${starClass} text-xs transition-all duration-200"></i>
                </button>
            </div>
            
            <!-- פס התקדמות להורדה (מוסתר כברירת מחדל) -->
            <div id="dl-progress-${ytVideoId}" class="hidden absolute bottom-1 left-2 right-2 items-center gap-2 bg-white/95 p-1 rounded shadow-sm border border-gray-100 z-10">
                 <div class="flex-1 h-1.5 bg-gray-200 rounded-full overflow-hidden">
                     <div class="dl-bar h-full bg-violet-500 w-0 transition-all duration-300"></div>
                 </div>
                 <span class="dl-pct text-[9px] text-violet-600 font-bold w-6 text-left">0%</span>
            </div>
        </div>`;

    // שמירת נתוני הפרק על הכרטיס להעברה ל-toggleFavorite
    card._epData = { ep, channelTitle, mainImage, categoryName };
    return card;
}

// ─── Channel Stats ────────────────────────────────────────────

/** מטפל בלחיצה על כוכב מועדפים מתוך כרטיס סרטון */
function _toggleFavFromCard(btn, event) {
    const card = btn.closest('.group');
    if (!card || !card._epData) return;
    const { ep, channelTitle, mainImage, categoryName } = card._epData;
    toggleFavorite(ep, encodeURIComponent(channelTitle || ''), encodeURIComponent(mainImage || ''), encodeURIComponent(categoryName || ''), btn);

    // עדכון ויזואלי מיידי עם אנימציה
    const icon = btn.querySelector('i');
    const epId = (ep.guid || ep.audioUrl || ep.title || '').toString().trim();
    const nowFav = isFavorite(epId);
    btn.title = nowFav ? 'הסר ממועדפים' : 'הוסף למועדפים';

    // אנימציית pop
    btn.style.transform = 'scale(1.4)';
    setTimeout(() => { btn.style.transform = ''; }, 200);

    // הכוכב תמיד גלוי אחרי לחיצה (גם ללא hover)
    if (nowFav) {
        btn.classList.remove('opacity-0');
        btn.classList.add('opacity-100');
    } else {
        btn.classList.remove('opacity-100');
        btn.classList.add('opacity-0');
        // מחזיר ל-group-hover אחרי רגע
        setTimeout(() => btn.classList.remove('opacity-0'), 300);
    }
}

function updateChannelStats(ch) {
    // מספר סרטונים
    const videoCountEl = document.getElementById('statVideoCount');
    if (videoCountEl) videoCountEl.textContent = ch.episodeCount || (ch.episodes || []).length || 0;

    // מנויים
    const subBadge = document.getElementById('statSubscribers');
    const subVal   = document.getElementById('statSubscribersVal');
    if (subBadge && subVal && ch.subscribers) {
        const n = parseInt(ch.subscribers);
        subVal.textContent = n >= 1000000 ? (n / 1000000).toFixed(1) + 'M'
                           : n >= 1000    ? Math.round(n / 1000) + 'K'
                           : n;
        subBadge.classList.remove('hidden');
    } else if (subBadge) {
        subBadge.classList.add('hidden');
    }

    // תאריך הוספה
    const addedBadge = document.getElementById('statAddedDate');
    const addedVal   = document.getElementById('statAddedDateVal');
    if (addedBadge && addedVal && ch.addedAt) {
        try { addedVal.textContent = new Date(ch.addedAt).toLocaleDateString('he-IL'); } catch(e) {}
        addedBadge.classList.remove('hidden');
    } else if (addedBadge) {
        addedBadge.classList.add('hidden');
    }

    // פרק אחרון
    const lastEpBadge = document.getElementById('statLastEpisode');
    const lastEpVal   = document.getElementById('statLastEpisodeVal');
    const eps = ch.episodes || [];
    if (lastEpBadge && lastEpVal && eps.length > 0) {
        try {
            const latest = eps.reduce((a, b) => new Date(a.pubDate) > new Date(b.pubDate) ? a : b);
            lastEpVal.textContent = new Date(latest.pubDate).toLocaleDateString('he-IL');
            lastEpBadge.classList.remove('hidden');
        } catch(e) { lastEpBadge.classList.add('hidden'); }
    } else if (lastEpBadge) {
        lastEpBadge.classList.add('hidden');
    }

    // קישור לערוץ
    const linkBadge = document.getElementById('statChannelLink');
    if (linkBadge) {
        if (ch.link || ch.rssUrl) {
            linkBadge.href = ch.link || ch.rssUrl;
            linkBadge.classList.remove('hidden');
        } else {
            linkBadge.classList.add('hidden');
        }
    }
}

// ─── Search ───────────────────────────────────────────────────

function setSearchMode(mode) {
    searchMode = mode;
    const btnChannels = document.getElementById('modeBtnChannels');
    const btnVideos   = document.getElementById('modeBtnVideos');
    if (btnChannels && btnVideos) {
        if (mode === 'channels') {
            btnChannels.className = 'p-1.5 rounded-md transition-all text-xs text-violet-400 bg-violet-500/10';
            btnVideos.className   = 'p-1.5 rounded-md transition-all text-xs';
            btnVideos.style.color = 'var(--text-muted)';
        } else {
            btnVideos.className   = 'p-1.5 rounded-md transition-all text-xs text-violet-400 bg-violet-500/10';
            btnChannels.className = 'p-1.5 rounded-md transition-all text-xs';
            btnChannels.style.color = 'var(--text-muted)';
        }
    }
    // הפעל חיפוש מחדש אם יש טקסט
    const q = document.getElementById('globalSearchInput')?.value?.trim();
    if (q) triggerGlobalSearch(q);
}

function performLocalSearch(query) {
    if (!vsState?.channelId) return;
    const { channelId, categoryName, channelTitle, mainImage } = vsState;
    const allData = getChannelEpisodes(channelId, 0, 999999);
    const q = query.toLowerCase();
    const filtered = allData.episodes.filter(ep =>
        (ep.title || '').toLowerCase().includes(q) ||
        (ep.description || '').toLowerCase().includes(q)
    );
    const countEl = document.getElementById('localSearchCount');
    if (countEl) {
        countEl.textContent = `${filtered.length} תוצאות`;
        countEl.classList.toggle('hidden', filtered.length === 0);
    }
    renderVideosList(filtered, categoryName, channelTitle, mainImage);
}

function triggerGlobalSearch(query) {
    const resultsDiv  = document.getElementById('globalSearchResults');
    const resultsList = document.getElementById('globalResultsList');
    const countEl     = document.getElementById('globalSearchCount');
    const categories  = document.getElementById('categoriesContainer');
    const clearBtn    = document.getElementById('clearGlobalSearch');

    if (!query) {
        resultsDiv?.classList.add('hidden');
        categories?.style && (categories.style.display = '');
        if (clearBtn) clearBtn.classList.add('hidden');
        return;
    }

    if (clearBtn) clearBtn.classList.remove('hidden');
    const q = query.toLowerCase();

    if (searchMode === 'channels') {
        // חיפוש ערוצים לפי שם
        const allData = getLocalData();
        const matches = [];
        allData.forEach(cat => {
            (cat.channels || []).forEach(ch => {
                if ((ch.title || '').toLowerCase().includes(q)) matches.push({ ch, catName: cat.name });
            });
        });

        if (countEl) countEl.textContent = `${matches.length} ערוצים`;
        resultsList.innerHTML = '';

        if (matches.length === 0) {
            resultsList.innerHTML = '<p style="color:var(--text-muted); font-size:13px; text-align:center; padding:32px 0;">לא נמצאו ערוצים</p>';
        } else {
            const grid = document.createElement('div');
            grid.style.cssText = 'display:flex; flex-wrap:wrap; gap:12px;';
            matches.forEach(({ ch }) => {
                const card = document.createElement('div');
                card.style.cssText = 'cursor:pointer; display:flex; align-items:center; gap:10px; background:var(--bg-card); border:1px solid var(--border); border-radius:12px; padding:10px 14px; transition:border-color 0.15s;';
                card.onmouseenter = () => card.style.borderColor = 'var(--accent)';
                card.onmouseleave = () => card.style.borderColor = 'var(--border)';
                card.onclick = () => openChannel(ch.id);
                card.innerHTML = `<img src="${ch.image || ''}" style="width:32px;height:32px;border-radius:50%;object-fit:cover;" onerror="this.style.display='none'">
                    <span style="font-size:13px;font-weight:600;color:var(--text-primary);">${ch.title}</span>`;
                grid.appendChild(card);
            });
            resultsList.appendChild(grid);
        }

        resultsDiv?.classList.remove('hidden');
        if (categories) categories.style.display = 'none';

    } else {
        // חיפוש סרטונים בכל הערוצים
        const allFull = getFullDataSync();
        const matches = [];
        allFull.forEach(cat => {
            (cat.channels || []).forEach(ch => {
                (ch.episodes || []).forEach(ep => {
                    if ((ep.title || '').toLowerCase().includes(q)) {
                        matches.push({ ep, ch, catName: cat.name });
                    }
                });
            });
        });

        if (countEl) countEl.textContent = `${matches.length} סרטונים`;
        resultsList.innerHTML = '';

        if (matches.length === 0) {
            resultsList.innerHTML = '<p style="color:var(--text-muted); font-size:13px; text-align:center; padding:32px 0;">לא נמצאו סרטונים</p>';
        } else {
            const grid = document.createElement('div');
            grid.className = 'grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4';
            matches.slice(0, 100).forEach(({ ep, ch, catName }) => {
                grid.appendChild(createVideoCard(ep, catName, ch.title, ch.image));
            });
            resultsList.appendChild(grid);
        }

        resultsDiv?.classList.remove('hidden');
        if (categories) categories.style.display = 'none';
    }
}

// ─── Search event listeners ───────────────────────────────────

document.addEventListener('DOMContentLoaded', () => {
    // חיפוש גלובלי
    const globalInput = document.getElementById('globalSearchInput');
    const clearGlobal = document.getElementById('clearGlobalSearch');

    if (globalInput) {
        let debounceTimer;
        globalInput.addEventListener('input', () => {
            clearTimeout(debounceTimer);
            debounceTimer = setTimeout(() => triggerGlobalSearch(globalInput.value.trim()), 250);
        });
    }

    if (clearGlobal) {
        clearGlobal.addEventListener('click', () => {
            const inp = document.getElementById('globalSearchInput');
            if (inp) { inp.value = ''; triggerGlobalSearch(''); }
            clearGlobal.classList.add('hidden');
            document.getElementById('categoriesContainer').style.display = '';
            document.getElementById('globalSearchResults')?.classList.add('hidden');
        });
    }

    // חיפוש מקומי בערוץ
    const localInput = document.getElementById('localVideoSearch');
    const clearLocal = document.getElementById('clearLocalSearch');

    if (localInput) {
        let debounceLocal;
        localInput.addEventListener('input', () => {
            const q = localInput.value.trim();
            clearLocal?.classList.toggle('hidden', !q);
            clearTimeout(debounceLocal);
            debounceLocal = setTimeout(() => {
                if (q) {
                    performLocalSearch(q);
                } else {
                    // שחזור virtual scroll רגיל
                    if (vsState?.channelId) {
                        loadVideosPage(vsState.channelId, 0, vsState.categoryName, vsState.channelTitle, vsState.mainImage, true);
                    }
                }
            }, 250);
        });
    }

    if (clearLocal) {
        clearLocal.addEventListener('click', () => {
            const inp = document.getElementById('localVideoSearch');
            if (inp) inp.value = '';
            clearLocal.classList.add('hidden');
            document.getElementById('localSearchCount')?.classList.add('hidden');
            if (vsState?.channelId) {
                loadVideosPage(vsState.channelId, 0, vsState.categoryName, vsState.channelTitle, vsState.mainImage, true);
            }
        });
    }
});

// ─── Refresh ──────────────────────────────────────────────────

async function refreshCurrentChannel() {
    if (!currentChannelId) return;
    const result = findChannelWithCategory(currentChannelId);
    if (!result) return;
    const { ch, categoryName } = result;

    const btn = document.getElementById('refreshBtn');
    const orig = btn.innerHTML;
    btn.disabled = true;
    btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';

    try {
        const maxEpisodes = parseInt(localStorage.getItem('yt_max_episodes') ?? '1500') || 1500;
        const res = await fetch(ENDPOINTS.YOUTUBE, {
            method: 'POST', 
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ url: ch.rssUrl, maxEpisodes })
        });
        
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const newData = await res.json();

        const currentEps = ch.episodes || [];
        // יצירת סט של מזהים קיימים (מנורמלים)
        const existingIds = new Set(currentEps.map(ep => getNormalizedId(ep)));

        // סינון סרטונים שבאמת חדשים
        const newEpisodes = (newData.episodes || []).filter(ep => {
            const id = getNormalizedId(ep);
            return id && !existingIds.has(id);
        });

        if (newEpisodes.length > 0) {
            newEpisodes.forEach(ep => ep.isNew = true);
            ch.episodes     = [...newEpisodes, ...currentEps];
            ch.episodeCount = ch.episodes.length;
            ch.newCount     = (ch.newCount || 0) + newEpisodes.length;
            ch.lastFetch    = new Date().toISOString();
            
            const data = await getFullData();
            for (const cat of data) {
                const idx = (cat.channels || []).findIndex(c => c.id === ch.id);
                if (idx !== -1) { cat.channels[idx] = ch; break; }
            }
            
            await saveDataToServer(data);
            await loadDataFromServer();
            
            // עדכון UI
            document.getElementById('channelTitle').textContent = ch.title;
            loadVideosPage(ch.id, 0, categoryName, ch.title, ch.image, true);
            showToast(`נוספו ${newEpisodes.length} סרטונים חדשים ✓`, 'success');
        } else {
            showToast('הכל מעודכן, אין סרטונים חדשים', 'info');
        }
    } catch(err) {
        showToast(`שגיאה: ${err.message}`, 'error');
    } finally {
        btn.innerHTML = orig;
        btn.disabled  = false;
    }
}