import { state } from './state.js';
import { fetchTMDB, fetchAllAvailableStreams } from './api.js';
import { showNotification, getRelativeTime, fetchWithTimeout, _ } from './utils.js';
import { getFromDB, addItemsToStore } from './db.js';
import { getAvailableProviders, renderProviders, getRegions, fetchAllProviders, resetProvidersView } from './providers.js';

let charts = {};

export async function loadInitialContent() {
    await Promise.all([loadGenres(), loadYears(), loadRegions()]);
    resetView(); 
    setupScrollEffects();
}

async function loadRegions() {
    const select = document.getElementById('region-filter');
    select.innerHTML = `<option value="">${_('loadingRegions')}</option>`;
    try {
        const data = await getRegions();
        select.innerHTML = `<option value="">${_('allRegions')}</option>`;
        data.forEach(region => {
            const option = document.createElement('option');
            option.value = region.iso_3166_1;
            option.textContent = region.english_name;
            select.appendChild(option);
        });
        select.value = state.settings.watchRegion || "";
    } catch (error) {
        select.innerHTML = `<option value="">${_('errorLoadingRegions')}</option>`;
    }
}

export function initializeUserData() {
    try {
        const savedHistory = localStorage.getItem('cineplex_userHistory');
        state.userHistory = savedHistory ? JSON.parse(savedHistory) : [];
        if (!Array.isArray(state.userHistory)) state.userHistory = [];
    } catch {
        state.userHistory = [];
    }
    try {
        const savedPrefs = localStorage.getItem('cineplex_userPreferences');
        state.userPreferences = savedPrefs ? JSON.parse(savedPrefs) : { genres: {}, keywords: {}, ratings: [], cast: {}, crew: {} };
    } catch {
        state.userPreferences = { genres: {}, keywords: {}, ratings: [], cast: {}, crew: {} };
    }
}

export async function loadLocalContent() {
    if (!state.db) return;
    try {
        const [movies, series, artists, photos, jfMovies, jfSeries] = await Promise.all([
            getFromDB('movies'), 
            getFromDB('series'), 
            getFromDB('artists'), 
            getFromDB('photos'),
            getFromDB('jellyfin_movies'),
            getFromDB('jellyfin_series')
        ]);
        state.localMovies = movies;
        state.localSeries = series;
        state.localArtists = artists;
        state.localPhotos = photos;
        state.jellyfinMovies = jfMovies;
        state.jellyfinSeries = jfSeries;

    } catch (error) {
        showNotification(_("errorLoadingLocalContent"), "error");
    }
}

export function resetView() {
    if (state.isLoading) return;

    const heroSection = document.getElementById('hero-section');
    const mainContent = document.getElementById('main-content');
    const contentSection = document.getElementById('content-section');
    const heroContent = document.querySelector('.hero-content');
    const heroBg1 = document.querySelector('.hero-background-1');
    const heroBg2 = document.querySelector('.hero-background-2');

    // Hide all main content sections
    if (mainContent) {
        mainContent.style.display = 'none';
    }
    if (contentSection) {
        contentSection.style.display = 'none';
    }
    document.getElementById('stats-section').style.display = 'none';
    document.getElementById('history-section').style.display = 'none';
    document.getElementById('recommendations-section').style.display = 'none';
    document.getElementById('photos-section').style.display = 'none';
    document.getElementById('providers-section').style.display = 'none';
    document.getElementById('m3u-generator-section').style.display = 'none';

    // Show hero if enabled
    if (heroSection) {
        if (state.settings.showHero) {
            heroSection.style.display = 'flex';
            
            // Clear dynamic hero content and reset to default
            if (state.heroIntervalId) {
                clearInterval(state.heroIntervalId);
                state.heroIntervalId = null;
            }
            
            if (heroContent) {
                heroContent.querySelector('.hero-title').textContent = _('welcomeToCinePlex');
                heroContent.querySelector('.hero-subtitle').textContent = _('welcomeSubtitle');
                heroContent.querySelector('#hero-rating').innerHTML = '';
                heroContent.querySelector('#hero-year').innerHTML = '';
                heroContent.querySelector('#hero-extra').innerHTML = '';
                heroContent.querySelector('.hero-buttons').style.display = 'none';
            }
            
            gsap.set(heroBg1, { backgroundImage: 'url(img/hero-def.png)', autoAlpha: 1, scale: 1 });
            gsap.set(heroBg2, { autoAlpha: 0 });
            heroSection.classList.add('no-overlay');

            initializeHeroSection();

        } else {
            heroSection.style.display = 'none';
        }
    }

    state.currentView = 'home';
    updateActiveNav('home');
    updateSectionTitle();
}

export function switchView(viewType) {
    if (state.isLoading) return;

    resetProvidersView();

    resetProvidersView();

    const heroSection = document.getElementById('hero-section');
    const mainContent = document.querySelector('.main-content');

    if (heroSection) {
        heroSection.style.display = 'none';
        if (state.heroIntervalId) {
            clearInterval(state.heroIntervalId);
            state.heroIntervalId = null;
        }
    }

    if (mainContent) {
        mainContent.style.display = 'block'; // Ensure main content is visible when switching views
    }

    const sidebar = document.getElementById('sidebar-nav');
    if (sidebar.classList.contains('open')) {
        sidebar.classList.remove('open');
        document.getElementById('main-container').classList.remove('sidebar-open');
    }

    const topBarHeight = document.querySelector('.top-bar')?.offsetHeight || 60;
    const targetScrollTop = mainContent ? mainContent.offsetTop - topBarHeight : 0;

    if (state.currentView === viewType && viewType !== 'search') {
        if (window.scrollY > targetScrollTop) {
            window.scrollTo({
                top: targetScrollTop,
                behavior: 'smooth'
            });
        }
        return;
    }

    state.currentView = viewType;
    state.currentPage = 1;
    state.currentParams.query = '';
    document.getElementById('search-input').value = '';
    state.lastScrollPosition = 0;

    const allSections = ['content-section', 'stats-section', 'history-section', 'recommendations-section', 'photos-section', 'providers-section', 'm3u-generator-section'];
    allSections.forEach(id => {
        const el = document.getElementById(id);
        if (el) el.style.display = 'none';
    });

    // Explicitly reset the Providers section to its initial state before view switch
    const providersSection = document.getElementById('providers-section');
    if (providersSection) {
        const detailsContainer = document.getElementById('provider-details-container');
        if (detailsContainer) detailsContainer.style.display = 'none';

        const gridContainer = document.getElementById('provider-grid-container');
        if (gridContainer) gridContainer.style.display = 'grid';

        const sectionTitle = providersSection.querySelector('.section-title');
        if (sectionTitle) sectionTitle.textContent = _('navProviders');
        
        const backArrow = providersSection.querySelector('.back-arrow');
        if (backArrow) backArrow.style.display = 'none';
    }

    const backToProvidersBtn = document.getElementById('back-to-providers-btn');
    if (backToProvidersBtn) backToProvidersBtn.style.display = 'none';

    const filters = document.querySelector('.filters');
    if (filters) filters.style.display = 'none';

    switch(viewType) {
        case 'movies':
        case 'series':
        case 'search':
            document.getElementById('content-section').style.display = 'block';
            filters.style.display = 'flex';
            if (viewType !== 'search') {
                state.currentParams.contentType = viewType === 'movies' ? 'movie' : 'tv';
                resetFilters(false);
                updateSortOptions();
                loadGenres();
            }
            break;
        case 'favorites':
            document.getElementById('content-section').style.display = 'block';
            break;
        case 'history':
            document.getElementById('history-section').style.display = 'block';
            break;
        case 'recommendations':
            document.getElementById('recommendations-section').style.display = 'block';
            break;
        case 'stats':
            document.getElementById('stats-section').style.display = 'block';
            document.getElementById('stats-filters').style.display = 'flex';
            break;
        case 'photos':
            document.getElementById('photos-section').style.display = 'block';
            break;
        case 'providers':
            document.getElementById('providers-section').style.display = 'block';
            break;
        case 'm3u-generator':
            document.getElementById('m3u-generator-section').style.display = 'block';
            break;
    }

    updateActiveNav(viewType);
    updateSectionTitle();
    
    window.scrollTo({ top: targetScrollTop, behavior: 'auto' });

    switch(viewType) {
        case 'movies':
        case 'series':
        case 'search':
            loadContent();
            break;
        case 'favorites':
            loadFavorites();
            break;
        case 'history':
            displayHistory();
            break;
        case 'recommendations':
            loadRecommendations();
            break;
        case 'stats':
            generateStatistics();
            break;
        case 'photos':
            initPhotosView();
            break;
        case 'providers':
            loadProviders();
            break;
        case 'm3u-generator':
            // The m3u-generator.js file handles its own initialization
            break;
    }

    if (document.getElementById('item-details-view').classList.contains('active')) {
        showMainView();
    }
}

function updateActiveNav(activeView) {
    document.querySelectorAll('.nav-link, .footer-link').forEach(link => link.classList.remove('active'));
    if (activeView === 'home') return;
    let navId = (activeView === 'search') ? (state.currentParams.contentType === 'movie' ? 'movies' : 'series') : activeView;
    const activeLink = document.getElementById(`nav-${navId}`);
    const activeFooterLink = document.getElementById(`footer-${navId}`);
    if (activeLink) activeLink.classList.add('active');
    if (activeFooterLink) activeFooterLink.classList.add('active');
}

export function updateSectionTitle() {
    let title = "";
    const mainTitleElement = document.getElementById('main-section-title');

    switch (state.currentView) {
        case 'home':
            title = _('explore');
            break;
        case 'movies': case 'series':
            const sortMap = { 
                'popularity.desc': _('popularSort'), 
                'vote_average.desc': _('topRatedSort'), 
                'release_date.desc': _('recentSort'), 
                'first_air_date.desc': _('recentSort')
            };
            const typeTitle = state.currentView === 'movies' ? _('moviesSectionTitle') : _('seriesSectionTitle');
            title = `${typeTitle} ${sortMap[state.currentParams.sort] || ''}`;
            break;
        case 'stats': title = _('statsTitle'); break;
        case 'favorites': title = _('navFavorites'); break;
        case 'history': title = _('historyTitle'); break;
        case 'recommendations': title = _('recommendationsTitle'); break;
        case 'photos': title = _('navPhotos'); break;
        case 'providers': title = _('navProviders'); break;
        case 'search':
            title = state.currentParams.query.startsWith('actor:')
                ? _('contentFrom', state.currentParams.query.split(':')[1])
                : _('searchResultsFor', state.currentParams.query);
            break;
        default: title = _('explore');
    }
    
    let targetTitleElement;
    if (['stats', 'history', 'recommendations', 'providers'].includes(state.currentView)) {
        targetTitleElement = document.querySelector(`#${state.currentView}-section .section-title`);
    } else {
        targetTitleElement = mainTitleElement;
    }

    if(targetTitleElement && state.currentView !== 'photos') {
        targetTitleElement.textContent = title;
        const backArrow = targetTitleElement.parentElement.querySelector('.back-arrow');
        if (backArrow) {
            backArrow.style.display = 'none';
        }
    }
}

