const providerSelector = document.getElementById('provider-selector');
const searchInput = document.getElementById('search-input');
const resultsContainer = document.getElementById('gallery-results');

let currentPage = 1;
let currentProvider = '';
let currentQuery = '';
const perPage = 48;
let isLoading = false;
let favorites = new Set();
let favoritesMode = false;

let msnry = null;

const sentinel = document.createElement('div');
sentinel.id = 'infinite-scroll-sentinel';
sentinel.style.height = '1px';
sentinel.style.marginBottom = '300px';
sentinel.style.display = 'none';
resultsContainer.parentNode.appendChild(sentinel);

function getAuthHeaders(extra = {}) {
    const token = localStorage.getItem("token");
    return token
        ? { ...extra, Authorization: `Bearer ${token}` }
        : extra;
}

function initializeMasonry() {
    if (typeof Masonry === 'undefined') {
        setTimeout(initializeMasonry, 100);
        return;
    }
    if (msnry) msnry.destroy();
    msnry = new Masonry(resultsContainer, {
        itemSelector: '.gallery-card',
        columnWidth: '.gallery-card',
        percentPosition: true,
        gutter: 0,
        transitionDuration: '0.4s'
    });
    msnry.layout();
}
initializeMasonry();

function getTagsArray(item) {
    if (Array.isArray(item.tags)) return item.tags;
    if (typeof item.tags === 'string') {
        return item.tags
            .split(',')
            .map(t => t.trim())
            .filter(t => t.length > 0);
    }
    return [];
}

function getProxiedImageUrl(item) {
    const imageUrl = item.image || item.image_url;

    if (!imageUrl || !item.headers) {
        return imageUrl;
    }

    let proxyUrl = `/api/proxy?url=${encodeURIComponent(imageUrl)}`;

    const headers = item.headers;
    const lowerCaseHeaders = {};
    for (const key in headers) {
        if (Object.prototype.hasOwnProperty.call(headers, key)) {
            lowerCaseHeaders[key.toLowerCase()] = headers[key];
        }
    }

    const referer = lowerCaseHeaders.referer;
    if (referer) {
        proxyUrl += `&referer=${encodeURIComponent(referer)}`;
    }

    const origin = lowerCaseHeaders.origin;
    if (origin) {
        proxyUrl += `&origin=${encodeURIComponent(origin)}`;
    }

    const userAgent = lowerCaseHeaders['user-agent'];
    if (userAgent) {
        proxyUrl += `&userAgent=${encodeURIComponent(userAgent)}`;
    }

    return proxyUrl;
}

async function loadFavorites() {
    try {
        const res = await fetch('/api/gallery/favorites', {
            headers: getAuthHeaders()
        });
        if (!res.ok) return;
        const data = await res.json();
        favorites.clear();
        (data.favorites || []).forEach(fav => favorites.add(fav.id));
    } catch (err) {
        console.error('Error loading favorites:', err);
    }
}

async function toggleFavorite(item) {
    const id = item.id;
    const isFav = favorites.has(id);

    try {
        if (isFav) {
            await fetch(`/api/gallery/favorites/${encodeURIComponent(id)}`, {
                method: 'DELETE',
                headers: getAuthHeaders()
            });
            favorites.delete(id);
        } else {
            const tagsArray = getTagsArray(item);

            const serializedHeaders = item.headers ? JSON.stringify(item.headers) : "";

            await fetch('/api/gallery/favorites', {
                method: 'POST',
                headers: getAuthHeaders({
                    'Content-Type': 'application/json'
                }),
                body: JSON.stringify({
                    id: item.id,
                    title: item.title || tagsArray.join(', ') || 'Untitled',
                    image_url: item.image || item.image_url,
                    thumbnail_url: item.image || item.image_url,
                    tags: tagsArray.join(','),
                    provider: item.provider || "",
                    headers: serializedHeaders
                })
            });


            favorites.add(id);
        }

        document.querySelectorAll(`.gallery-card[data-id="${CSS.escape(id)}"] .fav-btn`).forEach(btn => {
            btn.classList.toggle('favorited', !isFav);
            btn.innerHTML = !isFav
                ? '<i class="fas fa-heart"></i>'
                : '<i class="far fa-heart"></i>';
        });

        if (providerSelector.value === 'favorites' && isFav) {
            setTimeout(() => searchGallery(false), 300);
        }

    } catch (err) {
        console.error('Error toggling favorite:', err);
        alert('Error updating favorite');
    }
}

