function openFileModal(title, author, type, uploaded, updated, filePath, documentId, description, fileSize, resolution, refNo) {
    // Update modal metadatas
    document.getElementById('fileTitle').textContent = title;
    document.getElementById('fileAuthor').textContent = author;
    // populate both variants of the file-type element so it works with different templates
    const ft1 = document.getElementById('fileType');
    const ft2 = document.getElementById('file_type');
    if (ft1) ft1.textContent = type;
    if (ft2) ft2.textContent = type;
    // Reference number (admin modal uses id 'fileRefNo')
    const refEl = document.getElementById('fileRefNo');
    if (refEl) refEl.textContent = refNo || "N/A";
    document.getElementById('uploadDate').textContent = uploaded;
    document.getElementById('lastUpdated').textContent = updated;
    document.getElementById('fileDescription').textContent = description || "N/A";
    document.getElementById('fileSize').textContent = fileSize ? formatFileSize(fileSize) : "N/A";
    document.getElementById('fileResolution').textContent = resolution || "N/A";

    // Set download button action
    document.getElementById('modalDownloadBtn').setAttribute('onclick', `window.location.href='download.php?id=${documentId}'`);

    // set global current document/file for email modal or other actions
    window.currentDocumentId = documentId;
    window.currentFileName = title;

    // Set preview based on file type
    const previewArea = document.getElementById('previewArea');
    previewArea.innerHTML = ""; // Clear previous content

    // Use view.php endpoint to handle path conversions (absolute server paths, URLs, etc.)
    // This ensures consistent handling of all path types
    const viewUrl = `view.php?id=${documentId}`;

    // Make type matching case-insensitive and use view.php for all embeddable types
    if (type.match(/(jpg|jpeg|png|gif|svg)$/i)) {
        previewArea.innerHTML = `<img src="${viewUrl}" alt="Preview Image">`;
    } else if (type.match(/(mp4|mpeg|avi|mov|wmv)$/i)) {
        previewArea.innerHTML = `<video controls><source src="${viewUrl}" type="video/${type}">Your browser does not support the video tag.</video>`;
    } else if (type.match(/(mp3|aac|wav|aiff|pcm)$/i)) {
        previewArea.innerHTML = `<audio controls><source src="${viewUrl}" type="audio/${type}">Your browser does not support the audio tag.</audio>`;
    } else if (type.match(/(pdf)$/i)) {
        previewArea.innerHTML = `<iframe src="${viewUrl}" style="width: 100%; height: 100%;" frameborder="0"></iframe>`;
    } else if (type.match(/(doc|docx|xls|xlsx|ppt|pptx|js|html|py|php|sql|css)$/i)) {
        if (type.match(/(ppt|pptx|xls|xlsx)$/i)) {
            // Use Office Online viewer for Office documents
            previewArea.innerHTML = `<iframe src="https://view.officeapps.live.com/op/embed.aspx?src=${encodeURIComponent(window.location.origin + '/' + viewUrl)}" style="width: 100%; height: 100%;" frameborder="0"></iframe>`;
        } else {
            previewArea.innerHTML = `<p>Preview not available for ${type} files. Download to view.</p>`;
        }
    } else {
        previewArea.innerHTML = `<p>Unsupported file type.</p>`;
    }

    // Display the modal
    document.getElementById('fileModal').style.display = "block";
}


// Helper function to format file size
function formatFileSize(bytes) {
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    if (bytes === 0) return '0 Byte';
    const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
    return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
}