export function applyFilters() {
    state.currentParams.genre = document.getElementById('genre-filter').value;
    state.currentParams.year = document.getElementById('year-filter').value;
    state.currentParams.sort = document.getElementById('sort-filter').value;
    state.currentPage = 1;
    loadContent();
    updateSectionTitle();
}

function resetFilters(triggerLoad = true) {
    state.currentParams.genre = '';
    state.currentParams.year = '';
    state.currentParams.sort = 'popularity.desc';
    document.getElementById('genre-filter').value = '';
    document.getElementById('year-filter').value = '';
    document.getElementById('sort-filter').value = 'popularity.desc';
    if (triggerLoad) {
        state.currentPage = 1;
        loadContent();
    }
}

function updateSortOptions() {
    const sortOption = document.getElementById('sort-release-date');
    const isMovie = state.currentParams.contentType === 'movie';
    sortOption.textContent = _('sortRecent');
    sortOption.value = isMovie ? 'release_date.desc' : 'first_air_date.desc';
}

async function loadGenres() {
    const type = state.currentParams.contentType;
    const select = document.getElementById('genre-filter');
    select.innerHTML = `<option value="">${_('loadingGenres')}</option>`;
    try {
        const data = await fetchTMDB(`genre/${type}/list`);
        select.innerHTML = `<option value="">${_('allGenres')}</option>`;
        data.genres.forEach(genre => {
            const option = document.createElement('option');
            option.value = genre.id;
            option.textContent = genre.name;
            select.appendChild(option);
        });
        select.value = state.currentParams.genre || "";
    } catch (error) {
        select.innerHTML = `<option value="">${_('errorLoadingGenres')}</option>`;
    }
}

function loadYears() {
    const select = document.getElementById('year-filter');
    select.innerHTML = `<option value="">${_('allYears')}</option>`;
    const currentYear = new Date().getFullYear();
    for (let year = currentYear; year >= 1900; year--) {
        const option = document.createElement('option');
        option.value = year;
        option.textContent = year;
        select.appendChild(option);
    }
    select.value = state.currentParams.year || "";
}

export async function loadContent(append = false) {
    if (state.currentContentFetchController) state.currentContentFetchController.abort();
    state.currentContentFetchController = new AbortController();
    const signal = state.currentContentFetchController.signal;

    if (state.isLoading) return;
    state.isLoading = true;

    const grid = document.getElementById('content-grid');
    const loadMoreButton = document.getElementById('load-more');

    if (!append) {
        grid.innerHTML = '<div class="col-12 text-center mt-5"><div class="spinner" style="position: static; margin: auto; display: block;"></div></div>';
        loadMoreButton.style.display = 'none';
    } else {
        loadMoreButton.disabled = true;
        loadMoreButton.innerHTML = `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> ${_('loading')}`;
    }

    try {
        let endpoint = '';
        const type = state.currentParams.contentType;
        if (state.currentView === 'search' && state.currentParams.query) {
            endpoint = `search/${type}?query=${encodeURIComponent(state.currentParams.query)}&page=${state.currentPage}&include_adult=false`;
        } else {
            endpoint = `discover/${type}?page=${state.currentPage}&sort_by=${state.currentParams.sort}&include_adult=false&vote_count.gte=50`;
            if (state.currentParams.genre) endpoint += `&with_genres=${state.currentParams.genre}`;
            const yearParam = type === 'movie' ? 'primary_release_year' : 'first_air_date_year';
            if (state.currentParams.year) endpoint += `&${yearParam}=${state.currentParams.year}`;
        }
        
        const data = await fetchTMDB(endpoint, signal);
        renderGrid(data.results, append);
        loadMoreButton.style.display = (data.page < data.total_pages) ? 'block' : 'none';
        if (!append) setupScrollEffects();

    } catch (error) {
        if (error.name !== 'AbortError') {
            if (!append) grid.innerHTML = `<div class="empty-state"><i class="fas fa-exclamation-triangle"></i><p>${_('couldNotLoadContent')}</p></div>`;
        }
    } finally {
        state.isLoading = false;
        if (append) {
            loadMoreButton.disabled = false;
            loadMoreButton.textContent = _('loadMore');
        }
    }
}

function isContentAvailableLocally(title, type, year) {
    if (!title || !type) return false;

    const normalize = (str) => str.toLowerCase().trim().replace(/\s+/g, ' ');
    const normalizedTitle = normalize(title);

    const checkSource = (source, itemType) => {
        if (!Array.isArray(source)) return false;
        return source.some(server => 
            server && Array.isArray(server.titulos) && 
            server.titulos.some(t => {
                if (!t || typeof t.title !== 'string') return false;
                const localTitle = normalize(t.title);
                if (localTitle !== normalizedTitle) return false;
                if (year && t.year && Math.abs(parseInt(t.year) - parseInt(year)) > 1) return false;
                if (itemType && t.type && t.type.toLowerCase() !== itemType.toLowerCase()) return false;
                return true;
            })
        );
    };

    if (checkSource(state.localMovies, 'movie')) return true;
    if (checkSource(state.localSeries, 'series')) return true;
    if (checkSource(state.jellyfinMovies, 'movie')) return true;
    if (checkSource(state.jellyfinSeries, 'series')) return true;

    return false;
}


export function renderGrid(items, append = false, gridId = 'content-grid') {
    const grid = document.getElementById(gridId);
    if (!append) grid.innerHTML = '';
    
    if (!items || items.length === 0) {
        if (!append) {
             const emptyStateTarget = document.getElementById('recommendations-grid') || grid;
             const emptyIcon = state.currentView === 'recommendations' ? 'fa-user-astronaut' : 'fa-film';
             const emptyText = state.currentView === 'recommendations' ? _('noRecommendations') : _('noContentFound');
             emptyStateTarget.innerHTML = `<div class="empty-state"><i class="fas ${emptyIcon} fa-3x mb-3"></i><p class="lead">${emptyText}</p></div>`;
        }
        document.getElementById('load-more').style.display = 'none';
        return;
    }

    const fragment = document.createDocumentFragment();
    items.forEach((item, index) => {
        if (!item || !item.id) return;
        const isMovie = item.media_type === 'movie' || (item.hasOwnProperty('title') && !item.hasOwnProperty('name'));
        const itemType = isMovie ? 'movie' : 'tv';

        const title = isMovie ? item.title : item.name;
        const releaseDate = isMovie ? item.release_date : item.first_air_date;
        const year = releaseDate ? releaseDate.slice(0, 4) : 'N/A';
        const posterPath = item.poster_path ? `https://image.tmdb.org/t/p/w500${item.poster_path}` : 'img/no-poster.png';
        const isAvailable = isContentAvailableLocally(title, itemType, year);
        const isFavorite = state.favorites.some(fav => fav.id === item.id && fav.type === itemType);
        const voteAvg = item.vote_average ? item.vote_average.toFixed(1) : 'N/A';
        const ratingClass = voteAvg >= 7.5 ? 'rating-good' : (voteAvg >= 5.0 ? 'rating-ok' : 'rating-bad');

        const card = document.createElement('div');
        card.className = `item-card`;
        card.dataset.id = item.id;
        card.dataset.type = itemType;
        card.innerHTML = `
            <div class="item-poster" style="background-image: url('${posterPath}')"></div>
            ${voteAvg >= 7.8 ? '<span class="badge top-badge">TOP</span>' : ''}
            ${isAvailable ? `<span class="badge available-badge"><i class="fas fa-check-circle"></i> ${_('local')}</span>` : ''}
            <div class="item-overlay">
                <div class="item-actions">
                    <button class="action-btn info-btn" title="${_('moreInfo')}"><i class="fas fa-info-circle fa-lg"></i></button>
                    <button class="action-btn favorites-btn ${isFavorite ? 'active' : ''}" title="${isFavorite ? _('removeFromFavorites') : _('addToFavorites')}"><i class="fas ${isFavorite ? 'fa-heart-broken' : 'fa-heart'} fa-lg"></i></button>
                    ${isAvailable ? `
                        <button class="action-btn download-btn" data-title="${title}" data-type="${itemType}" title="${_('miniplayerDownloadAlbum')}"><i class="fas fa-download fa-lg"></i></button>
                        <button class="action-btn play-btn" data-title="${title}" data-type="${itemType}" title="${_('addStream')}"><i class="fas fa-plus-circle fa-lg"></i></button>
                    ` : `<button class="action-btn disabled-btn" disabled title="${_('notAvailable')}"><i class="fas fa-times-circle fa-lg text-muted"></i></button>`}
                </div>
            </div>
            <div class="item-info">
                <h3 class="item-title" title="${title}">${title}</h3>
                <div class="item-meta">
                    <span><i class="fas fa-calendar-alt me-1"></i>${year}</span>
                    ${voteAvg !== 'N/A' ? `<span class="item-rating ms-2 ${ratingClass}"><i class="fas fa-star me-1"></i> ${voteAvg}</span>` : ''}
                </div>
            </div>
        `;
        fragment.appendChild(card);
    });
    const targetGrid = state.currentView === 'recommendations' ? document.getElementById('recommendations-grid') : grid;
    if(!append) targetGrid.innerHTML = '';
    targetGrid.appendChild(fragment);
    if (items.length > 0) setupScrollEffects();
}