function createGalleryCard(item, isLoadMore = false) {
    const card = document.createElement('a');
    card.className = 'gallery-card grid-item';
    card.href = `/gallery/${item.provider || currentProvider || 'unknown'}/${encodeURIComponent(item.id)}`;
    card.dataset.id = item.id;

    const img = document.createElement('img');
    img.className = 'gallery-card-img';

    img.src = getProxiedImageUrl(item);
    img.alt = getTagsArray(item).join(', ') || 'Image';
    if (isLoadMore) {
        img.loading = 'lazy';
    }

    const favBtn = document.createElement('button');
    favBtn.className = 'fav-btn';
    const isFav = favorites.has(item.id);
    favBtn.classList.toggle('favorited', isFav);
    favBtn.innerHTML = isFav ? '<i class="fas fa-heart"></i>' : '<i class="far fa-heart"></i>';
    favBtn.onclick = (e) => {
        e.preventDefault();
        e.stopPropagation();
        toggleFavorite(item);
    };

    card.appendChild(favBtn);
    card.appendChild(img);

    if (currentProvider !== 'favorites') {
        const badge = document.createElement('div');
        badge.className = 'provider-badge';
        badge.textContent = item.provider || 'Global';
        card.appendChild(badge);
    } else {
        const badge = document.createElement('div');
        badge.className = 'provider-badge';
        badge.textContent = 'Favorites';
        badge.style.background = 'rgba(255,107,107,0.7)';
        card.appendChild(badge);
    }

    img.onload = img.onerror = () => {
        card.classList.add('is-loaded');
        if (msnry) msnry.layout();
    };

    return card;
}

function showSkeletons(count, append = false) {
    const skeleton = `<div class="gallery-card skeleton grid-item"><div class="poster-skeleton"></div></div>`;
    if (!append) {
        resultsContainer.innerHTML = '';
        initializeMasonry();
    }
    const elements = [];
    for (let i = 0; i < count; i++) {
        const div = document.createElement('div');
        div.innerHTML = skeleton;
        const el = div.firstChild;
        resultsContainer.appendChild(el);
        elements.push(el);
    }
    if (msnry) {
        msnry.appended(elements);
        msnry.layout();
    }
    sentinel.style.display = 'none';
    observer.unobserve(sentinel);
}

