/**
 * Viewer page — renders a single Directus asset in-browser.
 *   PDF  → native <iframe>
 *   DOCX → docx-preview library (renders document XML to HTML in-page)
 *
 * URL params: ?id={uuid}&name={filename}&type={pdf|docx}
 */

class ViewerApi {
    static API_BASE = 'https://api.ifuntanhub.dev';

    static assetUrl(uuid) {
        return `${this.API_BASE}/assets/${uuid}`;
    }

    static async fetchBlob(url, onProgress) {
        const response = await fetch(url);
        if (!response.ok) throw new Error(`Gagal mengambil berkas (HTTP ${response.status}).`);

        // If the response supports streaming and we have a progress callback,
        // pipe through a progress-tracking reader.
        const contentLength = response.headers.get('Content-Length');
        if (onProgress && contentLength && response.body) {
            const total = parseInt(contentLength, 10);
            const reader = response.body.getReader();
            const chunks = [];
            let received = 0;

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;
                chunks.push(value);
                received += value.length;
                onProgress(received / total);
            }
            return new Blob(chunks);
        }

        return response.blob();
    }
}

class FileViewer {
    constructor() {
        const params = new URLSearchParams(window.location.search);
        this.id = params.get('id');
        this.name = params.get('name') || 'Dokumen';
        this.type = (params.get('type') || 'pdf').toLowerCase();

        this.titleEl = document.getElementById('viewer-title');
        this.typeBadgeEl = document.getElementById('viewer-type');
        this.downloadEl = document.getElementById('viewer-download');
        this.contentEl = document.getElementById('viewer-content');

        this.assetUrl = this.id ? ViewerApi.assetUrl(this.id) : null;
    }

    async init() {
        if (!this.id) {
            this._renderError('Parameter berkas tidak ditemukan di URL.');
            return;
        }

        document.title = `${this.name} — Pratinjau Dokumen`;
        this.titleEl.textContent = this.name;
        this.typeBadgeEl.textContent = this.type.toUpperCase();
        this._setupDownload();

        try {
            if (this.type === 'docx') {
                await this._renderDocx();
            } else {
                this._renderPdf();
            }
        } catch (err) {
            console.error(err);
            this._renderError('Gagal memuat pratinjau berkas. Silakan unduh berkas untuk membuka secara lokal.');
        }
    }

    _setupDownload() {
        const ext = `.${this.type}`;
        const filename = this.name.toLowerCase().endsWith(ext) ? this.name : `${this.name}${ext}`;

        // Use blob-based download so the browser always triggers a save
        // dialog rather than navigating to the file (cross-origin `download`
        // attribute is ignored by browsers).
        this.downloadEl.removeAttribute('href');
        this.downloadEl.style.cursor = 'pointer';
        this.downloadEl.addEventListener('click', async (e) => {
            e.preventDefault();
            // Visual feedback while downloading.
            const origHtml = this.downloadEl.innerHTML;
            this.downloadEl.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Mengunduh…';
            this.downloadEl.style.pointerEvents = 'none';
            try {
                const blob = await ViewerApi.fetchBlob(this.assetUrl);
                const blobUrl = URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.style.display = 'none';
                a.href = blobUrl;
                a.download = filename;
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                URL.revokeObjectURL(blobUrl);
            } catch (err) {
                console.warn('Blob download failed, falling back:', err);
                // Fallback: open asset URL with ?download param
                window.open(`${this.assetUrl}?download`, '_blank');
            } finally {
                this.downloadEl.innerHTML = origHtml;
                this.downloadEl.style.pointerEvents = '';
            }
        });
    }

    _renderPdf() {
        const iframe = document.createElement('iframe');
        iframe.className = 'viewer-pdf-frame';
        iframe.title = this.name;
        iframe.src = this.assetUrl;
        this.contentEl.replaceChildren(iframe);
    }

    /**
     * Lazy-load a script by URL. Returns a promise that resolves on load.
     */
    static _loadScript(src) {
        return new Promise((resolve, reject) => {
            const s = document.createElement('script');
            s.src = src;
            s.onload = resolve;
            s.onerror = () => reject(new Error(`Gagal memuat skrip: ${src}`));
            document.head.appendChild(s);
        });
    }

    async _renderDocx() {
        // Show progress bar immediately.
        const progressBar = this._showProgress();

        // Load DOCX libraries and fetch the blob in parallel.
        const [blob] = await Promise.all([
            ViewerApi.fetchBlob(this.assetUrl, (ratio) => {
                progressBar.update(ratio);
            }),
            this._loadDocxLibraries(),
        ]);
        progressBar.finish();

        if (typeof docx === 'undefined' || typeof docx.renderAsync !== 'function') {
            throw new Error('Library docx-preview belum dimuat.');
        }

        const container = document.createElement('div');
        container.className = 'viewer-docx-content';
        this.contentEl.replaceChildren(container);

        await docx.renderAsync(blob, container, null, {
            inWrapper: true,
            ignoreWidth: false,
            ignoreHeight: false,
        });
    }

    async _loadDocxLibraries() {
        if (typeof docx !== 'undefined') return; // already loaded
        await FileViewer._loadScript('https://unpkg.com/jszip@3.10.1/dist/jszip.min.js');
        await FileViewer._loadScript('https://unpkg.com/docx-preview@0.3.5/dist/docx-preview.js');
    }

    /**
     * Show a thin progress bar at the top of the content area.
     * Returns { update(ratio), finish() }.
     */
    _showProgress() {
        const bar = document.createElement('div');
        bar.className = 'viewer-progress-bar';
        const fill = document.createElement('div');
        fill.className = 'viewer-progress-fill';
        bar.appendChild(fill);

        // Insert above the loading spinner.
        this.contentEl.prepend(bar);

        return {
            update(ratio) {
                fill.style.width = `${Math.min(Math.round(ratio * 100), 100)}%`;
            },
            finish() {
                fill.style.width = '100%';
                setTimeout(() => bar.remove(), 300);
            },
        };
    }

    _renderError(message) {
        const wrapper = document.createElement('div');
        wrapper.className = 'viewer-error';

        const icon = document.createElement('i');
        icon.className = 'fas fa-exclamation-triangle';

        const span = document.createElement('span');
        span.textContent = message;

        const back = document.createElement('a');
        back.href = 'index.html#repository';
        back.className = 'btn-back-mini';
        back.textContent = 'Kembali ke Repositori';

        wrapper.append(icon, span, back);
        this.contentEl.replaceChildren(wrapper);
    }
}

document.addEventListener('DOMContentLoaded', () => {
    new FileViewer().init();
});