export function showMainView() {
    const detailsView = document.getElementById('item-details-view');
    const mainView = document.getElementById('main-view');
    const detailsContent = document.getElementById('item-details-content');

    if (!state.lastClickedCardElement) {
        detailsView.classList.remove('active');
        document.body.classList.remove('details-view-active');
        mainView.style.display = 'block';
        mainView.style.opacity = '1';
        window.scrollTo({ top: state.lastScrollPosition, behavior: 'auto' });
        state.currentItemId = null;
        state.currentItemType = null;
        return;
    }

    const targetRect = state.lastClickedCardElement.getBoundingClientRect();
    mainView.style.display = 'block';

    const tl = gsap.timeline({
        onComplete: () => {
            detailsView.classList.remove('active');
            document.body.classList.remove('details-view-active');
            state.currentItemId = null;
            state.currentItemType = null;
            state.lastClickedCardElement = null;
            window.scrollTo({ top: state.lastScrollPosition, behavior: 'auto' });
            gsap.set(mainView, { clearProps: 'all' });
            gsap.set(detailsView, { clearProps: 'all', display: 'none' });
        }
    });

    tl.set(detailsView, { overflow: 'hidden' })
      .to(detailsContent, { opacity: 0, duration: 0.3, ease: 'power2.in' })
      .to(detailsView, {
          top: targetRect.top,
          left: targetRect.left,
          width: targetRect.width,
          height: targetRect.height,
          borderRadius: '18px',
          duration: 0.6,
          ease: 'power3.inOut'
      }, 0)
      .to(mainView, { opacity: 1, scale: 1, duration: 0.5, ease: 'power3.out' }, "-=0.4");
}

export async function showItemDetails(itemId, contentType) {
    if (!itemId || !contentType) return;

    state.currentItemId = itemId;
    state.currentItemType = contentType;
    
    const detailsView = document.getElementById('item-details-view');
    const mainView = document.getElementById('main-view');
    const detailsContent = document.getElementById('item-details-content');

    if (mainView.style.display !== 'none') state.lastScrollPosition = window.scrollY;

    document.body.classList.add('details-view-active');
    detailsContent.innerHTML = '<div class="text-center py-5"><div class="spinner" style="display: block; margin: auto; position: static;"></div></div>';
    
    detailsView.classList.add('active');
    
    const startRect = state.lastClickedCardElement 
        ? state.lastClickedCardElement.getBoundingClientRect() 
        : { top: window.innerHeight / 2, left: window.innerWidth / 2, width: 0, height: 0 };

    const tl = gsap.timeline({
        onComplete: () => {
            mainView.style.display = 'none';
            gsap.set(detailsView, { overflowY: 'auto' });
        }
    });

    tl.set(detailsView, {
        top: startRect.top,
        left: startRect.left,
        width: startRect.width,
        height: startRect.height,
        borderRadius: '18px',
        overflow: 'hidden',
        display: 'block'
    })
    .to(detailsView, {
        top: 0,
        left: 0,
        width: '100vw',
        height: '100vh',
        borderRadius: '0px',
        duration: 0.7,
        ease: 'power3.inOut'
    })
    .to(mainView, {
        opacity: 0,
        scale: 0.98,
        duration: 0.6,
        ease: 'power2.inOut'
    }, 0);

    gsap.fromTo(detailsContent, 
        { opacity: 0 }, 
        { opacity: 1, duration: 0.6, ease: 'power2.out', delay: 0.5 }
    );

    state.isLoading = true;
    try {
        const isMovie = contentType === 'movie';
        let appendToResponse = 'videos,credits,keywords,release_dates,external_ids,similar';
        if (!isMovie) {
            appendToResponse += ',content_ratings,aggregate_credits';
        }
        
        const item = await fetchTMDB(`${contentType}/${itemId}?append_to_response=${appendToResponse}`);

        if (!isMovie && item.seasons && item.seasons.length > 0) {
            const seasonPromises = item.seasons
                .filter(s => s.season_number > 0)
                .map(s => fetchTMDB(`${contentType}/${itemId}/season/${s.season_number}`).catch(() => null));
            const seasonsData = await Promise.all(seasonPromises);
            item.seasons_with_episodes = seasonsData.filter(s => s !== null);
        }

        updateUserData(item);
        await renderItemDetails(item);

    } catch (error) {
        detailsContent.innerHTML = `<div class="alert alert-danger mx-3 my-5 text-center"><h4>${_('errorLoadingDetails')}</h4><p>${error.message}</p></div>`;
    } finally {
        state.isLoading = false;
    }
}

