const API_BASE = '/api';

const DashboardApp = {

    State: {
        currentList: [],
        filteredList: [],
        localLibraryData: [],
        currentUserId: null,
        currentLocalType: 'anime',
        pagination: {
            itemsPerPage: 50,
            visibleCount: 50
        }
    },

    init: async function() {
        console.log('Initializing Dashboard...');
        await this.User.init();
        await this.Tracking.load();

        this.UI.setupTabSystem();
        this.initListeners();

        const localInput = document.getElementById('local-search-input');
        if(localInput) {
            localInput.addEventListener('input', (e) => this.Library.filterContent(e.target.value));
        }
    },

    initListeners: function() {

        document.getElementById('scan-incremental-btn')?.addEventListener('click', () => this.Library.triggerScan('incremental'));
        document.getElementById('scan-full-btn')?.addEventListener('click', () => this.Library.triggerScan('full'));

        document.getElementById('profile-form')?.addEventListener('submit', (e) => this.User.updateProfile(e));
        document.getElementById('password-form')?.addEventListener('submit', (e) => this.User.changePassword(e));
        document.getElementById('logout-btn')?.addEventListener('click', () => window.AuthUtils.logout());

        const fileInput = document.getElementById('avatar-upload');
        if (fileInput) {
            fileInput.addEventListener('change', (e) => {
                const file = e.target.files[0];
                if (file) {
                    const reader = new FileReader();
                    reader.onload = evt => {
                        document.getElementById('user-avatar').src = evt.target.result;
                        const urlInput = document.getElementById('setting-avatar-url');
                        if(urlInput) urlInput.value = '';
                    };
                    reader.readAsDataURL(file);
                }
            });
        }

        const trackingInput = document.getElementById('tracking-search-input');
        if (trackingInput) trackingInput.addEventListener('input', () => this.Tracking.applyFilters());

        ['status-filter', 'type-filter', 'sort-filter'].forEach(id => {
            document.getElementById(id)?.addEventListener('change', () => this.Tracking.applyFilters());
        });

        document.querySelectorAll('.view-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                document.querySelectorAll('.view-btn').forEach(b => b.classList.remove('active'));
                btn.classList.add('active');
                const view = btn.dataset.view;
                const container = document.getElementById('list-container');
                view === 'list' ? container.classList.add('list-view') : container.classList.remove('list-view');
            });
        });
    },

    User: {
        init: async function() {
            try {
                const headers = window.AuthUtils.getSimpleAuthHeaders();
                const res = await fetch(`${API_BASE}/me`, { headers });

                if (res.ok) {
                    const data = await res.json();
                    document.getElementById('user-username').textContent = data.username;
                    const settingUsername = document.getElementById('setting-username');
                    if(settingUsername) settingUsername.value = data.username;

                    if (data.avatar) {
                        document.getElementById('user-avatar').src = data.avatar;
                    }
                }

                const token = localStorage.getItem('token');
                if (token) {
                    const payload = JSON.parse(atob(token.split('.')[1]));
                    DashboardApp.State.currentUserId = payload.id;
                    await this.checkIntegrations(payload.id);
                }
            } catch (err) {
                console.error("Error loading user profile:", err);
            }
        },

        checkIntegrations: async function(userId) {
            if (!userId) return;
            try {
                const res = await fetch(`${API_BASE}/users/${userId}/integration`);
                let data = { connected: false };
                if (res.ok) data = await res.json();

                this.updateIntegrationUI(data, userId);
            } catch (e) { console.error("Integration check error:", e); }
        },

        updateIntegrationUI: function(data, userId) {
            const statusEl = document.getElementById('anilist-status');
            const btn = document.getElementById('anilist-action-btn');
            const headerBadge = document.getElementById('header-anilist-link');

            if (data.connected) {
                if (headerBadge) {
                    headerBadge.style.display = 'flex';
                    headerBadge.href = `https://anilist.co/user/${data.anilistUserId}`;
                    headerBadge.title = `Connected as ${data.anilistUserId}`;
                }
                if (statusEl) {
                    // CAMBIO: Mostrar fecha de expiración si existe
                    const expiresDate = data.expiresAt ? new Date(data.expiresAt).toLocaleDateString() : 'Unknown';
                    statusEl.innerHTML = `
                        <span style="color:var(--color-success)">Connected as: <b>${data.anilistUserId}</b></span>
                        <span style="display:block; font-size:0.75rem; color:#71717a">Expires: ${expiresDate}</span>
                    `;
                }
                if (btn) {
                    btn.textContent = 'Disconnect';
                    btn.className = 'btn-stream-outline link-danger';
                    btn.onclick = () => this.disconnectAniList(userId);
                }
            } else {
                if (headerBadge) headerBadge.style.display = 'none';
                if (statusEl) {
                    statusEl.textContent = 'Not connected';
                    statusEl.style.color = 'var(--color-text-secondary)';
                }
                if (btn) {
                    btn.textContent = 'Connect';
                    btn.className = 'btn-stream-outline';
                    btn.onclick = () => this.openAniListModal();
                }
            }
        },

        redirectToAniListLogin: async function() {
            if (!DashboardApp.State.currentUserId) return;
            try {
                const clientId = 32898;
                const redirectUri = encodeURIComponent(window.location.origin + '/api/anilist');
                const state = encodeURIComponent(DashboardApp.State.currentUserId);
                window.location.href = `https://anilist.co/api/v2/oauth/authorize?client_id=${clientId}&response_type=code&redirect_uri=${redirectUri}&state=${state}`;
            } catch (err) { console.error(err); alert('Error starting AniList login'); }
        },
        openAniListModal: function() {
            const modal = document.getElementById('anilist-connect-modal');
            const body = document.getElementById('anilist-modal-body');
            const clientId = 32898; // Tu Client ID

            // Generamos el HTML del modal dinámicamente
            body.innerHTML = `
                <p class="modal-description">Connect your AniList account to sync your progress automatically.</p>
                
                <div style="margin-bottom: 1.5rem;">
                    <label style="display:block; font-size:0.85rem; font-weight:600; color:#a1a1aa; margin-bottom:0.5rem">Step 1: Get Token</label>
                    <a href="https://anilist.co/api/v2/oauth/authorize?client_id=${clientId}&response_type=token" 
                       target="_blank" 
                       class="btn-blur" 
                       style="width:100%; text-align:center; box-sizing:border-box; display:block;">
                       Open AniList Login ↗
                    </a>
                </div>

                <div class="input-group">
                    <label>Step 2: Paste Token</label>
                    <input type="text" id="manual-anilist-token" class="stream-input" placeholder="Paste the long access token here..." autocomplete="off">
                </div>

                <div class="modal-footer" style="padding:0; background:transparent;">
                    <button class="btn-primary" style="width:100%" onclick="DashboardApp.User.submitAniListToken()">Verify & Connect</button>
                </div>
            `;

            modal.classList.remove('hidden');
        },

        closeAniListModal: function() {
            document.getElementById('anilist-connect-modal').classList.add('hidden');
        },

        submitAniListToken: async function() {
            const tokenInput = document.getElementById('manual-anilist-token');
            const token = tokenInput.value.trim();
            const userId = DashboardApp.State.currentUserId;

            if (!token) {
                alert('Please paste the AniList token first');
                return;
            }

            const confirmBtn = document.querySelector('#anilist-connect-modal .btn-primary');
            const originalText = confirmBtn.textContent;
            confirmBtn.textContent = "Verifying...";
            confirmBtn.disabled = true;

            try {
                const res = await fetch(`${API_BASE}/anilist/store`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        userId: userId,
                        accessToken: token
                    })
                });

                const data = await res.json();

                if (!res.ok) throw new Error(data.error || 'Failed to verify token');

                this.closeAniListModal();
                await this.checkIntegrations(userId);
                alert('AniList connected successfully!');

            } catch (err) {
                console.error(err);
                alert(err.message || 'Invalid Token');
            } finally {
                confirmBtn.textContent = originalText;
                confirmBtn.disabled = false;
            }
        },

        disconnectAniList: async function(userId) {
            if(!confirm("Disconnect AniList?")) return;
            try {
                const token = localStorage.getItem('token');
                await fetch(`${API_BASE}/users/${userId}/integration`, {
                    method: 'DELETE',
                    headers: { 'Authorization': `Bearer ${token}` }
                });
                this.checkIntegrations(userId);
            } catch (e) { alert("Failed to disconnect"); }
        },

        updateProfile: async function(e) {
            e.preventDefault();
            const userId = DashboardApp.State.currentUserId;
            if (!userId) return;

            const username = document.getElementById('setting-username').value;
            const urlInput = document.getElementById('setting-avatar-url')?.value || '';
            const fileInput = document.getElementById('avatar-upload');
            let finalAvatar = null;

            if (fileInput && fileInput.files && fileInput.files[0]) {
                try {
                    finalAvatar = await DashboardApp.Utils.fileToBase64(fileInput.files[0]);
                } catch (err) { alert("Error reading file"); return; }
            } else if (urlInput.trim() !== "") {
                finalAvatar = urlInput.trim();
            }

            const bodyData = { username };
            if (finalAvatar) bodyData.profilePictureUrl = finalAvatar;

            try {
                const res = await fetch(`${API_BASE}/users/${userId}`, {
                    method: 'PUT',
                    headers: { ...window.AuthUtils.getSimpleAuthHeaders(), 'Content-Type': 'application/json' },
                    body: JSON.stringify(bodyData)
                });
                if (res.ok) alert('Profile updated successfully!');
                else { const err = await res.json(); alert(err.error || 'Update failed'); }
            } catch (e) { console.error(e); }
        },

        changePassword: async function(e) {
            e.preventDefault();
            const userId = DashboardApp.State.currentUserId;
            if (!userId) return;
            const currentPassword = document.getElementById('current-password').value;
            const newPassword = document.getElementById('new-password').value;

            try {
                const res = await fetch(`${API_BASE}/users/${userId}/password`, {
                    method: 'PUT',
                    headers: { ...window.AuthUtils.getSimpleAuthHeaders(), 'Content-Type': 'application/json' },
                    body: JSON.stringify({ currentPassword, newPassword })
                });
                const data = await res.json();
                if (res.ok) { alert("Password updated successfully"); document.getElementById('password-form').reset(); }
                else alert(data.error || "Failed to update password");
            } catch (e) { console.error(e); }
        }
    },

    Tracking: {
        load: async function() {
            const loadingState = document.getElementById('loading-state');
            const emptyState = document.getElementById('empty-state');
            const container = document.getElementById('list-container');

            try {
                loadingState.style.display = 'flex';
                emptyState.style.display = 'none';
                container.innerHTML = '';

                const response = await fetch(`${API_BASE}/list`, { headers: window.AuthUtils.getSimpleAuthHeaders() });
                if (!response.ok) throw new Error('Failed');

                const data = await response.json();
                DashboardApp.State.currentList = data.results || [];

                this.updateStats();

                loadingState.style.display = 'none';
                if (DashboardApp.State.currentList.length === 0) emptyState.style.display = 'flex';
                else this.applyFilters();

            } catch (error) {
                console.error(error);
                loadingState.style.display = 'none';
            }
        },

        updateStats: function() {
            const list = DashboardApp.State.currentList;
            const animeCount = list.filter(item => item.entry_type === 'ANIME').length;
            const mangaCount = list.filter(item => item.entry_type === 'MANGA').length;

            document.getElementById('total-stat').textContent = list.length;
            if (document.getElementById('anime-stat')) document.getElementById('anime-stat').textContent = animeCount;
            if (document.getElementById('manga-stat')) document.getElementById('manga-stat').textContent = mangaCount;
        },

        applyFilters: function() {
            const statusFilter = document.getElementById('status-filter').value;
            const typeFilter = document.getElementById('type-filter').value;
            const sortFilter = document.getElementById('sort-filter').value;
            const searchInput = document.getElementById('tracking-search-input');
            const searchQuery = searchInput ? searchInput.value.toLowerCase().trim() : '';

            let result = [...DashboardApp.State.currentList];

            if (searchQuery) {
                result = result.filter(item => (item.title ? item.title.toLowerCase() : '').includes(searchQuery));
            }

            if (statusFilter !== 'all') result = result.filter(item => item.status === statusFilter);
            if (typeFilter !== 'all') result = result.filter(item => item.entry_type === typeFilter);

            if (sortFilter === 'title') result.sort((a, b) => (a.title || '').localeCompare(b.title || ''));
            else if (sortFilter === 'score') result.sort((a, b) => (b.score || 0) - (a.score || 0));
            else result.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at));

            DashboardApp.State.filteredList = result;
            DashboardApp.State.pagination.visibleCount = DashboardApp.State.pagination.itemsPerPage;
            this.render();
        },

        render: function() {
            const container = document.getElementById('list-container');
            container.innerHTML = '';
            const list = DashboardApp.State.filteredList;
            const count = DashboardApp.State.pagination.visibleCount;

            if (list.length === 0) {
                container.innerHTML = '<div class="empty-text" style="grid-column: 1/-1; text-align:center; color: var(--color-text-secondary);">No matches found</div>';
                return;
            }

            const itemsToShow = list.slice(0, count);
            itemsToShow.forEach(item => container.appendChild(this.createItemElement(item)));

            if (count < list.length) {
                this.renderLoadMoreButton(container, list.length - count);
            }
        },

        createItemElement: function(item) {
            const div = document.createElement('div');
            div.className = 'list-item';

            const itemLink = this.getEntryLink(item);
            const posterUrl = item.poster || '/public/assets/placeholder.svg';
            const progress = item.progress || 0;
            const totalUnits = item.entry_type === 'ANIME' ? item.total_episodes || 0 : item.total_chapters || 0;
            const progressPercent = totalUnits > 0 ? (progress / totalUnits) * 100 : 0;
            const score = item.score ? item.score.toFixed(1) : null;
            const entryType = (item.entry_type).toUpperCase();

            const statusLabels = {
                'CURRENT': entryType === 'ANIME' ? 'Watching' : 'Reading',
                'COMPLETED': 'Completed', 'PLANNING': 'Planning', 'PAUSED': 'Paused',
                'DROPPED': 'Dropped', 'REPEATING': entryType === 'ANIME' ? 'Rewatching' : 'Rereading'
            };

            const extraInfo = [];
            if (item.repeat_count > 0) extraInfo.push(`<span class="meta-pill repeat-pill">🔁 ${item.repeat_count}</span>`);
            if (item.is_private) extraInfo.push('<span class="meta-pill private-pill">🔒 Private</span>');

            div.innerHTML = `
                <a href="${itemLink}" class="item-poster-link">
                    <img src="${posterUrl}" alt="${item.title}" class="item-poster" onerror="this.src='/public/assets/placeholder.svg'">
                </a>
                <div class="item-content">
                    <div>
                        <a href="${itemLink}" style="text-decoration:none; color:inherit;">
                            <h3 class="item-title">${item.title || 'Unknown'}</h3>
                        </a>
                        <div class="item-meta">
                            <span class="meta-pill status-pill">${statusLabels[item.status] || item.status}</span>
                            <span class="meta-pill type-pill">${entryType}</span> 
                            <span class="meta-pill source-pill">${item.source.toUpperCase()}</span>
                            ${extraInfo.join('')}
                        </div>
                    </div>
                    <div>
                        <div class="progress-bar-container"><div class="progress-bar" style="width: ${progressPercent}%"></div></div>
                        <div class="progress-text">
                            <span>${progress}${totalUnits > 0 ? ` / ${totalUnits}` : ''}</span> 
                            ${score ? `<span class="score-badge">⭐ ${score}</span>` : ''}
                        </div>
                    </div>
                </div>
                <button class="edit-icon-btn">
                    <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path d="M15.232 5.232l3.536 3.536m-2.036-5.808a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.536L15.232 5.232z"/></svg>
                </button>
            `;

            div.querySelector('.edit-icon-btn').onclick = (e) => {
                e.preventDefault(); e.stopPropagation();
                window.ListModalManager.currentData = item;
                window.ListModalManager.isInList = true;
                window.ListModalManager.currentEntry = item;
                window.ListModalManager.open(item, item.source || 'anilist');
            };

            return div;
        },

        renderLoadMoreButton: function(container, remaining) {
            const btnContainer = document.createElement('div');
            Object.assign(btnContainer.style, { gridColumn: "1 / -1", display: "flex", justifyContent: "center", padding: "2rem 0" });

            const loadMoreBtn = document.createElement('button');
            loadMoreBtn.className = "btn-blur";
            loadMoreBtn.textContent = `Show All (${remaining} more)`;
            loadMoreBtn.onclick = () => {
                DashboardApp.State.pagination.visibleCount = DashboardApp.State.filteredList.length;
                this.render();
            };

            btnContainer.appendChild(loadMoreBtn);
            container.appendChild(btnContainer);
        },

        getEntryLink: function(item) {
            const baseRoute = (item.entry_type?.toUpperCase() === 'ANIME') ? '/anime' : '/book';
            return `${baseRoute}/${item.entry_id}`;
        }
    },

    Library: {
        tempMatchContext: null,
        pollInterval: null,
        updateDownloadStatus: async function() {
            try {
                const res = await fetch(`${API_BASE}/library/downloads/status`, {
                    headers: window.AuthUtils.getSimpleAuthHeaders()
                });

                if (!res.ok) return;

                const data = await res.json();
                this.renderDownloadMonitor(data);

                // Si hay descargas completadas nuevas, podríamos recargar la lista de archivos
                // (Opcional: lógica para detectar cambios y llamar a loadContent)

            } catch (e) {
                console.error("Error polling downloads:", e);
            }
        },

        renderDownloadMonitor: function(data) {
            const monitor = document.getElementById('downloads-monitor');
            const listContainer = document.getElementById('downloads-list-container');
            const activeCountEl = document.getElementById('dl-stat-active');

            // Datos por defecto
            const downloads = data.downloads || { list: [], active: 0, failed: 0 };

            // Actualizar contadores cabecera
            if(activeCountEl) activeCountEl.textContent = `${downloads.active} Active / ${downloads.list.length} Total`;

            // Ocultar si vacío
            if (downloads.list.length === 0) {
                monitor.classList.add('hidden');
                return;
            }

            monitor.classList.remove('hidden');

            listContainer.innerHTML = downloads.list.map(item => {
                const fileName = item.fileName || `Unknown_File_${item.unitNumber}`;
                const folderName = item.folderName || 'Unsorted';
                const status = item.status || 'pending';
                const progress = item.progress || 0;
                const speed = item.speed || '0 KB/s';

                const isCompleted = status === 'completed';
                const isFailed = status === 'failed';

                let statusText = `${progress}%`;
                if (isCompleted) statusText = 'Done';
                if (isFailed) statusText = 'Failed';

                const folderIcon = `<svg width="12" height="12" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>`;

                // ESTRUCTURA NUEVA: Más plana para permitir Flexbox horizontal
                return `
            <div class="dl-item compact">
                <div class="dl-left-col">
                    <div class="dl-filename" title="${fileName}">${fileName}</div>
                    <div class="dl-folder" title="${folderName}">${folderIcon} ${folderName}</div>
                </div>
                
                <div class="dl-right-col">
                    <div class="dl-meta-info">
                        <span class="dl-speed">${isCompleted ? '' : speed}</span>
                        <span class="dl-status-text ${status}">${statusText}</span>
                    </div>
                    <div class="dl-progress-track">
                        <div class="dl-progress-fill ${status}" style="width: ${progress}%"></div>
                    </div>
                </div>
            </div>
        `;
            }).join('');
        },

        startPolling: function() {
            if (this.pollInterval) clearInterval(this.pollInterval);
            this.updateDownloadStatus(); // Primera llamada inmediata
            this.pollInterval = setInterval(() => this.updateDownloadStatus(), 2000); // Cada 2 segundos
        },

        stopPolling: function() {
            if (this.pollInterval) {
                clearInterval(this.pollInterval);
                this.pollInterval = null;
            }
        },
        loadStats: async function() {
            const types = ['anime', 'manga', 'novels'];
            const elements = { 'anime': 'local-anime-count', 'manga': 'local-manga-count', 'novels': 'local-novel-count' };

            for (const type of types) {
                try {
                    const res = await fetch(`${API_BASE}/library/${type}`, { headers: window.AuthUtils.getSimpleAuthHeaders() });
                    if(res.ok) {
                        const data = await res.json();
                        const el = document.getElementById(elements[type]);
                        if (el) el.textContent = `${data.length} items`;
                    }
                } catch (e) { console.error(e); }
            }
        },

        loadContent: async function(type) {
            DashboardApp.State.currentLocalType = type;
            const container = document.getElementById('local-list-container');
            const loading = document.getElementById('local-loading');
            const searchInput = document.getElementById('local-search-input');

            container.innerHTML = '';
            loading.style.display = 'flex';
            if(searchInput) searchInput.value = '';

            try {
                const res = await fetch(`${API_BASE}/library/${type}`, { headers: window.AuthUtils.getSimpleAuthHeaders() });
                if (!res.ok) throw new Error('Failed to load local content');

                const data = await res.json();
                DashboardApp.State.localLibraryData = data;
                this.renderGrid(data, type);
            } catch (err) {
                console.error(err);
                container.innerHTML = `<div class="empty-state"><p>Error loading library</p></div>`;
            } finally {
                loading.style.display = 'none';
            }
        },

        renderGrid: function(entries, type) {
            const container = document.getElementById('local-list-container');
            container.innerHTML = '';

            if (entries.length === 0) {
                container.innerHTML = `
                    <div class="empty-state" style="grid-column: 1/-1;">
                        <p>No ${type} files found.</p>
                        <button onclick="DashboardApp.Library.triggerScan('incremental')" class="btn-blur">Scan Now</button>
                    </div>`;
                return;
            }

            entries.forEach(entry => {
                const isMatched = entry.matched && entry.metadata;
                const meta = entry.metadata || {};
                let poster = meta.coverImage?.large || '/public/assets/placeholder.svg';

                let title = isMatched ? (meta.title?.english || meta.title?.romaji) : entry.path;
                if (!isMatched) title = title.replace(/\[.*?\]|\(.*?\)|\.mkv|\.mp4/g, '').trim();

                const url = isMatched ? (type === 'anime' ? `/anime/${meta.id}` : `/book/${meta.id}`) : '#';

                const div = document.createElement('div');
                div.className = 'list-item';
                div.innerHTML = `
                    <div class="item-poster-link" onclick="${isMatched ? `window.location='${url}'` : ''}" style="cursor: ${isMatched ? 'pointer' : 'default'}">
                        <img src="${poster}" class="item-poster" loading="lazy">
                        ${!isMatched ? `<div class="unmatched-badge"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><path d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg> UNMATCHED</div>` : ''}
                    </div>
                    <div class="item-content">
                        <h3 class="item-title" title="${entry.path}">${title}</h3>
                        <div class="item-meta">
                             <span class="meta-pill type-pill">${entry.files} FILES</span>
                             ${isMatched ? '<span class="meta-pill status-pill">MATCHED</span>' : ''}
                        </div>
                        <div class="folder-path-tooltip">${entry.path}</div>
                    </div>
                    <button class="edit-icon-btn" onclick="DashboardApp.Library.openManualMatch('${entry.id}', '${type}')" title="${isMatched ? 'Rematch' : 'Fix Match'}">
                        <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/></svg>
                    </button>
                `;
                container.appendChild(div);
            });
        },

        filterContent: function(query) {
            if (!DashboardApp.State.localLibraryData) return;
            const lowerQuery = query.toLowerCase();
            const filtered = DashboardApp.State.localLibraryData.filter(entry => {
                const metaTitle = entry.metadata?.title?.english || entry.metadata?.title?.romaji || '';
                const folderName = entry.folder_name || '';
                return metaTitle.toLowerCase().includes(lowerQuery) || folderName.toLowerCase().includes(lowerQuery);
            });
            this.renderGrid(filtered, DashboardApp.State.currentLocalType);
        },

        triggerScan: async function(mode) {
            const consoleDiv = document.getElementById('scan-console');
            const statusText = document.getElementById('scan-status-text');
            if(consoleDiv) consoleDiv.style.display = 'flex';
            if(statusText) statusText.textContent = `Starting ${mode} scan...`;

            try {
                const res = await fetch(`${API_BASE}/library/scan?mode=${mode}`, {
                    method: 'POST', headers: window.AuthUtils.getSimpleAuthHeaders()
                });
                if (res.ok) {
                    if(statusText) statusText.textContent = "Scan completed successfully!";
                    setTimeout(() => { if(consoleDiv) consoleDiv.style.display = 'none'; this.loadStats(); }, 3000);
                } else throw new Error('Scan failed');
            } catch (e) {
                if(statusText) { statusText.textContent = "Error during scan."; statusText.style.color = 'var(--color-danger)'; }
            }
        },

        openManualMatch: function(id, type) {
            const item = DashboardApp.State.localLibraryData.find(x => x.id === id);
            const pathName = item ? item.path : 'Unknown path';

            this.tempMatchContext = { id, type };

            document.getElementById('manual-match-path').textContent = pathName;
            document.getElementById('manual-match-id').value = '';

            const modal = document.getElementById('manual-match-modal');
            modal.classList.remove('hidden');

            setTimeout(() => document.getElementById('manual-match-id').focus(), 100);
        },

        closeManualMatch: function() {
            document.getElementById('manual-match-modal').classList.add('hidden');
            this.tempMatchContext = null;
        },

        submitManualMatch: async function() {
            if (!this.tempMatchContext) return;

            const newId = document.getElementById('manual-match-id').value;
            if (!newId) {
                alert("Please enter a valid ID");
                return;
            }

            const { id, type } = this.tempMatchContext;

            const confirmBtn = document.querySelector('#manual-match-modal .btn-primary');
            const originalText = confirmBtn.textContent;
            confirmBtn.textContent = "Matching...";
            confirmBtn.disabled = true;

            try {
                const res = await fetch(`${API_BASE}/library/${type}/${id}/match`, {
                    method: 'POST',
                    headers: {
                        ...window.AuthUtils.getSimpleAuthHeaders(),
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        source: 'anilist',
                        matched_id: parseInt(newId)
                    })
                });

                if(res.ok) {
                    this.closeManualMatch();
                    this.loadContent(type);
                } else {
                    const errData = await res.json();
                    alert("Failed to match: " + (errData.error || "Unknown error"));
                }
            } catch (e) {
                console.error(e);
                alert("Connection error");
            } finally {
                confirmBtn.textContent = originalText;
                confirmBtn.disabled = false;
            }
        },

        switchType: function(type, btnElement) {
            document.querySelectorAll('.type-pill-btn').forEach(b => b.classList.remove('active'));
            if(btnElement) btnElement.classList.add('active');
            this.loadContent(type);
        }
    },

    UI: {
        setupTabSystem: function() {
            const tabs = document.querySelectorAll('.nav-pill');
            const sections = document.querySelectorAll('.tab-section');

            tabs.forEach(tab => {
                tab.addEventListener('click', () => {
                    // Gestión de clases activas
                    tabs.forEach(t => t.classList.remove('active'));
                    tab.classList.add('active');

                    const targetId = `section-${tab.dataset.target}`;
                    sections.forEach(sec => {
                        sec.classList.remove('active');
                        if (sec.id === targetId) sec.classList.add('active');
                    });

                    // Lógica específica por pestaña
                    if (tab.dataset.target === 'local') {
                        DashboardApp.Library.loadStats();
                        DashboardApp.Library.loadContent(DashboardApp.State.currentLocalType || 'anime');
                        DashboardApp.Library.startPolling(); // <--- INICIAR POLLING
                    } else {
                        DashboardApp.Library.stopPolling(); // <--- DETENER POLLING AL SALIR
                    }
                });
            });
        }
    },

    Utils: {
        fileToBase64: (file) => new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => resolve(reader.result);
            reader.onerror = error => reject(error);
        })
    }
};

document.addEventListener('DOMContentLoaded', () => {
    DashboardApp.init();
});

window.switchLocalType = (type, btn) => DashboardApp.Library.switchType(type, btn);

window.saveToList = async () => {
    const data = window.ListModalManager.currentData;
    if (!data) return;
    const idToSave = data.entry_id || data.id;
    await window.ListModalManager.save(idToSave, data.source || 'anilist');
    await DashboardApp.Tracking.load();
};

window.deleteFromList = async () => {
    const data = window.ListModalManager.currentData;
    if (!data) return;
    const idToDelete = data.entry_id || data.id;
    await window.ListModalManager.delete(idToDelete, data.source || 'anilist');
    await DashboardApp.Tracking.load();
};

window.closeAddToListModal = () => window.ListModalManager.close();