async function searchGallery(isLoadMore = false) {
    if (isLoading) return;

    const query = searchInput.value.trim();
    const provider = providerSelector.value;
    const page = isLoadMore ? currentPage + 1 : 1;

    favoritesMode = (provider === 'favorites');

    currentQuery = query;
    currentProvider = provider;

    if (!isLoadMore) {
        currentPage = 1;
        showSkeletons(perPage);
    } else {
        showSkeletons(8, true);
    }

    isLoading = true;

    try {
        let data;

        if (favoritesMode) {
            const res = await fetch('/api/gallery/favorites', {
                headers: getAuthHeaders()
            });
            data = await res.json();

            let favoritesResults = data.favorites || [];
            if (query) {
                const lowerQuery = query.toLowerCase();
                favoritesResults = favoritesResults.filter(fav =>
                    (fav.title && fav.title.toLowerCase().includes(lowerQuery)) ||
                    (fav.tags && fav.tags.toLowerCase().includes(lowerQuery))
                );
            }

            data.results = favoritesResults.map(fav => ({
                id: fav.id,
                image: fav.image_url,
                image_url: fav.image_url,
                provider: fav.provider,
                tags: fav.tags
            }));
            data.hasNextPage = false;

        } else if (provider && provider !== '') {
            const res = await fetch(`/api/gallery/search/provider?provider=${provider}&q=${encodeURIComponent(query)}&page=${page}&perPage=${perPage}`);
            data = await res.json();
        } else {
            const res = await fetch(`/api/gallery/search?q=${encodeURIComponent(query)}&page=${page}&perPage=${perPage}`);
            data = await res.json();
        }

        const results = data.results || [];

        const skeletons = resultsContainer.querySelectorAll('.gallery-card.skeleton');
        const toRemove = isLoadMore ? Array.from(skeletons).slice(-8) : skeletons;
        if (msnry) msnry.remove(toRemove);
        toRemove.forEach(el => el.remove());

        const newCards = results.map((item, index) => createGalleryCard(item, isLoadMore));
        newCards.forEach(card => resultsContainer.appendChild(card));
        if (msnry) msnry.appended(newCards);

        if (results.length === 0 && !isLoadMore) {
            const msg = favoritesMode
                ? (query ? 'No favorites found matching your search' : 'You don\'t have any favorite images yet')
                : 'No results found';
            resultsContainer.innerHTML = `<p style="text-align:center;color:var(--color-text-secondary);padding:4rem;font-size:1.1rem;">${msg}</p>`;
        }

        if (msnry) msnry.layout();

        if (!favoritesMode && data.hasNextPage) {
            sentinel.style.display = 'block';
            observer.observe(sentinel);
        } else {
            sentinel.style.display = 'none';
            observer.unobserve(sentinel);
        }

        if (isLoadMore) currentPage++;
        else currentPage = 1;

    } catch (err) {
        console.error('Error:', err);
        if (!isLoadMore) {
            resultsContainer.innerHTML = '<p style="text-align:center;color:red;padding:4rem;">Error loading gallery</p>';
        }
    } finally {
        isLoading = false;
    }
}

async function loadExtensions() {
    try {
        const res = await fetch('/api/extensions/gallery');
        const data = await res.json();

        providerSelector.innerHTML = '';

        const favoritesOption = document.createElement('option');
        favoritesOption.value = 'favorites';
        favoritesOption.textContent = 'Favorites';
        providerSelector.appendChild(favoritesOption);

        (data.extensions || []).forEach(ext => {
            const opt = document.createElement('option');
            opt.value = ext;
            opt.textContent = ext.charAt(0).toUpperCase() + ext.slice(1);
            providerSelector.appendChild(opt);
        });

    } catch (err) {
        console.error('Error loading extensions:', err);
    }
}

providerSelector.addEventListener('change', () => {
    if (providerSelector.value === 'favorites') {
        searchInput.placeholder = "Search in favorites...";
    } else {
        searchInput.placeholder = "Search in gallery...";
    }
    searchGallery(false);
});

let searchTimeout;

searchInput.addEventListener('input', () => {
    clearTimeout(searchTimeout);
    searchTimeout = setTimeout(() => {
        searchGallery(false);
    }, 500);
});
searchInput.addEventListener('keydown', e => {
    if (e.key === 'Enter') {
        clearTimeout(searchTimeout);
        searchGallery(false);
    }
});

const observer = new IntersectionObserver(entries => {
    if (entries[0].isIntersecting && !isLoading && !favoritesMode) {
        observer.unobserve(sentinel);
        searchGallery(true);
    }
}, { rootMargin: '1000px' });

loadFavorites().then(() => {
    loadExtensions().then(() => {
        searchGallery(false);
    });
});

window.addEventListener('scroll', () => {
    document.getElementById('navbar')?.classList.toggle('scrolled', window.scrollY > 50);
});