async function renderItemDetails(item) {
    const detailsContent = document.getElementById('item-details-content');
    const isMovie = state.currentItemType === 'movie';
    const title = isMovie ? item.title : item.name;
    const backdropPath = item.backdrop_path ? `https://image.tmdb.org/t/p/original${item.backdrop_path}` : '';
    const posterPath = item.poster_path ? `https://image.tmdb.org/t/p/w500${item.poster_path}` : 'img/no-poster.png';
    const tagline = item.tagline || '';
    const overview = item.overview || _('noSynopsis');
    const releaseDate = isMovie ? item.release_date : item.first_air_date;
    const year = releaseDate ? releaseDate.slice(0, 4) : 'N/A';
    const voteAverage = item.vote_average ? item.vote_average.toFixed(1) : 'N/A';
    const genres = item.genres || [];
    const trailer = item.videos?.results?.find(v => v.site === 'YouTube' && v.type === 'Trailer');
    const isAvailable = isContentAvailableLocally(title, state.currentItemType);
    const isFavorite = state.favorites.some(fav => fav.id === item.id && fav.type === state.currentItemType);

    const imdbId = item.external_ids?.imdb_id;
    const crew = (isMovie ? item.credits?.crew : item.aggregate_credits?.crew) || [];
    const director = crew.find(c => c.job === 'Director');
    const writer = crew.find(c => c.job === 'Screenplay' || c.job === 'Writer' || c.job === 'Story');

    detailsContent.innerHTML = `
        ${backdropPath ? `<div class="details-backdrop-container"><img src="${backdropPath}" class="details-backdrop-img"><div class="details-backdrop-overlay"></div></div>` : ''}
        <div class="item-details-container">
            <div class="item-details-header">
                <div class="item-details-poster-wrapper"><img src="${posterPath}" class="item-details-poster"></div>
                <div class="item-details-content">
                    <h1 class="item-details-title">${title}</h1>
                    ${tagline ? `<p class="item-details-tagline fst-italic">"${tagline}"</p>` : ''}
                    <div class="item-details-meta">
                        ${voteAverage !== 'N/A' ? `<span class="item-details-meta-item"><i class="fas fa-star"></i> ${voteAverage}/10</span>` : ''}
                        <span class="item-details-meta-item"><i class="fas fa-calendar-alt"></i> ${year}</span>
                        ${isMovie && item.runtime ? `<span class="item-details-meta-item"><i class="fas fa-clock"></i> ${_('runtimeMinutes', String(item.runtime))}</span>` : ''}
                        ${!isMovie && item.number_of_seasons ? `<span class="item-details-meta-item"><i class="fas fa-tv"></i> ${_('seasonsCount', String(item.number_of_seasons))}</span>` : ''}
                    </div>
                    <div class="item-details-genres mb-3">${genres.map(g => `<span class="genre-badge">${g.name}</span>`).join('')}</div>
                     <div class="item-details-crew">
                        ${director ? `<p><strong>${_('director')}</strong> ${director.name}</p>` : ''}
                        ${writer ? `<p><strong>${_('writer')}</strong> ${writer.name}</p>` : ''}
                    </div>
                    ${imdbId ? `<div class="item-details-external-links mt-3 mb-4"><a href="https://www.imdb.com/title/${imdbId}" target="_blank" rel="noopener"><i class="fab fa-imdb"></i>${_('viewOnImdb')}</a></div>` : ''}
                    <h3 class="section-subtitle mt-4">${_('synopsis')}</h3>
                    <p class="item-details-overview mb-4">${overview}</p>
                    <div class="item-details-actions">
                        ${trailer ? `<button class="btn btn-outline-light trailer-btn me-2" data-trailer-key="${trailer.key}"><i class="fab fa-youtube me-1"></i> ${_('watchTrailer')}</button>` : ''}
                        <button class="btn ${isFavorite ? 'btn-danger' : 'btn-outline-danger'} favorites-btn me-2" data-id="${item.id}" data-type="${state.currentItemType}"><i class="fas ${isFavorite ? 'fa-heart-broken' : 'fa-heart'} me-1"></i> ${isFavorite ? _('removeFromFavorites') : _('addToFavorites')}</button>
                        ${isAvailable ? `
                            <button class="btn btn-success play-btn me-2" data-title="${title}" data-type="${state.currentItemType}"><i class="fas fa-plus-circle me-1"></i> ${_('addStream')}</button>
                            <button class="btn btn-info download-btn" data-title="${title}" data-type="${state.currentItemType}"><i class="fas fa-download me-1"></i> ${_('miniplayerDownloadAlbum')}</button>
                        ` : `<button class="btn btn-secondary" disabled><i class="fas fa-times-circle me-1"></i> ${_('notAvailable')}</button>`}
                    </div>
                </div>
            </div>

            <div class="item-details-section">
                ${(isMovie ? item.credits?.cast?.length > 0 : item.aggregate_credits?.cast?.length > 0) ? `
                    <h3 class="section-subtitle">${_('mainCast')}</h3>
                    <div class="cast-grid">
                        ${((isMovie ? item.credits.cast : item.aggregate_credits.cast) || []).slice(0, 12).map(actor => `
                            <div class="cast-card" data-actor-id="${actor.id}">
                                <img src="${actor.profile_path ? `https://image.tmdb.org/t/p/w200${actor.profile_path}` : 'img/no-profile.png'}" class="cast-photo">
                                <div class="cast-name">${actor.name}</div>
                                <div class="cast-character">${actor.roles ? actor.roles.map(r=>r.character).slice(0,2).join(', ') : actor.character}</div>
                            </div>
                        `).join('')}
                    </div>` : ''}
            </div>
             ${!isMovie && item.seasons_with_episodes && item.seasons_with_episodes.length > 0 ? `
                <div class="item-details-section">
                    <h3 class="section-subtitle">${_('seasonsAndEpisodes')}</h3>
                    <div class="accordion seasons-accordion" id="seasonsAccordion">
                    ${item.seasons_with_episodes.map((season, index) => `
                      <div class="accordion-item">
                        <h2 class="accordion-header" id="heading-season-${season.id}">
                          <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-season-${season.id}" aria-expanded="false" aria-controls="collapse-season-${season.id}">
                            <div class="season-info">
                               <img src="${season.poster_path ? `https://image.tmdb.org/t/p/w200${season.poster_path}` : posterPath}" class="season-poster">
                               <div class="season-details">
                                <span class="season-title">${season.name}</span>
                                <div class="season-meta">
                                  <span><i class="fas fa-calendar-alt"></i> ${season.air_date ? new Date(season.air_date).getFullYear() : 'N/A'}</span>
                                  <span><i class="fas fa-list-ol"></i> ${_('episodesCount', String(season.episodes.length))}</span>
                                </div>
                                <p class="season-overview d-none d-md-block">${(season.overview || '').substring(0,120)}${season.overview && season.overview.length > 120 ? '...' : ''}</p>
                               </div>
                            </div>
                          </button>
                        </h2>
                        <div id="collapse-season-${season.id}" class="accordion-collapse collapse" aria-labelledby="heading-season-${season.id}" data-bs-parent="#seasonsAccordion">
                          <div class="accordion-body season-episodes">
                            ${season.episodes.map(ep => `
                               <div class="episode-card">
                                 <span class="episode-number">${ep.episode_number}</span>
                                 <div class="episode-info">
                                    <h5 class="episode-title">${ep.name}</h5>
                                     <div class="episode-meta">
                                       <span><i class="far fa-calendar-alt"></i> ${ep.air_date || 'N/A'}</span>
                                       <span><i class="far fa-star"></i> ${ep.vote_average.toFixed(1)}/10</span>
                                     </div>
                                    <p class="episode-overview">${ep.overview || _('noSynopsis')}</p>
                                 </div>
                               </div>
                            `).join('')}
                          </div>
                        </div>
                      </div>
                    `).join('')}
                    </div>
                </div>
            ` : ''}

            <div class="item-details-section">
                ${item.similar?.results?.length > 0 ? `
                    <h3 class="section-subtitle">${_('similarContent')}</h3>
                    <div class="similar-items-grid">
                        ${item.similar.results.slice(0, 8).map(similar => `
                            <div class="similar-item-card" data-id="${similar.id}" data-type="${similar.media_type || state.currentItemType}">
                                <img src="${similar.poster_path ? `https://image.tmdb.org/t/p/w300${similar.poster_path}` : 'img/no-poster.png'}" class="similar-item-poster">
                                <div class="similar-item-info">
                                    <div class="similar-item-title">${similar.title || similar.name}</div>
                                </div>
                            </div>
                        `).join('')}
                    </div>` : ''}
            </div>
        </div>
    `;
}

function updateUserData(item) {
    if (!item || !item.id || !state.currentItemType) return;
    const { userHistory, userPreferences } = state;
    const contentType = state.currentItemType;

    const historyItem = { id: item.id, type: contentType, title: contentType === 'movie' ? item.title : item.name, poster: item.poster_path, timestamp: Date.now() };
    state.userHistory = [historyItem, ...userHistory.filter(h => !(h.id === item.id && h.type === contentType))].slice(0, 100);
    
    item.genres?.forEach(g => { userPreferences.genres[g.id] = (userPreferences.genres[g.id] || 0) + 1; });
    (item.keywords?.keywords || item.keywords?.results || []).slice(0, 10).forEach(kw => { userPreferences.keywords[kw.id] = (userPreferences.keywords[kw.id] || 0) + 1; });
    if (item.vote_average > 0) userPreferences.ratings.push(item.vote_average);
    if (userPreferences.ratings.length > 100) userPreferences.ratings.shift();
    
    const credits = contentType === 'tv' && item.aggregate_credits ? item.aggregate_credits : item.credits;
    credits?.cast?.slice(0, 15).forEach(a => { userPreferences.cast[a.id] = (userPreferences.cast[a.id] || 0) + 1; });
    credits?.crew?.slice(0, 15).forEach(c => { userPreferences.crew[c.id] = (userPreferences.crew[c.id] || 0) + 1; });

    localStorage.setItem('cineplex_userHistory', JSON.stringify(state.userHistory));
    localStorage.setItem('cineplex_userPreferences', JSON.stringify(userPreferences));
}

export function initializeFavorites() {
    try {
        const saved = localStorage.getItem('cineplex_favorites');
        state.favorites = saved ? JSON.parse(saved) : [];
        if (!Array.isArray(state.favorites)) state.favorites = [];
    } catch {
        state.favorites = [];
    }
}

export function toggleFavorite(itemId, itemType) {
    if (!itemId || !itemType) return;
    const index = state.favorites.findIndex(fav => fav.id === itemId && fav.type === itemType);
    let isFavoriteNow = false;

    if (index === -1) {
        state.favorites.push({ id: itemId, type: itemType });
        showNotification(_('addedToFavorites'), 'success');
        isFavoriteNow = true;
    } else {
        state.favorites.splice(index, 1);
        showNotification(_('removedFromFavorites'), 'info');
    }
    localStorage.setItem('cineplex_favorites', JSON.stringify(state.favorites));
    updateFavoriteButtonVisuals(itemId, itemType, isFavoriteNow);
    if (state.currentView === 'favorites') loadFavorites();
}

function updateFavoriteButtonVisuals(itemId, itemType, isFavorite) {
    document.querySelectorAll(`.item-card[data-id="${itemId}"][data-type="${itemType}"] .favorites-btn`).forEach(btn => {
        btn.classList.toggle('active', isFavorite);
        btn.querySelector('i').className = `fas ${isFavorite ? 'fa-heart-broken' : 'fa-heart'} fa-lg`;
    });
    if (document.getElementById('item-details-view').classList.contains('active') && state.currentItemId === itemId && state.currentItemType === itemType) {
        const detailsBtn = document.querySelector('#item-details-content .favorites-btn');
        if(detailsBtn) {
            detailsBtn.classList.toggle('btn-danger', isFavorite);
            detailsBtn.classList.toggle('btn-outline-danger', !isFavorite);
            detailsBtn.querySelector('i').className = `fas ${isFavorite ? 'fa-heart-broken' : 'fa-heart'} me-1`;
            detailsBtn.lastChild.textContent = ` ${isFavorite ? _('removeFromFavorites') : _('addToFavorites')}`;
        }
    }
}

export async function loadFavorites() {
    const grid = document.getElementById('content-grid');
    grid.innerHTML = '<div class="col-12 text-center mt-5"><div class="spinner" style="position: static; margin: auto; display: block;"></div></div>';
    
    if (state.favorites.length === 0) {
        grid.innerHTML = `<div class="empty-state"><i class="far fa-heart fa-3x mb-3"></i><p class="lead">${_('noFavorites')}</p></div>`;
        return;
    }

    try {
        const favoritePromises = state.favorites.map(fav => fetchTMDB(`${fav.type}/${fav.id}`).catch(()=>null));
        const favoriteItems = (await Promise.all(favoritePromises)).filter(item => item !== null);
        renderGrid(favoriteItems, false);
    } catch (error) {
        grid.innerHTML = `<div class="empty-state"><i class="fas fa-exclamation-triangle"></i><p>${_('errorLoadingFavorites')}</p></div>`;
    }
}

export function displayHistory() {
    const listContainer = document.getElementById('history-list');
    listContainer.innerHTML = "";
    if (state.userHistory.length === 0) {
        listContainer.innerHTML = `<div class="empty-state"><i class="fas fa-history fa-3x mb-3"></i><p class="lead">${_('historyEmpty')}</p><p class="text-muted">${_('historyEmptySub')}</p></div>`;
        document.getElementById('clear-history-btn').style.display = 'none';
        return;
    }
    
    document.getElementById('clear-history-btn').style.display = 'inline-flex';
    const fragment = document.createDocumentFragment();
    [...state.userHistory].sort((a,b) => b.timestamp - a.timestamp).forEach(item => {
        const posterUrl = item.poster ? `https://image.tmdb.org/t/p/w92${item.poster}` : 'img/no-poster.png';
        const isAvailable = isContentAvailableLocally(item.title, item.type);
        const historyItem = document.createElement('div');
        historyItem.className = 'history-item';
        historyItem.dataset.id = item.id;
        historyItem.dataset.type = item.type;
        historyItem.dataset.title = item.title;
        historyItem.innerHTML = `
            <div class="history-main-content">
                <img src="${posterUrl}" class="history-poster info-btn">
                <div class="history-info info-btn">
                    <div class="history-title-wrapper">
                        <div class="history-title">${item.title}</div>
                        ${isAvailable ? `<span class="badge local-badge-history">${_('local')}</span>` : ''}
                    </div>
                    <div class="history-meta">${_('viewed')} ${getRelativeTime(item.timestamp)}</div>
                </div>
            </div>
            <div class="history-actions">
                <button class="action-btn info-btn" title="${_('moreInfo')}"><i class="fas fa-info-circle"></i></button>
                <button class="action-btn trailer-btn" title="${_('watchTrailer')}"><i class="fab fa-youtube"></i></button>
                <button class="action-btn play-btn" title="${_('addStream')}" ${!isAvailable ? 'disabled' : ''}><i class="fas fa-plus-circle"></i></button>
                <button class="action-btn delete-btn" title="${_('clearHistory')}"><i class="fas fa-trash-alt"></i></button>
            </div>`;
        fragment.appendChild(historyItem);
    });
    listContainer.appendChild(fragment);
}

export function deleteHistoryItem(id, type, element) {
    const numericId = Number(id);
    state.userHistory = state.userHistory.filter(item => !(item.id === numericId && item.type === type));
    localStorage.setItem('cineplex_userHistory', JSON.stringify(state.userHistory));
    
    gsap.to(element, {
        height: 0,
        opacity: 0,
        paddingTop: 0,
        paddingBottom: 0,
        marginTop: 0,
        marginBottom: 0,
        duration: 0.5,
        ease: "power3.inOut",
        onComplete: () => {
            element.remove();
            if (state.userHistory.length === 0) {
                displayHistory();
            }
        }
    });
    showNotification(_('historyItemDeleted'), "info");
}

export function clearAllHistory() {
    if (confirm(_('confirmClearHistory'))) {
        state.userHistory = [];
        localStorage.setItem('cineplex_userHistory', JSON.stringify(state.userHistory));
        displayHistory();
        showNotification(_('historyCleared'), "success");
    }
}

export async function getTrailerKey(id, type) {
    try {
        const data = await fetchTMDB(`${type}/${id}/videos`);
        const trailer = data.results.find(v => v.site === 'YouTube' && v.type === 'Trailer') || data.results.find(v => v.site === 'YouTube');
        return trailer ? trailer.key : null;
    } catch (error) {
        return null;
    }
}

