document.addEventListener('DOMContentLoaded', () => {
    loadComponents().then(() => {
        initSkillIssueTicker();
        initCryptoCopier();
    });

    loadRecentPosts();
    initTypingEffect();
    initScrollReveal();
    initScrollParallax();

    if (document.getElementById('sec-grid')) {
        initSearchableGrid('sec', 'sec-grid', 'sec-search');
    }
    if (document.getElementById('magic-grid')) {
        initSearchableGrid('magic', 'magic-grid', 'magic-search');
    }
});

function initScrollParallax() {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;

    const root = document.documentElement;
    let scrollY = 0;
    let ticking = false;

    function update() {
        root.style.setProperty('--scroll', scrollY);
        ticking = false;
    }

    window.addEventListener('scroll', () => {
        scrollY = window.scrollY || window.pageYOffset || 0;
        if (!ticking) {
            requestAnimationFrame(update);
            ticking = true;
        }
    }, { passive: true });
}

async function loadComponents() {
    try {
        const headerRes = await fetch('components/header.html');
        if (headerRes.ok) {
            let headerHtml = await headerRes.text();
            headerHtml = headerHtml.replaceAll('{{prefix}}', '');
            const headerEl = document.querySelector('header');
            if (headerEl) headerEl.innerHTML = headerHtml;
        }

        const footerRes = await fetch('components/footer.html');
        if (footerRes.ok) {
            const footerEl = document.querySelector('footer');
            if (footerEl) footerEl.innerHTML = await footerRes.text();
        }
    } catch (e) {
        console.error('Component load error:', e);
    }
}

function initScrollReveal() {
    const sections = document.querySelectorAll('main > section');
    sections.forEach(section => {
        if (!section.classList.contains('hero')) {
            section.classList.add('reveal');
        }
    });

    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                entry.target.classList.add('in-view');
                observer.unobserve(entry.target);
            }
        });
    }, { threshold: 0.12, rootMargin: '0px 0px -60px 0px' });

    document.querySelectorAll('.reveal, .reveal-stagger, main > section').forEach(el => {
        observer.observe(el);
    });
}

function attachStaggerObserver(root) {
    if (!root) return;
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                entry.target.classList.add('in-view');
                observer.unobserve(entry.target);
            }
        });
    }, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
    observer.observe(root);
}

function initTypingEffect() {
    const el = document.querySelector('.hero-typed');
    if (!el) return;

    const text = "My Computer Science notes, mostly focused on trying to master cybersecurity.";
    let index = 0;

    function type() {
        if (index < text.length) {
            el.textContent += text[index];
            index++;
            setTimeout(type, 28 + Math.random() * 35);
        } else {
            el.classList.add('done');
        }
    }

    setTimeout(type, 700);
}

async function loadRecentPosts() {
    const container = document.getElementById('post-container');
    if (!container) return;

    try {
        const response = await fetch('/api/collections/cases/records?sort=-created');
        if (!response.ok) throw new Error('Status: ' + response.status);

        const data = await response.json();
        const posts = (data.items || []).slice(0, 6);

        if (posts.length === 0) {
            container.innerHTML = '<p class="empty-state mono">No posts yet.</p>';
            return;
        }

        container.classList.add('reveal-stagger');
        container.innerHTML = posts.map(post => {
            const linkUrl = 'walkthroughs/view.html?id=' + post.id;
            const tagStyle = post.category === 'magic'
                ? 'color: #a855f7; background: rgba(168, 85, 247, 0.1);'
                : '';
            const date = (post.created || '').split(' ')[0];
            return `
                <a href="${linkUrl}" class="post-item">
                    <span class="post-meta mono">
                        <span class="post-tag" style="${tagStyle}">[${escapeHtml(post.tag || '')}]</span>
                        ${escapeHtml(date)}
                    </span>
                    <h3>${escapeHtml(post.title || '')}</h3>
                    <p>${escapeHtml(post.summary || '')}</p>
                </a>`;
        }).join('');

        attachStaggerObserver(container);
    } catch (e) {
        console.error('Failed to sync data:', e);
        container.innerHTML = '<p class="empty-state mono">Failed to load posts.</p>';
    }
}

