/**
 * Shared library toolbar JS — handles batch generation, tag regeneration,
 * and bulk create operations for all category index pages.
 *
 * Reads configuration from data attributes on the toolbar wrapper element:
 *   data-toolbar-category   — e.g. "outfits"
 *   data-get-missing-url    — e.g. "/get_missing_outfits"
 *   data-clear-covers-url   — e.g. "/clear_all_outfit_covers"
 *   data-generate-url       — e.g. "/outfit/{slug}/generate" (with {slug} placeholder)
 *   data-regen-tags-category — e.g. "outfits" (for /admin/bulk_regenerate_tags/<cat>)
 *   data-bulk-create-url    — e.g. "/outfits/bulk_create"
 */
document.addEventListener('DOMContentLoaded', () => {
    const toolbar = document.querySelector('[data-toolbar-category]');
    if (!toolbar) return;

    const category = toolbar.dataset.toolbarCategory;
    const getMissingUrl = toolbar.dataset.getMissingUrl;
    const clearCoversUrl = toolbar.dataset.clearCoversUrl;
    const generateUrlPattern = toolbar.dataset.generateUrl;
    const regenTagsCat = toolbar.dataset.regenTagsCategory;
    const bulkCreateUrl = toolbar.dataset.bulkCreateUrl;

    const batchBtn = document.getElementById('batch-generate-btn');
    const regenAllBtn = document.getElementById('regenerate-all-btn');
    const regenTagsBtn = document.getElementById('regen-tags-all-btn');
    const bulkCreateBtn = document.getElementById('bulk-create-btn');
    const bulkOverwriteBtn = document.getElementById('bulk-overwrite-btn');

    // --- Utility: poll a job until done ---
    function waitForJob(jobId, maxPollMs = 300000) {
        return new Promise((resolve, reject) => {
            const start = Date.now();
            const poll = setInterval(async () => {
                if (Date.now() - start > maxPollMs) {
                    clearInterval(poll);
                    reject(new Error('Job timed out after ' + Math.round(maxPollMs / 1000) + 's'));
                    return;
                }
                try {
                    const resp = await fetch(`/api/queue/${jobId}/status`);
                    const data = await resp.json();
                    if (data.status === 'done') { clearInterval(poll); resolve(data); }
                    else if (data.status === 'failed' || data.status === 'removed') {
                        clearInterval(poll); reject(new Error(data.error || 'Job failed'));
                    }
                } catch (err) { /* ignore transient errors */ }
            }, 1500);
        });
    }

    // --- Batch Generate Missing Covers ---
    async function runBatch() {
        if (!getMissingUrl || !generateUrlPattern) return;

        const response = await fetch(getMissingUrl);
        const data = await response.json();
        const missing = data.missing;

        if (missing.length === 0) {
            alert('No items missing cover images.');
            return;
        }

        if (batchBtn) batchBtn.disabled = true;
        if (regenAllBtn) regenAllBtn.disabled = true;

        // Phase 1: Queue all jobs
        const jobs = [];
        for (const item of missing) {
            try {
                const url = generateUrlPattern.replace('{slug}', item.slug);
                const body = new URLSearchParams({ action: 'replace' });
                // Secondary categories need a random character for generation
                if (category !== 'characters') {
                    body.set('character_slug', '__random__');
                }
                const genResp = await fetch(url, {
                    method: 'POST',
                    body: body,
                    headers: { 'X-Requested-With': 'XMLHttpRequest' }
                });
                const genData = await genResp.json();
                if (genData.job_id) jobs.push({ item, jobId: genData.job_id });
            } catch (err) {
                console.error(`Failed to queue ${item.name}:`, err);
            }
        }

        // Phase 2: Poll all concurrently, update card images as they finish
        await Promise.all(jobs.map(async ({ item, jobId }) => {
            try {
                const jobResult = await waitForJob(jobId);
                if (jobResult.result && jobResult.result.image_url) {
                    const img = document.getElementById(`img-${item.slug}`);
                    const noImgSpan = document.getElementById(`no-img-${item.slug}`);
                    if (img) { img.src = jobResult.result.image_url; img.classList.remove('d-none'); }
                    if (noImgSpan) noImgSpan.classList.add('d-none');
                }
            } catch (err) {
                console.error(`Failed for ${item.name}:`, err);
            }
        }));

        if (batchBtn) batchBtn.disabled = false;
        if (regenAllBtn) regenAllBtn.disabled = false;
        alert(`Batch generation complete! ${jobs.length} images queued.`);
    }

    if (batchBtn) {
        batchBtn.addEventListener('click', async () => {
            if (!getMissingUrl) return;
            const response = await fetch(getMissingUrl);
            const data = await response.json();
            if (data.missing.length === 0) {
                alert('No items missing cover images.');
                return;
            }
            if (!confirm(`Generate cover images for ${data.missing.length} items?`)) return;
            runBatch();
        });
    }

    // --- Regenerate All Covers ---
    if (regenAllBtn) {
        regenAllBtn.addEventListener('click', async () => {
            if (!clearCoversUrl) return;
            if (!confirm('This will unassign ALL current cover images and generate new ones. Proceed?')) return;

            const clearResp = await fetch(clearCoversUrl, { method: 'POST' });
            if (clearResp.ok) {
                document.querySelectorAll('.img-container img').forEach(img => img.classList.add('d-none'));
                document.querySelectorAll('.img-container .text-muted').forEach(span => span.classList.remove('d-none'));
                runBatch();
            }
        });
    }

    // --- Regenerate Tags (LLM) ---
    if (regenTagsBtn && regenTagsCat) {
        regenTagsBtn.addEventListener('click', async () => {
            if (!confirm('Regenerate tags for ALL items using the LLM? This will consume API credits.')) return;
            regenTagsBtn.disabled = true;
            const origText = regenTagsBtn.textContent;
            regenTagsBtn.textContent = 'Queuing...';
            try {
                const resp = await fetch(`/admin/bulk_regenerate_tags/${regenTagsCat}`, {
                    method: 'POST',
                    headers: { 'X-Requested-With': 'XMLHttpRequest' }
                });
                const data = await resp.json();
                if (data.success) {
                    alert(`Queued ${data.queued} tag regeneration tasks. Watch progress in the queue.`);
                } else {
                    alert('Error: ' + (data.error || 'Unknown error'));
                }
            } catch (err) {
                alert('Request failed: ' + err.message);
            }
            regenTagsBtn.disabled = false;
            regenTagsBtn.textContent = origText;
        });
    }

    // --- Bulk Create from LoRAs (LLM) ---
    async function doBulkCreate(overwrite) {
        if (!bulkCreateUrl) return;
        const body = overwrite ? new URLSearchParams({ overwrite: 'true' }) : undefined;
        try {
            const resp = await fetch(bulkCreateUrl, {
                method: 'POST',
                headers: { 'X-Requested-With': 'XMLHttpRequest' },
                body: body,
            });
            const data = await resp.json();
            if (data.success) {
                alert(`Queued ${data.queued} LLM tasks (${data.skipped} skipped). Watch progress in the queue.`);
            } else {
                alert('Error: ' + (data.error || 'Unknown error'));
            }
        } catch (err) {
            alert('Request failed: ' + err.message);
        }
    }

    if (bulkCreateBtn) {
        bulkCreateBtn.addEventListener('click', () => {
            if (!confirm('Create entries from LoRA files using the LLM? This will consume API credits.')) return;
            doBulkCreate(false);
        });
    }

    if (bulkOverwriteBtn) {
        bulkOverwriteBtn.addEventListener('click', () => {
            if (!confirm('WARNING: This will overwrite ALL existing metadata using the LLM. This consumes API credits. Proceed?')) return;
            doBulkCreate(true);
        });
    }
});