export async function loadRecommendations() {
    const grid = document.getElementById('recommendations-grid');
    grid.innerHTML = '<div class="col-12 text-center mt-5"><div class="spinner" style="position: static; margin: auto; display: block;"></div></div>';

    const cachedRecs = sessionStorage.getItem('cineplex_recommendations');
    if (cachedRecs) {
        const { timestamp, data } = JSON.parse(cachedRecs);
        if (Date.now() - timestamp < 1000 * 60 * 30) {
            renderGrid(data);
            return;
        }
    }

    const seedPool = [...state.favorites, ...state.userHistory.slice(0, 10)];
    if (seedPool.length === 0) {
        renderGrid([]);
        return;
    }

    try {
        const seed = seedPool[Math.floor(Math.random() * seedPool.length)];
        const endpoint = `${seed.type}/${seed.id}/recommendations?page=1`;
        const data = await fetchTMDB(endpoint);

        const seenIds = new Set(state.userHistory.map(item => item.id));
        const recommendations = data.results.filter(rec => !seenIds.has(rec.id)).slice(0, 12);

        if (recommendations.length > 0) {
            renderGrid(recommendations);
            sessionStorage.setItem('cineplex_recommendations', JSON.stringify({ timestamp: Date.now(), data: recommendations }));
        } else {
            renderGrid([]);
        }
    } catch(error) {
        grid.innerHTML = `<div class="empty-state"><i class="fas fa-exclamation-triangle"></i><p>${_('errorGeneratingRecommendations')}</p></div>`;
    }
}

async function populateStatsTokenFilter() {
    const select = document.getElementById('stats-token-filter');
    const currentValue = select.value;
    select.innerHTML = `<option value="all">${_('statsAllTokens')}</option>`;

    try {
        const tokensData = await getFromDB('tokens');
        const primaryTokens = [...new Set(tokensData.map(t => t.token))];
        
        const connections = await getFromDB('conexiones_locales');
        const tokenNames = {};
        connections.forEach(conn => {
            if (conn.tokenPrincipal && !tokenNames[conn.tokenPrincipal]) {
                 tokenNames[conn.tokenPrincipal] = conn.nombre || `Token...${conn.tokenPrincipal.slice(-4)}`;
            }
        });
        
        primaryTokens.forEach(token => {
            const option = document.createElement('option');
            option.value = token;
            option.textContent = tokenNames[token] || `Token...${token.slice(-4)}`;
            select.appendChild(option);
        });

        if (currentValue) {
            select.value = currentValue;
        }

    } catch(e) {
        select.innerHTML = `<option value="all">${_('errorLoadingTokens')}</option>`;
    }
}

export async function generateStatistics() {
    const loader = document.getElementById('stats-loader');
    const content = document.getElementById('stats-content');
    loader.style.display = 'block';
    content.style.display = 'none';

    Object.values(charts).forEach(chart => chart.destroy());
    charts = {};

    await populateStatsTokenFilter();
    
    try {
        const selectedToken = document.getElementById('stats-token-filter').value;

        const filteredPlexMovies = selectedToken === 'all' ? state.localMovies : state.localMovies.filter(server => server.tokenPrincipal === selectedToken);
        const filteredPlexSeries = selectedToken === 'all' ? state.localSeries : state.localSeries.filter(server => server.tokenPrincipal === selectedToken);
        const filteredPlexArtists = selectedToken === 'all' ? state.localArtists : state.localArtists.filter(server => server.tokenPrincipal === selectedToken);

        const plexMovieItems = filteredPlexMovies.flatMap(s => s.titulos);
        const plexSeriesItems = filteredPlexSeries.flatMap(s => s.titulos);
        const plexArtistItems = filteredPlexArtists.flatMap(s => s.titulos);

        const jellyfinMovieItems = state.jellyfinMovies.flatMap(lib => lib.titulos);
        const jellyfinSeriesItems = state.jellyfinSeries.flatMap(lib => lib.titulos);

        const allMovieItems = [...plexMovieItems, ...jellyfinMovieItems];
        const allSeriesItems = [...plexSeriesItems, ...jellyfinSeriesItems];
        const allArtistItems = [...plexArtistItems];

        const uniqueMovieTitles = new Set(allMovieItems.map(item => item.title));
        const uniqueSeriesTitles = new Set(allSeriesItems.map(item => item.title));
        const uniqueArtists = new Set(allArtistItems.map(item => item.title));
        animateValue('total-movies', 0, uniqueMovieTitles.size, 1000);
        animateValue('total-series', 0, uniqueSeriesTitles.size, 1000);
        animateValue('total-artists', 0, uniqueArtists.size, 1000);

        const allTokens = await getFromDB('tokens');
        const allConnections = await getFromDB('conexiones_locales');

        const filteredTokens = selectedToken === 'all' 
            ? allTokens 
            : allTokens.filter(t => t.token === selectedToken);

        const filteredConnections = selectedToken === 'all'
            ? allConnections
            : allConnections.filter(c => c.tokenPrincipal === selectedToken);

        animateValue('total-tokens', 0, filteredTokens.length, 1000);
        animateValue('total-servers', 0, filteredConnections.length, 1000);
        
        updateTokenDetailsCard(selectedToken, filteredConnections);
        
        const movieGenres = processLocalGenres(allMovieItems);
        const seriesGenres = processLocalGenres(allSeriesItems);
        const allDecades = processLocalDecades([...allMovieItems, ...allSeriesItems]);
        
        createGenreChart('movie-genres-chart', movieGenres, _('statsChartMoviesByGenre'));
        createGenreChart('series-genres-chart', seriesGenres, _('statsChartSeriesByGenre'));
        createDecadeChart('decade-chart', allDecades, _('statsChartByDecade'));

        loader.style.display = 'none';
        content.style.display = 'grid';
        gsap.from(".stats-card, .chart-container", {
            duration: 0.7,
            y: 30,
            opacity: 0,
            stagger: 0.1,
            ease: "power3.out"
        });

    } catch (error) {
        loader.innerHTML = `<div class="empty-state"><i class="fas fa-exclamation-triangle"></i><p>${_('errorGeneratingStats')}</p></div>`;
    }
}

function updateTokenDetailsCard(selectedToken, allConnections) {
    const card = document.getElementById('token-details-card');
    const serverList = document.getElementById('token-server-list');
    
    if (selectedToken === 'all') {
        card.style.display = 'none';
        return;
    }
    
    const associatedServers = allConnections.filter(c => c.tokenPrincipal === selectedToken);
    
    if (associatedServers.length === 0) {
        serverList.innerHTML = `<li>${_('noServersForToken')}</li>`;
    } else {
        serverList.innerHTML = associatedServers.map(s => 
            `<li><strong>${s.nombre}:</strong> <code>${s.token.slice(0, 5)}...${s.token.slice(-5)}</code></li>`
        ).join('');
    }
    card.style.display = 'block';
}

function processLocalGenres(items) {
    const genreCounts = {};
    items.forEach(item => {
        const genre = item.genre || _('noGenre');
        genreCounts[genre] = (genreCounts[genre] || 0) + 1;
    });
    return genreCounts;
}

function processLocalDecades(items) {
    const decadeCounts = {};
    items.forEach(item => {
        if (item.year && !isNaN(item.year)) {
            const decade = Math.floor(parseInt(item.year, 10) / 10) * 10;
            decadeCounts[decade] = (decadeCounts[decade] || 0) + 1;
        }
    });
    return decadeCounts;
}


async function createGenreChart(canvasId, genreData, label) {
    const sortedGenres = Object.entries(genreData)
        .sort(([, a], [, b]) => b - a)
        .slice(0, 15);

    const labels = sortedGenres.map(([name]) => name);
    const data = sortedGenres.map(([, count]) => count);

    const ctx = document.getElementById(canvasId).getContext('2d');
    charts[canvasId] = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: labels,
            datasets: [{
                label: label,
                data: data,
                backgroundColor: 'rgba(0, 224, 255, 0.6)',
                borderColor: 'rgba(0, 224, 255, 1)',
                borderWidth: 1,
                borderRadius: 5,
            }]
        },
        options: {
            responsive: true,
            indexAxis: 'y',
            scales: { y: { ticks: { color: 'rgba(240, 240, 245, 0.8)' } }, x: { ticks: { color: 'rgba(240, 240, 245, 0.8)' } } },
            plugins: { legend: { display: false }, tooltip: { bodyFont: { size: 14 }, titleFont: { size: 16 } } }
        }
    });
}

function createDecadeChart(canvasId, decadeData, label) {
    const sortedDecades = Object.entries(decadeData).sort(([a], [b]) => a - b);
    const labels = sortedDecades.map(([decade]) => `${decade}s`);
    const data = sortedDecades.map(([, count]) => count);
    
    const ctx = document.getElementById(canvasId).getContext('2d');
    charts[canvasId] = new Chart(ctx, {
        type: 'line',
        data: {
            labels: labels,
            datasets: [{
                label: label,
                data: data,
                fill: true,
                backgroundColor: 'rgba(0, 114, 255, 0.2)',
                borderColor: 'rgba(0, 114, 255, 1)',
                tension: 0.3,
                pointBackgroundColor: 'rgba(0, 114, 255, 1)',
                pointBorderColor: '#fff',
                pointHoverRadius: 7,
            }]
        },
        options: {
            responsive: true,
            scales: { y: { ticks: { color: 'rgba(240, 240, 245, 0.8)', beginAtZero: true } }, x: { ticks: { color: 'rgba(240, 240, 245, 0.8)' } } },
            plugins: { legend: { display: false } }
        }
    });
}

function animateValue(id, start, end, duration) {
    const obj = document.getElementById(id);
    if (!obj) return;
    let startTimestamp = null;
    const step = (timestamp) => {
        if (!startTimestamp) startTimestamp = timestamp;
        const progress = Math.min((timestamp - startTimestamp) / duration, 1);
        obj.innerHTML = Math.floor(progress * (end - start) + start).toLocaleString(state.settings.language);
        if (progress < 1) {
            window.requestAnimationFrame(step);
        }
    };
    window.requestAnimationFrame(step);
}

