// preview.js — file preview popup. Reuses shared/preview-lib.js for // TIFF, ZIP listing, and image-rendering helpers; native iframe for // PDF and HTML;
 for text; download button for everything else.
//
// Lifecycle: a single popup window is reused across multiple file
// clicks (state.previewWindow). Subsequent clicks rewrite its
// contents instead of spawning a new window — same UX as the archive
// tool.
(function () {
    'use strict';

    var state = window.app.state;
    var loader = window.app.modules.loader;
    var preview = window.zddc && window.zddc.preview;
    if (!preview) {
        // shared/preview-lib.js wasn't concatenated in. Bail loudly so
        // the bug shows up in console rather than mysteriously failing.
        console.error('[browse] zddc.preview not loaded — preview popup disabled.');
    }

    function escapeHtml(s) {
        return String(s).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"');
    }

    var MIME = {
        'pdf': 'application/pdf',
        'html': 'text/html', 'htm': 'text/html',
        'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png',
        'gif': 'image/gif', 'webp': 'image/webp', 'svg': 'image/svg+xml',
        'tif': 'image/tiff', 'tiff': 'image/tiff',
        'zip': 'application/zip',
        'txt': 'text/plain', 'md': 'text/markdown', 'json': 'application/json',
        'xml': 'application/xml', 'csv': 'text/csv', 'log': 'text/plain',
        'js': 'text/javascript', 'css': 'text/css'
    };

    // Pull bytes for a file node. Three sources:
    //   - server URL (zddc-server-backed file, including downloads
    //     of archived files served at real paths)
    //   - FS-API handle (local folder)
    //   - JSZip entry (file inside an expanded zip; reads from
    //     parent's cached JSZip instance)
    async function getArrayBuffer(node) {
        if (node.zipParentId != null) {
            var owner = state.nodes.get(node.zipParentId);
            if (!owner || !owner.zipFile) {
                throw new Error('parent zip not loaded');
            }
            return await owner.zipFile.file(node.zipPath).async('arraybuffer');
        }
        if (state.source === 'server' && node.url) {
            var resp = await fetch(node.url);
            if (!resp.ok) throw new Error('HTTP ' + resp.status);
            return await resp.arrayBuffer();
        }
        if (node.handle) {
            var f = await node.handle.getFile();
            return await f.arrayBuffer();
        }
        throw new Error('no source for file');
    }

    function getMime(ext) {
        return MIME[ext] || 'application/octet-stream';
    }

    // Build a blob URL for the file's bytes. For server-mode regular
    // files (not in a zip), prefer the live URL — relative links and
    // server-side interception (e.g. .archive resolution) work then.
    async function getBlobUrl(node) {
        if (state.source === 'server' && node.url && node.zipParentId == null) {
            return { url: node.url, fromServer: true };
        }
        var buf = await getArrayBuffer(node);
        var blob = new Blob([buf], { type: getMime(node.ext) });
        return { url: URL.createObjectURL(blob), fromServer: false };
    }

    function popupShell(node, primaryUrl) {
        var safeName = escapeHtml(node.name);
        var safeHref = escapeHtml(primaryUrl);
        var ext = (node.ext || '').toLowerCase();
        // Inline PDF and HTML previews load in iframes. HTML uses
        // sandbox="allow-same-origin allow-popups
        // allow-popups-to-escape-sandbox" — same posture as archive's
        // preview: links navigate, scripts blocked, popups allowed.
        var contentHtml;
        if (ext === 'pdf') {
            contentHtml = '';
        } else if (ext === 'html' || ext === 'htm') {
            contentHtml = '';
        } else if (preview && preview.isImage(ext) && !preview.isTiff(ext)) {
            contentHtml = '' + safeName + '';
        } else {
            contentHtml = '
Loading preview…
'; } return '' + '' + safeName + ' — preview' + '

' + safeName + '

' + '
' + contentHtml + '