async function initSearchableGrid(category, gridId, searchId) {
    const grid = document.getElementById(gridId);
    const searchInput = document.getElementById(searchId);
    if (!grid) return;

    try {
        const response = await fetch('/api/collections/cases/records?sort=-created');
        if (!response.ok) throw new Error('Status: ' + response.status);

        const data = await response.json();
        const allPosts = data.items || [];
        const categoryPosts = allPosts.filter(p => p.category === category);

        const render = (items) => {
            grid.classList.add('reveal-stagger');
            grid.classList.remove('in-view');

            if (items.length === 0) {
                grid.classList.remove('reveal-stagger');
                grid.innerHTML = '<p class="empty-state mono">No results found.</p>';
                return;
            }

            grid.innerHTML = items.map(post => {
                let imageHtml = '';
                let cardClass = 'sec-card';
                const date = (post.created || '').split(' ')[0];

                if (category === 'magic' && post.thumbnail) {
                    imageHtml = `<div class="card-img" style="background-image: url('${escapeAttr(post.thumbnail)}');"></div>`;
                    cardClass += ' has-image';
                }

                return `
                    <a href="walkthroughs/view.html?id=${encodeURIComponent(post.id)}" class="${cardClass}">
                        ${imageHtml}
                        <div class="card-content">
                            <h3 class="mono">${escapeHtml(post.title || '')}</h3>
                            <span class="card-meta mono">[${escapeHtml(post.tag || '')}] ${escapeHtml(date)}</span>
                        </div>
                    </a>`;
            }).join('');

            requestAnimationFrame(() => grid.classList.add('in-view'));
        };

        render(categoryPosts);

        if (searchInput) {
            searchInput.addEventListener('input', (e) => {
                const term = e.target.value.toLowerCase();
                const filtered = categoryPosts.filter(post =>
                    (post.title || '').toLowerCase().includes(term) ||
                    (post.tag || '').toLowerCase().includes(term) ||
                    (post.summary || '').toLowerCase().includes(term)
                );
                render(filtered);
            });
        }
    } catch (e) {
        console.error('Grid error:', e);
        grid.innerHTML = '<p class="empty-state mono">Failed to load.</p>';
    }
}

function initSkillIssueTicker() {
    const tickerContainer = document.getElementById('skill-issue-feed');
    if (!tickerContainer) return;

    const messages = [
        "Zero Days found: 0",
        "Imposter Syndrome kicking in",
        "Pigeons are liars",
        "CERTIFICATIONS: Trust me bro",
        "The S in IOT stand for Security.",
        "Must be a layer 8 issue.",
        "The best way to secure a computer is to turn it off and never power it on.",
        "And then?"
    ];

    const content = [...messages, ...messages, ...messages]
        .map(msg => `<span class="ticker-item">${escapeHtml(msg)}</span>`)
        .join('');
    tickerContainer.innerHTML = content;
}

function initCryptoCopier() {
    document.querySelectorAll('.crypto-addr').forEach(addr => {
        addr.addEventListener('click', async () => {
            const originalText = addr.innerText;
            const cleanAddress = originalText.replace(/\s/g, '');
            try {
                await navigator.clipboard.writeText(cleanAddress);
                addr.classList.add('copied');
                addr.innerText = '[ ADDRESS COPIED ]';
                setTimeout(() => {
                    addr.classList.remove('copied');
                    addr.innerText = originalText;
                }, 1500);
            } catch (err) {
                console.error('Copy failed:', err);
            }
        });
    });
}

function escapeHtml(str) {
    if (str == null) return '';
    return String(str)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
}

function escapeAttr(str) {
    if (str == null) return '';
    return String(str).replace(/"/g, '&quot;').replace(/'/g, '&#39;');
}