export async function searchByActor(actorId, actorName) {
    if (state.isLoading) return;
    showNotification(_('searchingActorContent', actorName), 'info');

    if (document.getElementById('item-details-view').classList.contains('active')) {
        const mainContent = document.querySelector('.main-content');
        const topBarHeight = document.querySelector('.top-bar')?.offsetHeight || 60;
        const targetScrollTop = mainContent ? mainContent.offsetTop - topBarHeight : 0;
        state.lastScrollPosition = targetScrollTop;
        showMainView();
    }
    
    state.currentView = 'search';
    document.getElementById('search-input').value = ``;
    state.currentParams.query = `actor:${actorName}`;
    state.currentPage = 1;
    updateSectionTitle();
    updateActiveNav(state.currentParams.contentType);

    const grid = document.getElementById('content-grid');
    grid.innerHTML = '<div class="col-12 text-center mt-5"><div class="spinner" style="display: block; margin: auto; position: static;"></div></div>';
    document.querySelector('.filters').style.display = 'none';
    
    try {
        const endpoint = `discover/${state.currentParams.contentType}?with_cast=${actorId}&sort_by=popularity.desc&page=1`;
        const data = await fetchTMDB(endpoint);
        renderGrid(data.results, false);
        document.getElementById('load-more').style.display = (data.page < data.total_pages) ? 'block' : 'none';
    } catch (error) {
        grid.innerHTML = `<div class="empty-state"><i class="fas fa-exclamation-triangle"></i><p>${_('errorLoadingActorContent', actorName)}</p></div>`;
    }
}

export async function initializeHeroSection() {
    const heroSection = document.getElementById('hero-section');
    if (heroSection.style.display === 'none' || !state.settings.showHero) return;

    // Clear existing timers for slide changes and initial load
    if (state.heroIntervalId) {
        clearInterval(state.heroIntervalId);
        state.heroIntervalId = null;
    }
    if (state.heroLoadTimeoutId) {
        clearTimeout(state.heroLoadTimeoutId);
        state.heroLoadTimeoutId = null;
    }

    const bg1 = document.querySelector('.hero-background-1');
    const bg2 = document.querySelector('.hero-background-2');
    const content = document.querySelector('.hero-content');
    const heroButtons = content.querySelector('.hero-buttons');

    // Set static background and show default content
    content.querySelector('.hero-title').textContent = _('heroWelcome');
    content.querySelector('.hero-subtitle').textContent = _('heroSubtitle');
    content.querySelector('#hero-rating').innerHTML = '';
    content.querySelector('#hero-year').innerHTML = '';
    content.querySelector('#hero-extra').innerHTML = '';
    heroButtons.style.display = 'none';

    heroSection.classList.add('no-overlay');
    gsap.set(bg1, { backgroundImage: `url(img/hero-def.png)`, autoAlpha: 1, scale: 1 });
    gsap.set(bg2, { autoAlpha: 0 });
    gsap.set(content, { autoAlpha: 1 });
    heroSection.classList.remove('loading');

    // After 5 seconds, load the dynamic content if we are still on the home view
    state.heroLoadTimeoutId = setTimeout(() => {
        if (state.currentView === 'home') {
            loadTmdbHeroContent();
        }
    }, 5000);

    async function loadTmdbHeroContent() {
        heroSection.classList.remove('no-overlay');
        try {
            const type = Math.random() > 0.5 ? 'movie' : 'tv';
            const data = await fetchTMDB(`${type}/popular?page=1`);
            const popularItems = data.results.filter(i => i.backdrop_path && i.overview).slice(0, 8);

            if (popularItems.length === 0) {
                return; // Keep static image if no items
            }

            let currentBg = bg1;
            let nextBg = bg2;
            let currentIndex = -1;

            function changeHeroSlide() {
                currentIndex = (currentIndex + 1) % popularItems.length;
                const item = popularItems[currentIndex];
                const nextImage = new Image();
                nextImage.src = `https://image.tmdb.org/t/p/original${item.backdrop_path}`;

                nextImage.onload = () => {
                    updateHeroContent(item);

                    const heroElements = [
                        content.querySelector('.hero-title'),
                        content.querySelector('.hero-subtitle'),
                        ...content.querySelectorAll('.hero-meta-item'),
                        content.querySelector('.hero-buttons')
                    ];

                    const tl = gsap.timeline({
                        onComplete: () => {
                            const temp = currentBg;
                            currentBg = nextBg;
                            nextBg = temp;
                            gsap.set(nextBg, { autoAlpha: 0 });
                        }
                    });

                    tl.to(heroElements, { autoAlpha: 0, y: 30, stagger: 0.08, duration: 0.6, ease: 'power3.in' }, 0);
                    gsap.set(nextBg, { backgroundImage: `url(${nextImage.src})`, autoAlpha: 0 });
                    tl.to(currentBg, { autoAlpha: 0, duration: 2.5, ease: 'power2.inOut' }, 0);
                    tl.to(nextBg, { autoAlpha: 1, duration: 2.5, ease: 'power2.inOut' }, 0);
                    gsap.fromTo(nextBg, { scale: 1.15, transformOrigin: 'center center' }, { scale: 1, duration: 12, ease: 'none' });
                    tl.fromTo(heroElements, { y: -30, autoAlpha: 0 }, { y: 0, autoAlpha: 1, stagger: 0.1, duration: 1.2, ease: 'power3.out' }, '>-0.8');
                };
            }

            if (state.heroIntervalId) {
                clearInterval(state.heroIntervalId);
            }
            changeHeroSlide();
            state.heroIntervalId = setInterval(changeHeroSlide, 12000);

        } catch (error) {
            console.error("Error initializing hero section from TMDB:", error);
        }
    }
}

function updateHeroContent(item) {
    const heroContent = document.querySelector('.hero-content');
    const heroTitle = heroContent.querySelector('.hero-title');
    const heroSubtitle = heroContent.querySelector('.hero-subtitle');
    const heroRating = heroContent.querySelector('#hero-rating');
    const heroYear = heroContent.querySelector('#hero-year');
    const heroExtra = heroContent.querySelector('#hero-extra');
    const heroButtons = heroContent.querySelector('.hero-buttons');
    const heroPlayBtn = heroButtons.querySelector('#hero-play-btn');
    const heroInfoBtn = heroButtons.querySelector('#hero-info-btn');

    const type = item.title ? 'movie' : 'tv';
    const title = item.title || item.name;
    const isAvailable = isContentAvailableLocally(title, type);
    
    if (heroTitle) heroTitle.textContent = title;
    if (heroSubtitle) heroSubtitle.textContent = item.overview.substring(0, 200) + (item.overview.length > 200 ? '...' : '');
    if (heroRating) heroRating.innerHTML = `<i class="fas fa-star"></i> ${item.vote_average.toFixed(1)}/10`;
    if (heroYear) heroYear.innerHTML = `<i class="fas fa-calendar-alt"></i> ${(item.release_date || item.first_air_date).slice(0, 4)}`;
    if (heroExtra) heroExtra.innerHTML = `<i class="fas ${type === 'movie' ? 'fa-film' : 'fa-tv'}"></i> ${type === 'movie' ? _('moviesSectionTitle') : _('seriesSectionTitle')}`;

    heroButtons.style.display = 'block';

    if (heroPlayBtn) {
        heroPlayBtn.onclick = () => addStreamToList(title, type, heroPlayBtn);
        heroPlayBtn.disabled = !isAvailable;
    }
    if (heroInfoBtn) {
        heroInfoBtn.onclick = () => {
            state.lastClickedCardElement = heroInfoBtn;
            showItemDetails(item.id, type);
        };
        heroInfoBtn.disabled = false;
    }
}

export async function addStreamToList(title, type, buttonElement = null) {
    if (state.isAddingStream) return;
    state.isAddingStream = true;
    let originalButtonContent = null;
    if (buttonElement) {
        originalButtonContent = buttonElement.innerHTML;
        buttonElement.disabled = true;
        buttonElement.innerHTML = `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>`;
    }

    if (!state.settings.phpScriptUrl || !state.settings.phpScriptUrl.trim().startsWith('http')) {
        showNotification(_('phpUrlNotConfigured'), 'warning');
        state.isAddingStream = false;
        if (buttonElement && originalButtonContent) {
            buttonElement.innerHTML = originalButtonContent;
            buttonElement.disabled = false;
        }
        return;
    }

    showNotification(_('searchingStreams', title), 'info');

    try {
        const streamData = await fetchAllAvailableStreams(title, type);
        if (!streamData.success || streamData.streams.length === 0) throw new Error(streamData.message);
        
        showNotification(_('sendingStreams', String(streamData.streams.length)), 'info');
        const payload = { streams: streamData.streams.map(s => ({ url: s.url, extinf: s.extinf.replace(/[\r\n]+/g, '') })) };

        const response = await fetch(state.settings.phpScriptUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(payload)
        });

        const result = await response.json();
        if (!response.ok || !result.success) throw new Error(result.message || _('errorServerResponse'));
        showNotification(result.message || _('streamAddedSuccess'), 'success');
    } catch (error) {
        showNotification(_('errorAddingStream', error.message), "error");
    } finally {
        state.isAddingStream = false;
        if (buttonElement && originalButtonContent) {
             buttonElement.innerHTML = originalButtonContent;
             buttonElement.disabled = false;
        }
    }
}

export async function downloadM3U(title, type, buttonElement = null) {
    if (state.isDownloadingM3U) return;
    state.isDownloadingM3U = true;
    let originalButtonContent = null;
    if (buttonElement) {
        originalButtonContent = buttonElement.innerHTML;
        buttonElement.disabled = true;
        buttonElement.innerHTML = `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>`;
    }

    showNotification(_('generatingM3U', title), "info");
    
    try {
        const streamData = await fetchAllAvailableStreams(title, type);

        if (!streamData.success || streamData.streams.length === 0) throw new Error(streamData.message);
        
        let m3uContent = "#EXTM3U\n";
        streamData.streams.forEach(stream => {
            m3uContent += `${stream.extinf}\n${stream.url}\n`;
        });

        const blob = new Blob([m3uContent], { type: "audio/x-mpegurl;charset=utf-8" });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `${title.replace(/[^a-z0-9]/gi, '_')}.m3u`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
        showNotification(_('m3uDownloaded', title), 'success');
    } catch (error) {
        showNotification(_('errorGeneratingM3U', error.message), "error");
    } finally {
        state.isDownloadingM3U = false;
         if (buttonElement && originalButtonContent) {
             buttonElement.innerHTML = originalButtonContent;
             buttonElement.disabled = false;
        }
    }
}

export function showTrailer(key) {
    const lightbox = document.getElementById('video-lightbox');
    const iframe = document.getElementById('video-iframe');
    iframe.src = `https://www.youtube.com/embed/${key}?autoplay=1&modestbranding=1&rel=0`;
    lightbox.classList.add('active');
    document.body.style.overflow = 'hidden';
}

