{% extends "base.html.j2" %}
<!-- fnord -->
{% block title %}neopig SERP{% endblock %}

{% block extra_css %}
/* Search page specific */
.result-hash { font-family: monospace; font-size: 11px; color: #ff6b6b; text-decoration: none; word-break: break-all; }
.result-hash:hover { text-decoration: underline; }
.result-keywords { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.tag { background: #333; padding: 2px 8px; border-radius: 4px; font-size: 11px; color: #aaa; }
.no-results { text-align: center; padding: 60px; color: #666; }
.result-count { padding: 10px 15px; color: #888; font-size: 14px; }
.result-count.over-9000 { color: #ff6b6b; font-weight: bold; font-size: 18px; text-shadow: 0 0 10px rgba(255,107,107,0.5); animation: powerUp 0.5s ease-out; }
@keyframes powerUp { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } }
.media-link { display: block; cursor: pointer; }
.media-link:hover img, .media-link:hover video { opacity: 0.8; }
/* Page results */
.page-results { display: flex; flex-direction: column; gap: 10px; }
.page-result { background: #1a1a1a; border-radius: 8px; padding: 15px; transition: background 0.2s; }
.page-result:hover { background: #252525; }
.page-result a { color: #ff6b6b; text-decoration: none; font-size: 16px; font-weight: 500; }
.page-result a:hover { text-decoration: underline; }
.page-path { font-size: 12px; color: #4ade80; margin-top: 4px; font-family: monospace; }
.page-snippet { font-size: 13px; color: #999; margin-top: 8px; line-height: 1.5; }
.page-snippet mark { background: #ff6b6b33; color: #ff9999; padding: 1px 3px; border-radius: 2px; }
/* Two-column layout for media + pages */
.search-columns { display: grid; grid-template-columns: 1fr; gap: 30px; align-items: start; }
.search-columns.has-pages { grid-template-columns: 1fr 2fr; }
.search-columns .page-column { display: none; }
.search-columns.has-pages .page-column { display: block; }
@media (max-width: 1000px) { .search-columns.has-pages { grid-template-columns: 1fr; } }
@media (max-width: 768px) { .results { grid-template-columns: repeat(2, 1fr); } }
{% endblock %}

{% block content %}
<div class="container">
    <div class="search-box">
        <input type="text" id="query" placeholder="{{ t.search_placeholder }}" autofocus>
        <select id="type">
            <option value="">{{ t.all_types }}</option>
            <option value="image">{{ t.images }}</option>
            <option value="video">{{ t.videos }}</option>
            <option value="audio">{{ t.audio }}</option>
        </select>
        <button onclick="search()">{{ t.search }}</button>
    </div>

    <div class="stats" id="stats">{{ t.loading_stats }}</div>

    <div class="search-columns">
        <div class="page-column" id="page-section">
            <h2 class="section-title">{{ t.pages_label }}</h2>
            <div class="page-results" id="page-results"></div>
        </div>

        <div class="media-column" id="media-section">
            <h2 class="section-title">{{ t.media }}</h2>
            <div id="results-count"></div>
            <div class="results" id="results"></div>
        </div>
    </div>
</div>
{% endblock %}

{% block scripts %}
<script>
const T = {{ t_json|safe }};
const OVER_9000 = 9000;
let currentOffset = 0;

async function loadStats() {
    const res = await fetch('/api/stats');
    const stats = await res.json();
    document.getElementById('stats').innerHTML =
        `<strong>${stats.total_media}</strong> ${T.media} | ` +
        `<strong>${stats.by_type?.image || 0}</strong> ${T.images} | ` +
        `<strong>${stats.by_type?.video || 0}</strong> ${T.videos} | ` +
        `<strong>${stats.total_sources}</strong> ${T.sources} | ` +
        `<strong>${stats.total_pages || 0}</strong> ${T.pages_label}`;
}

async function search(offset = 0) {
    currentOffset = offset;
    const query = document.getElementById('query').value;
    const type = document.getElementById('type').value;

    let mediaUrl = `/api/search?q=${encodeURIComponent(query)}&limit=${OVER_9000}&offset=${offset}`;
    if (type) mediaUrl += `&type=${type}`;

    const mediaRes = await fetch(mediaUrl);
    const mediaResults = await mediaRes.json();

    const mediaContainer = document.getElementById('results');
    const countContainer = document.getElementById('results-count');

    let countDisplay = '';
    if (mediaResults.length >= OVER_9000) {
        countDisplay = `<div class="result-count over-9000">${T.over_9000}</div>`;
    } else if (mediaResults.length > 0) {
        const start = offset + 1;
        const end = offset + mediaResults.length;
        countDisplay = `<div class="result-count">${start.toLocaleString()}-${end.toLocaleString()} of ${offset > 0 ? 'many' : mediaResults.length.toLocaleString()}</div>`;
    }

    let pagination = '';
    if (offset > 0 || mediaResults.length >= OVER_9000) {
        pagination = '<div class="pagination">';
        if (offset > 0) pagination += `<button onclick="search(${Math.max(0, offset - OVER_9000)})">← ${T.previous} ${OVER_9000.toLocaleString()}</button>`;
        if (mediaResults.length >= OVER_9000) pagination += `<button onclick="search(${offset + OVER_9000})">${T.next} ${OVER_9000.toLocaleString()} →</button>`;
        pagination += '</div>';
    }

    if (mediaResults.length === 0 && offset === 0) {
        countContainer.innerHTML = '';
        mediaContainer.innerHTML = `<div class="no-results">${T.no_media}</div>`;
    } else if (mediaResults.length === 0) {
        countContainer.innerHTML = '';
        mediaContainer.innerHTML = `<div class="no-results">${T.no_more}</div>` + pagination;
    } else {
        countContainer.innerHTML = countDisplay;
        mediaContainer.innerHTML = mediaResults.map(r => renderMediaCard(r)).join('') + pagination;
    }

    // Search pages
    const pageContainer = document.getElementById('page-results');
    const searchColumns = document.querySelector('.search-columns');

    if (query.trim()) {
        const pageRes = await fetch(`/api/search/pages?q=${encodeURIComponent(query)}&limit=30`);
        const pageResults = await pageRes.json();

        if (pageResults.length > 0) {
            searchColumns.classList.add('has-pages');
            pageContainer.innerHTML = pageResults.map(p => `
                <div class="page-result">
                    <a href="/page/${p.uri_hash}">${p.title || p.uri}</a>
                    <div class="page-path">${p.path || p.uri}</div>
                    <div class="page-snippet">${p.snippet || ''}</div>
                </div>
            `).join('');
        } else {
            searchColumns.classList.remove('has-pages');
            pageContainer.innerHTML = '';
        }
    } else {
        searchColumns.classList.remove('has-pages');
        pageContainer.innerHTML = '';
    }
}

function renderMediaCard(r) {
    const isVideo = r.media_type === 'video';
    const isCode = r.media_type === 'code';
    const isStyle = r.media_type === 'style';
    const isFont = r.media_type === 'font';

    const mimeToExt = {
        'text/javascript': '.js', 'application/javascript': '.js',
        'text/css': '.css', 'text/html': '.html.j2', 'text/xml': '.xml',
        'application/json': '.json', 'text/markdown': '.md',
        'font/woff': '.woff', 'font/woff2': '.woff2', 'font/ttf': '.ttf',
    };
    const getExt = (mime) => mimeToExt[mime] || (r.alt_text ? '.' + r.alt_text : '');

    const placeholder = (ext, icon, color) => `<svg viewBox="0 0 100 100" style="width:100%;height:100%;background:#1a1a1a;border-radius:4px;">
        <text x="50" y="40" text-anchor="middle" fill="${color}" font-size="24">${icon}</text>
        <text x="50" y="65" text-anchor="middle" fill="#888" font-family="monospace" font-size="14" font-weight="bold">${ext}</text>
    </svg>`;

    const getFilename = (uri) => {
        if (!uri) return '';
        try {
            const path = new URL(uri).pathname;
            const name = decodeURIComponent(path.split('/').pop() || '');
            return name.length > 40 ? name.slice(0, 37) + '...' : name;
        } catch { return ''; }
    };
    const filename = getFilename(r.media_uri);
    const displayName = filename ? filename.slice(0, 20) : getExt(r.mime_type);

    let mediaEl;
    if (isVideo) mediaEl = `<video src="/media/${r.md5_hash}" muted loop preload="metadata" onmouseenter="this.play()" onmouseleave="this.pause()"></video>`;
    else if (isCode) mediaEl = placeholder(displayName || getExt(r.mime_type), '{ }', '#6af');
    else if (isStyle) mediaEl = placeholder(displayName || '.css', '#', '#f6a');
    else if (isFont) mediaEl = placeholder(displayName || getExt(r.mime_type), 'Aa', '#af6');
    else mediaEl = `<img src="/media/${r.md5_hash}" alt="${r.alt_text || ''}" loading="lazy">`;

    const keywords = JSON.parse(r.keywords || '[]');
    const tagsHtml = keywords.map(k => `<span class="tag">${k}</span>`).join('');

    return `<div class="result">
        <a href="/view/${r.md5_hash}" class="media-link">${mediaEl}</a>
        <div class="result-info">
            ${filename ? `<div class="result-filename">${filename}</div>` : ''}
            <a href="/view/${r.md5_hash}" class="result-hash">${r.md5_hash}</a>
            <div class="result-meta">${r.media_type} · ${formatBytes(r.file_size)}${r.alt_text ? ` · ${r.alt_text.substring(0, 50)}` : ''}</div>
            <div class="result-keywords">${tagsHtml}</div>
        </div>
    </div>`;
}

function formatBytes(bytes) {
    if (!bytes) return '?';
    if (bytes < 1024) return bytes + ' B';
    if (bytes < 1024*1024) return (bytes/1024).toFixed(1) + ' KB';
    return (bytes/1024/1024).toFixed(1) + ' MB';
}

document.getElementById('query').addEventListener('keypress', e => { if (e.key === 'Enter') search(); });
loadStats();

const urlParams = new URLSearchParams(window.location.search);
const q = urlParams.get('q');
if (q) document.getElementById('query').value = q;
search();
</script>
{% endblock %}
