/**
 * Shared JS for all resource detail pages.
 *
 * Usage: call initDetailPage(options) from the template's <script> block.
 *
 * Options:
 *   batchItems        — Array of {slug, name} for batch generation (optional)
 *   jsonEditorUrl     — URL for save_json route (optional, enables JSON editor)
 *   hasPreviewGallery — If true, enables addToPreviewGallery helper (default: !!batchItems)
 */
function initDetailPage(options = {}) {
    const {
        batchItems = [],
        jsonEditorUrl = null,
        hasPreviewGallery = batchItems.length > 0,
    } = options;

    // -----------------------------------------------------------------------
    // DOM references
    // -----------------------------------------------------------------------
    const form = document.getElementById('generate-form');
    const progressBar = document.getElementById('progress-bar');
    const progressContainer = document.getElementById('progress-container');
    const progressLabel = document.getElementById('progress-label');
    const previewCard = document.getElementById('preview-card');
    const previewImg = document.getElementById('preview-img');
    const previewPath = document.getElementById('preview-path');
    const replaceBtn = document.getElementById('replace-cover-btn');
    const previewHeader = document.getElementById('preview-card-header');

    // -----------------------------------------------------------------------
    // Favourite toggle (delegated)
    // -----------------------------------------------------------------------
    document.querySelectorAll('.fav-toggle-btn').forEach(btn => {
        btn.addEventListener('click', async (e) => {
            e.preventDefault();
            const resp = await fetch(btn.dataset.url, {
                method: 'POST',
                headers: { 'X-Requested-With': 'XMLHttpRequest' }
            });
            const data = await resp.json();
            if (data.success) {
                btn.querySelector('span').innerHTML = data.is_favourite ? '&#9733;' : '&#9734;';
            }
        });
    });

    // -----------------------------------------------------------------------
    // Preview selection
    // -----------------------------------------------------------------------
    function selectPreview(relativePath, imageUrl) {
        if (!relativePath) return;
        previewImg.src = imageUrl;
        previewPath.value = relativePath;
        replaceBtn.disabled = false;
        previewCard.classList.remove('d-none');
        previewHeader.classList.replace('bg-secondary', 'bg-success');
        previewCard.classList.replace('border-secondary', 'border-success');
    }

    // Click any image with data-preview-path to select it
    document.addEventListener('click', e => {
        const img = e.target.closest('img[data-preview-path]');
        if (img) selectPreview(img.dataset.previewPath, img.src);
    });

    // -----------------------------------------------------------------------
    // Job polling
    // -----------------------------------------------------------------------
    async function waitForJob(jobId) {
        return new Promise((resolve, reject) => {
            const poll = setInterval(async () => {
                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'));
                    } else if (data.status === 'processing') {
                        progressLabel.textContent = 'Generating\u2026';
                    } else {
                        progressLabel.textContent = 'Queued\u2026';
                    }
                } catch (err) { console.error('Poll error:', err); }
            }, 1500);
        });
    }

    // -----------------------------------------------------------------------
    // Preview gallery helper
    // -----------------------------------------------------------------------
    function addToPreviewGallery(imageUrl, relativePath, charName) {
        const gallery = document.getElementById('preview-gallery');
        if (!gallery) return;
        const placeholder = document.getElementById('gallery-empty');
        if (placeholder) placeholder.remove();
        const col = document.createElement('div');
        col.className = 'col';
        col.innerHTML = `<div class="position-relative">
            <img src="${imageUrl}" class="img-fluid rounded"
                 style="cursor: pointer; aspect-ratio: 1; object-fit: cover; width: 100%;"
                 data-preview-path="${relativePath}"
                 title="${charName}">
            ${charName ? `<div class="position-absolute bottom-0 start-0 w-100 bg-dark bg-opacity-50 text-white p-1 rounded-bottom" style="font-size: 0.7rem; line-height: 1.2;">${charName}</div>` : ''}
        </div>`;
        gallery.insertBefore(col, gallery.firstChild);
        const badge = document.querySelector('#previews-tab .badge');
        if (badge) badge.textContent = parseInt(badge.textContent || '0') + 1;
        else {
            const tab = document.getElementById('previews-tab');
            if (tab) tab.insertAdjacentHTML('beforeend', ' <span class="badge bg-secondary">1</span>');
        }
    }

    // -----------------------------------------------------------------------
    // Form submit handler (single generation)
    // -----------------------------------------------------------------------
    if (form) {
        form.addEventListener('submit', async (e) => {
            const submitter = e.submitter;
            if (!submitter || submitter.value !== 'preview') return;
            e.preventDefault();

            const formData = new FormData(form);
            formData.append('action', 'preview');

            progressContainer.classList.remove('d-none');
            progressBar.style.width = '100%';
            progressBar.textContent = '';
            progressBar.classList.add('progress-bar-striped', 'progress-bar-animated');
            progressLabel.textContent = 'Queuing\u2026';

            try {
                const response = await fetch(form.getAttribute('action'), {
                    method: 'POST', body: formData,
                    headers: { 'X-Requested-With': 'XMLHttpRequest' }
                });
                const data = await response.json();
                if (data.error) { alert('Error: ' + data.error); return; }

                progressLabel.textContent = 'Queued\u2026';
                const jobResult = await waitForJob(data.job_id);

                if (jobResult.result?.image_url) {
                    selectPreview(jobResult.result.relative_path, jobResult.result.image_url);
                    if (hasPreviewGallery) {
                        addToPreviewGallery(jobResult.result.image_url, jobResult.result.relative_path, '');
                    }
                }
                if (typeof updateSeedFromResult === 'function') {
                    updateSeedFromResult(jobResult.result);
                }
            } catch (err) {
                console.error(err);
                alert('Generation failed: ' + err.message);
            } finally {
                progressContainer.classList.add('d-none');
                progressBar.classList.remove('progress-bar-striped', 'progress-bar-animated');
            }
        });
    }

    // -----------------------------------------------------------------------
    // Endless mode callback
    // -----------------------------------------------------------------------
    window._onEndlessResult = function(jobResult) {
        if (jobResult.result?.image_url) {
            selectPreview(jobResult.result.relative_path, jobResult.result.image_url);
            if (hasPreviewGallery) {
                addToPreviewGallery(jobResult.result.image_url, jobResult.result.relative_path, '');
            }
        }
    };

    // -----------------------------------------------------------------------
    // Batch generation (secondary categories only)
    // -----------------------------------------------------------------------
    if (batchItems.length > 0) {
        let stopBatch = false;
        const generateAllBtn = document.getElementById('generate-all-btn');
        const stopAllBtn = document.getElementById('stop-all-btn');
        const batchProgress = document.getElementById('batch-progress');
        const batchLabel = document.getElementById('batch-label');
        const batchBar = document.getElementById('batch-bar');

        if (generateAllBtn) {
            generateAllBtn.addEventListener('click', async () => {
                if (batchItems.length === 0) { alert('No characters available.'); return; }
                stopBatch = false;
                generateAllBtn.disabled = true;
                stopAllBtn.classList.remove('d-none');
                batchProgress.classList.remove('d-none');
                bootstrap.Tab.getOrCreateInstance(document.getElementById('previews-tab')).show();

                const genForm = document.getElementById('generate-form');
                const formAction = genForm.getAttribute('action');

                // Phase 1: submit all jobs
                batchLabel.textContent = 'Queuing all characters\u2026';
                const pending = [];
                for (const char of batchItems) {
                    if (stopBatch) break;
                    const fd = new FormData();
                    genForm.querySelectorAll('input[name="include_field"]:checked').forEach(
                        cb => fd.append('include_field', cb.value));
                    fd.append('character_slug', char.slug);
                    fd.append('action', 'preview');
                    try {
                        const resp = await fetch(formAction, {
                            method: 'POST', body: fd,
                            headers: { 'X-Requested-With': 'XMLHttpRequest' }
                        });
                        const data = await resp.json();
                        if (!data.error) pending.push({ char, jobId: data.job_id });
                    } catch (err) { console.error(`Submit error for ${char.name}:`, err); }
                }

                // Phase 2: poll all in parallel
                batchBar.style.width = '0%';
                let done = 0;
                const total = pending.length;
                batchLabel.textContent = `0 / ${total} complete`;

                await Promise.all(pending.map(({ char, jobId }) =>
                    waitForJob(jobId).then(result => {
                        done++;
                        batchBar.style.width = `${Math.round((done / total) * 100)}%`;
                        batchLabel.textContent = `${done} / ${total} complete`;
                        if (result.result?.image_url) {
                            addToPreviewGallery(result.result.image_url, result.result.relative_path, char.name);
                        }
                    }).catch(err => {
                        done++;
                        console.error(`Failed for ${char.name}:`, err);
                    })
                ));

                batchBar.style.width = '100%';
                batchLabel.textContent = stopBatch ? 'Stopped.' : 'Complete!';
                generateAllBtn.disabled = false;
                stopAllBtn.classList.add('d-none');
                setTimeout(() => {
                    batchProgress.classList.add('d-none');
                    batchBar.style.width = '0%';
                }, 3000);
            });
        }

        if (stopAllBtn) {
            stopAllBtn.addEventListener('click', () => {
                stopBatch = true;
                stopAllBtn.classList.add('d-none');
                batchLabel.textContent = 'Stopping\u2026';
            });
        }
    }

    // -----------------------------------------------------------------------
    // JSON editor
    // -----------------------------------------------------------------------
    if (jsonEditorUrl && typeof initJsonEditor === 'function') {
        initJsonEditor(jsonEditorUrl);
    }
}