export function closeTrailer() {
    const lightbox = document.getElementById('video-lightbox');
    const iframe = document.getElementById('video-iframe');
    iframe.src = '';
    lightbox.classList.remove('active');
    document.body.style.overflow = '';
}

function setupScrollEffects() {
    gsap.utils.toArray('.item-card:not(.gsap-anim), .photo-card:not(.gsap-anim), .album-card:not(.gsap-anim)').forEach((el) => {
        el.classList.add('gsap-anim');
        gsap.from(el, { 
            autoAlpha: 0, 
            y: 50, 
            duration: 0.6,
            ease: "power2.out",
            scrollTrigger: { 
                trigger: el, 
                start: "top 95%", 
                toggleActions: "play none none none",
            },
        });
    });
}

export function activateSettingsTab(tabId) {
    const tabButtons = document.querySelectorAll('#settingsTabs .nav-link');
    const tabPanes = document.querySelectorAll('#settingsTabsContent .tab-pane');

    tabButtons.forEach(button => {
        if (button.id === `${tabId}-tab`) {
            button.classList.add('active');
            button.setAttribute('aria-selected', 'true');
        } else {
            button.classList.remove('active');
            button.setAttribute('aria-selected', 'false');
        }
    });

    tabPanes.forEach(pane => {
        if (pane.id === tabId) {
            pane.classList.add('show', 'active');
        } else {
            pane.classList.remove('show', 'active');
        }
    });
}

export function openSettingsModal() {
    document.getElementById('tmdbApiKey').value = state.settings.apiKey;
    document.getElementById('appLanguage').value = state.settings.language;
    document.getElementById('phpScriptUrl').value = state.settings.phpScriptUrl || '';
    document.getElementById('lightModeToggle').checked = state.settings.theme === 'light';
    document.getElementById('showHeroToggle').checked = state.settings.showHero;

    document.getElementById('jellyfinServerUrl').value = state.jellyfinSettings.url || '';
    document.getElementById('jellyfinUsername').value = state.jellyfinSettings.username || '';
    document.getElementById('jellyfinPassword').value = state.jellyfinSettings.password || '';

    document.getElementById('phpSecretKeyCheck').checked = state.settings.phpUseSecretKey;
    document.getElementById('phpSecretKey').value = state.settings.phpSecretKey || '';
    document.getElementById('phpSavePath').value = state.settings.phpSavePath || '';
    document.getElementById('phpFilename').value = state.settings.phpFilename || 'CinePlex_Playlist.m3u';
    document.getElementById('phpFileActionAppend').checked = state.settings.phpFileAction === 'append';
    document.getElementById('phpFileActionOverwrite').checked = state.settings.phpFileAction === 'overwrite';
    
    activateSettingsTab('general');

    const modal = new bootstrap.Modal(document.getElementById('settingsModal'));
    modal.show();
}

export async function saveSettings() {
    const oldLanguage = state.settings.language;
    const newSettings = {
        id: 'user_settings',
        apiKey: document.getElementById('tmdbApiKey').value.trim(),
        language: document.getElementById('appLanguage').value,
        theme: document.getElementById('lightModeToggle').checked ? 'light' : 'dark',
        showHero: document.getElementById('showHeroToggle').checked,
        phpScriptUrl: document.getElementById('phpScriptUrl').value.trim(),
        phpUseSecretKey: document.getElementById('phpSecretKeyCheck').checked,
        phpSecretKey: document.getElementById('phpSecretKey').value.trim(),
        phpSavePath: document.getElementById('phpSavePath').value.trim(),
        phpFilename: document.getElementById('phpFilename').value.trim(),
        phpFileAction: document.getElementById('phpFileActionAppend').checked ? 'append' : 'overwrite',
        watchRegion: document.getElementById('region-filter').value
    };
    
    state.settings = { ...state.settings, ...newSettings };

    const newJellyfinSettings = {
        id: 'jellyfin_credentials',
        url: document.getElementById('jellyfinServerUrl').value.trim(),
        username: document.getElementById('jellyfinUsername').value.trim(),
        password: document.getElementById('jellyfinPassword').value
    };
    state.jellyfinSettings = { ...state.jellyfinSettings, ...newJellyfinSettings };
    
    try {
        await Promise.all([
            addItemsToStore('settings', [state.settings]),
            addItemsToStore('jellyfin_settings', [state.jellyfinSettings])
        ]);

        showNotification(_('settingsSavedSuccess'), 'success');
        applyTheme(state.settings.theme);
        applyHeroVisibility(state.settings.showHero);
        bootstrap.Modal.getInstance(document.getElementById('settingsModal'))?.hide();
        if (newSettings.language !== oldLanguage) {
            showNotification(_('languageChangeReload'), 'info', 4000);
            setTimeout(() => window.location.reload(), 4000);
        }
    } catch (error) {
        showNotification(_('errorSavingSettings'), 'error');
    }
}

export function applyTheme(theme) {
    document.body.classList.toggle('light-theme', theme === 'light');
}

export function applyHeroVisibility(show) {
    const hero = document.getElementById('hero-section');
    if(hero) hero.style.display = show ? 'flex' : 'none';
}

export const phpScriptGenerator = (() => {
    let dom = {};

    function cacheDom() {
        const settingsModal = document.getElementById('settingsModal');
        if (!settingsModal) return false;
        
        dom.secretKeyCheck = settingsModal.querySelector('#phpSecretKeyCheck');
        dom.secretKey = settingsModal.querySelector('#phpSecretKey');
        dom.savePath = settingsModal.querySelector('#phpSavePath');
        dom.filename = settingsModal.querySelector('#phpFilename');
        dom.fileActionAppendRadio = settingsModal.querySelector('#phpFileActionAppend');
        dom.generatedCode = settingsModal.querySelector('#generatedPhpCode');
        dom.generateBtn = settingsModal.querySelector('#generatePhpScriptBtn');
        dom.copyBtn = settingsModal.querySelector('#copyPhpScriptBtn');
        
        return dom.generateBtn && dom.copyBtn;
    }

    function init() {
        if (!cacheDom()) {
            return;
        }
        dom.generateBtn.addEventListener('click', generatePhpScript);
        dom.copyBtn.addEventListener('click', copyScript);
    }
    
    function generatePhpScript() {
        const useSecretKey = dom.secretKeyCheck.checked;
        const secretKey = dom.secretKey.value.trim();
        const savePath = dom.savePath.value.trim();
        const filename = dom.filename.value.trim() || 'CinePlex_Playlist.m3u';
        const appendToFile = dom.fileActionAppendRadio.checked;

        let script = `<?php\nheader('Content-Type: application/json');\nheader('Access-Control-Allow-Origin: *');\nheader('Access-Control-Allow-Methods: POST, OPTIONS');\nheader('Access-Control-Allow-Headers: Content-Type, Origin, X-Secret-Key');\n\nif ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {\n    http_response_code(200);\n    exit(0);\n}\n\ndefine('SAVE_DIRECTORY', '${savePath.replace(/'/g, "\\'")}');\ndefine('FILENAME', '${filename.replace(/'/g, "\\'")}');\ndefine('FILE_ACTION_APPEND', ${appendToFile ? 'true' : 'false'});\n${useSecretKey ? `define('SECRET_KEY', '${secretKey.replace(/'/g, "\\'")}');` : ''}\n\nfunction sendResponse($success, $message, $filename = '', $http_code = 200) {\n    if (!$success && $http_code === 200) {\n        $http_code = 400;\n    }\n    http_response_code($http_code);\n    echo json_encode(['success' => $success, 'message' => $message, 'filename' => $filename]);\n    exit;\n}\n`;
        if (useSecretKey) {
            script += `\n$auth_key = isset($_SERVER['HTTP_X_SECRET_KEY']) ? $_SERVER['HTTP_X_SECRET_KEY'] : '';\nif (!defined('SECRET_KEY') || SECRET_KEY === '' || $auth_key !== SECRET_KEY) {\n    sendResponse(false, 'Acceso no autorizado. Clave secreta inválida o no proporcionada.', '', 403);\n}\n`;
        }
        script += `\n$json_data = file_get_contents('php://input');\n$data = json_decode($json_data, true);\n\nif (json_last_error() !== JSON_ERROR_NONE) {\n    sendResponse(false, 'Error: Datos JSON inválidos.');\n}\n\nif (!isset($data['streams']) || !is_array($data['streams']) || empty($data['streams'])) {\n    sendResponse(false, 'Error: El JSON debe contener un array "streams" no vacío.');\n}\n\n$save_dir = SAVE_DIRECTORY !== '' ? rtrim(SAVE_DIRECTORY, '/\\') : __DIR__;\n\nif (!is_dir($save_dir) || !is_writable($save_dir)) {\n    sendResponse(false, 'Error del servidor: El directorio de destino no existe o no tiene permisos de escritura.', '', 500);\n}\n\n$safe_filename = preg_replace('/[^\\w\\s._-]/', '', basename(FILENAME));\n$safe_filename = preg_replace('/\\s+/', '_', $safe_filename);\n$target_path = $save_dir . DIRECTORY_SEPARATOR . $safe_filename;\n\n$content_to_write = "";\n\nif (FILE_ACTION_APPEND) {\n    $file_exists = file_exists($target_path);\n    if (!$file_exists) {\n        $content_to_write .= "#EXTM3U\\n";\n    }\n    foreach ($data['streams'] as $stream) {\n        if (isset($stream['extinf'], $stream['url'])) {\n            $content_to_write .= trim($stream['extinf']) . "\\n";\n            $content_to_write .= trim($stream['url']) . "\\n";\n        }\n    }\n    if (file_put_contents($target_path, $content_to_write, FILE_APPEND | LOCK_EX) !== false) {\n        sendResponse(true, 'Streams añadidos correctamente al archivo.', $safe_filename, 200);\n    } else {\n        sendResponse(false, 'Error del servidor: No se pudo añadir contenido al archivo.', '', 500);\n    }\n} else { // Overwrite mode\n    $content_to_write = "#EXTM3U\\n";\n    foreach ($data['streams'] as $stream) {\n        if (isset($stream['extinf'], $stream['url'])) {\n            $content_to_write .= trim($stream['extinf']) . "\\n";\n            $content_to_write .= trim($stream['url']) . "\\n";\n        }\n    }\n    if (file_put_contents($target_path, $content_to_write, LOCK_EX) !== false) {\n        sendResponse(true, 'Archivo de streams sobrescrito correctamente.', $safe_filename, 201);\n    } else {\n        sendResponse(false, 'Error del servidor: No se pudo escribir el archivo.', '', 500);\n    }\n}\n?>`;
        dom.generatedCode.value = script;
        showNotification(_("scriptGenerated"), "success");
    }

    function copyScript() {
        if (!dom.generatedCode.value || dom.generatedCode.value.trim() === '') {
            showNotification(_("errorGeneratingScript"), "warning");
            return;
        }
        navigator.clipboard.writeText(dom.generatedCode.value).then(() => {
            showNotification(_("scriptCopied"), "success");
        }).catch(err => {
            showNotification(_("errorCopyingScript"), "error");
        });
    }

    return { init };
})();

export function initPhotosView() {
    const select = document.getElementById('photos-token-select');
    select.innerHTML = `<option value="">${_('loading')}</option>`;
    
    const photoServers = [...new Map(state.localPhotos.map(item => [item.tokenPrincipal, item])).values()];

    if (photoServers.length === 0) {
        select.innerHTML = `<option value="">${_('noPhotoServers')}</option>`;
        document.getElementById('photos-empty-state').style.display = 'block';
        document.getElementById('photos-grid').innerHTML = '';
        return;
    }
    
    document.getElementById('photos-empty-state').style.display = 'none';

    select.innerHTML = `<option value="">${_('selectServer')}</option>`;
    photoServers.forEach(server => {
        const option = document.createElement('option');
        option.value = server.tokenPrincipal;
        option.textContent = server.serverName || `Servidor ${server.tokenPrincipal.slice(-4)}`;
        select.appendChild(option);
    });

    if (state.currentPhotoToken && photoServers.some(s => s.tokenPrincipal === state.currentPhotoToken)) {
        select.value = state.currentPhotoToken;
    } else {
        select.value = photoServers[0].tokenPrincipal;
    }
    handlePhotoTokenChange();
}

export function handlePhotoTokenChange() {
    const select = document.getElementById('photos-token-select');
    const selectedToken = select.value;
    if (!selectedToken) {
        document.getElementById('photos-grid').innerHTML = '';
        document.getElementById('photos-empty-state').style.display = 'block';
        return;
    }
    
    state.currentPhotoToken = selectedToken;
    state.currentPhotoServer = state.localPhotos.find(s => s.tokenPrincipal === selectedToken);
    
    state.photoStack = [];
    renderPhotoBreadcrumb();
    renderPhotoGrid(state.currentPhotoServer.titulos, 'album');
}

async function fetchPhotoAlbumContent(albumData) {
    const { id, token, ip, puerto, protocolo } = albumData;
    const url = `${protocolo}://${ip}:${puerto}/library/metadata/${id}/children?X-Plex-Token=${token}`;

    try {
        const response = await fetchWithTimeout(url, {}, 10000);
        if (!response.ok) throw new Error(_('errorPlexApi', String(response.status)));

        const data = await response.text();
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(data, "text/xml");
        if (xmlDoc.querySelector('parsererror')) throw new Error(_('errorParsingPlexXml'));

        const photos = Array.from(xmlDoc.querySelectorAll('Photo')).map(el => {
            const media = el.querySelector('Media Part');
            if (!media) return null;
            const key = media.getAttribute('key');
            return {
                type: 'photo',
                id: el.getAttribute('ratingKey'),
                title: el.getAttribute('title') || _('untitled'),
                thumbUrl: `${protocolo}://${ip}:${puerto}/photo/:/transcode?width=400&height=400&minSize=1&upscale=1&url=${encodeURIComponent(key)}&X-Plex-Token=${token}`,
                fullUrl: `${protocolo}://${ip}:${puerto}/photo/:/transcode?width=2000&height=2000&minSize=1&upscale=1&url=${encodeURIComponent(key)}&X-Plex-Token=${token}`
            };
        }).filter(p => p !== null);

        const subAlbums = Array.from(xmlDoc.querySelectorAll('Directory[type="photo"]')).map(el => ({
            type: 'album',
            id: el.getAttribute('ratingKey'),
            title: el.getAttribute('title'),
            count: el.getAttribute('leafCount') || el.getAttribute('childCount'),
        }));

        return [...subAlbums, ...photos];
    } catch (error) {
        showNotification(_('errorLoadingAlbum', error.message), 'error');
        return [];
    }
}

async function loadPhotoAlbum(albumData) {
    const loader = document.getElementById('photos-loader');
    const grid = document.getElementById('photos-grid');
    grid.innerHTML = '';
    loader.style.display = 'block';
    document.getElementById('photos-empty-state').style.display = 'none';

    const items = await fetchPhotoAlbumContent(albumData);
    loader.style.display = 'none';

    if (items.length > 0) {
        renderPhotoGrid(items);
    } else {
        document.getElementById('photos-empty-state').style.display = 'block';
    }
}

export async function handlePhotoGridClick(card) {
    const { type, id, title } = card.dataset;

    if (type === 'album') {
        if (!state.currentPhotoServer) {
            showNotification(_('noPhotoServerSelected'), "error");
            return;
        }
        
        const albumData = {
            ...state.currentPhotoServer,
            id: id,
            title: title
        };

        state.photoStack.push({ id, title });
        renderPhotoBreadcrumb();
        await loadPhotoAlbum(albumData);

    } else if (type === 'photo') {
        const photoIndex = state.currentPhotoItems.findIndex(p => p.id === id);
        if (photoIndex > -1) {
            openPhotoLightbox(photoIndex);
        }
    }
}

function renderPhotoGrid(items, forceType = null) {
    const grid = document.getElementById('photos-grid');
    grid.innerHTML = '';
    document.getElementById('photos-empty-state').style.display = 'none';
    state.currentPhotoItems = [];

    if (!items || items.length === 0) {
        document.getElementById('photos-empty-state').style.display = 'block';
        return;
    }

    const fragment = document.createDocumentFragment();
    items.forEach(item => {
        const type = forceType || item.type;
        const card = document.createElement('div');
        
        if (type === 'album') {
            card.className = 'album-card';
            card.innerHTML = `
                <div class="album-card-icon"><i class="fas fa-folder"></i></div>
                <div class="album-card-title">${item.title}</div>
                ${item.count ? `<div class="album-card-meta">${_('itemCount', String(item.count))}</div>` : ''}
            `;
            card.dataset.type = 'album';
        } else if (type === 'photo') {
            state.currentPhotoItems.push(item);
            card.className = 'photo-card';
            card.innerHTML = `
                <img src="${item.thumbUrl}" alt="${item.title}" class="photo-card-img" loading="lazy">
                <div class="photo-card-caption">${item.title}</div>
            `;
            card.dataset.type = 'photo';
        }

        card.dataset.id = item.id;
        card.dataset.title = item.title;
        fragment.appendChild(card);
    });
    grid.appendChild(fragment);
    setupScrollEffects();
}

function renderPhotoBreadcrumb() {
    const breadcrumb = document.getElementById('photos-breadcrumb');
    breadcrumb.innerHTML = '';

    const rootItem = document.createElement('li');
    rootItem.className = 'breadcrumb-item';
    const rootLink = document.createElement('a');
    rootLink.href = '#';
    rootLink.innerHTML = `<i class="fas fa-home"></i> ${_('photosBreadcrumbHome')}`;
    rootLink.onclick = (e) => {
        e.preventDefault();
        handlePhotoTokenChange();
    };
    rootItem.appendChild(rootLink);
    breadcrumb.appendChild(rootItem);

    state.photoStack.forEach((item, index) => {
        const divider = document.createElement('li');
        divider.className = 'breadcrumb-divider';
        divider.innerHTML = '<i class="fas fa-chevron-right"></i>';
        breadcrumb.appendChild(divider);

        const breadcrumbItem = document.createElement('li');
        breadcrumbItem.className = 'breadcrumb-item';
        if (index === state.photoStack.length - 1) {
            breadcrumbItem.classList.add('active');
            breadcrumbItem.textContent = item.title;
        } else {
            const link = document.createElement('a');
            link.href = '#';
            link.textContent = item.title;
            link.onclick = async (e) => {
                e.preventDefault();
                state.photoStack = state.photoStack.slice(0, index + 1);
                renderPhotoBreadcrumb();
                
                if (!state.currentPhotoServer) return;

                const albumData = { ...state.currentPhotoServer, id: item.id, title: item.title };
                await loadPhotoAlbum(albumData);
            };
            breadcrumbItem.appendChild(link);
        }
        breadcrumb.appendChild(breadcrumbItem);
    });
}

function openPhotoLightbox(startIndex) {
    if (state.currentPhotoItems.length === 0 || startIndex < 0) return;
    state.currentPhotoLightboxIndex = startIndex;
    
    const lightbox = document.getElementById('photo-lightbox');
    document.body.style.overflow = 'hidden';
    updatePhotoLightbox();
    
    gsap.fromTo(lightbox, { autoAlpha: 0 }, { display: 'flex', autoAlpha: 1, duration: 0.3 });
}

export function closePhotoLightbox() {
    const lightbox = document.getElementById('photo-lightbox');
    document.body.style.overflow = '';
    gsap.to(lightbox, { 
        autoAlpha: 0, 
        duration: 0.3, 
        onComplete: () => lightbox.style.display = 'none' 
    });
}

function updatePhotoLightbox() {
    const photo = state.currentPhotoItems[state.currentPhotoLightboxIndex];
    if (!photo) return;
    
    const img = document.getElementById('photo-lightbox-img');
    const caption = document.getElementById('photo-lightbox-caption');
    
    gsap.to([img, caption], {
        autoAlpha: 0,
        duration: 0.15,
        onComplete: () => {
            img.src = photo.fullUrl;
            caption.textContent = photo.title;
            gsap.to([img, caption], { autoAlpha: 1, duration: 0.15 });
        }
    });
}

export function showNextPhoto() {
    state.currentPhotoLightboxIndex = (state.currentPhotoLightboxIndex + 1) % state.currentPhotoItems.length;
    updatePhotoLightbox();
}

export function showPrevPhoto() {
    state.currentPhotoLightboxIndex = (state.currentPhotoLightboxIndex - 1 + state.currentPhotoItems.length) % state.currentPhotoItems.length;
    updatePhotoLightbox();
}



export async function loadProviders() {
    const providers = await fetchAllProviders(state.settings.watchRegion);
    renderProviders(providers);
}
