@ -1,10 +1,24 @@
{% extends "common/base.html" %}
{% from "components/header.html" import header %}

{% block title %}Room - DocuPulse{% endblock %}

{% block content %}
<meta name="csrf-token" content="{{ csrf_token }}">
{{ header(
    title=room.name,
    description=room.description or 'No description',
@ -20,68 +34,94 @@
        <div class="card-header d-flex justify-content-between align-items-center bg-white">
            <div class="d-flex align-items-center gap-3">
                <div class="btn-group btn-group-sm" role="group" style="margin-right: 0.5rem;">
                    <button type="button" id="gridViewBtn" class="btn btn-outline-secondary active" onclick="toggleView('grid')">
                        <i class="fas fa-th-large"></i>
                    </button>
                    <button type="button" id="listViewBtn" class="btn btn-outline-secondary" onclick="toggleView('list')">
                        <i class="fas fa-list"></i>
                    </button>
                </div>
                <h5 class="mb-0">Files</h5>
            </div>
            <div class="d-flex gap-2" id="actionButtonsRow">
            {% if current_user.is_admin %}
                <a href="{{ url_for('rooms.room_members', room_id=room.id) }}" class="btn btn-outline-primary d-flex align-items-center gap-2" style="border-color:var(--primary-color); color:var(--primary-color);" onmouseover="this.style.backgroundColor='var(--primary-color)'; this.style.color='white'" onmouseout="this.style.backgroundColor='transparent'; this.style.color='var(--primary-color)'">
                    <i class="fas fa-users"></i> Manage Members
                </a>
            {% endif %}
            {% if current_user.is_admin or can_upload %}
                <button type="button" id="newFolderBtn" class="btn btn-outline-primary d-flex align-items-center gap-2" style="border-color:var(--primary-color); color:var(--primary-color);" onmouseover="this.style.backgroundColor='var(--primary-color)'; this.style.color='white'" onmouseout="this.style.backgroundColor='transparent'; this.style.color='var(--primary-color)'">
                    <i class="fas fa-folder-plus"></i> New Folder
                </button>
                <form id="uploadForm" enctype="multipart/form-data" class="d-inline">
                    <input type="file" id="fileInput" name="file" multiple style="display:none;" />
                    <button type="button" id="uploadBtn" class="btn btn-primary d-flex align-items-center gap-2" style="background-color:var(--primary-color); border:1px solid var(--primary-color);" onmouseover="this.style.backgroundColor='var(--primary-light)'" onmouseout="this.style.backgroundColor='var(--primary-color)'">
                        <i class="fas fa-upload"></i> Upload
                    </button>
                </form>
            {% endif %}
            {% if current_user.is_admin or can_download %}
                <button id="downloadSelectedBtn" class="btn btn-outline-primary btn-sm d-flex align-items-center gap-2" style="display:none; border-color:var(--primary-color); color:var(--primary-color);" onmouseover="this.style.backgroundColor='var(--primary-color)'; this.style.color='white'" onmouseout="this.style.backgroundColor='transparent'; this.style.color='var(--primary-color)'">
                    <i class="fas fa-download"></i> Download Selected
                </button>
            {% endif %}
            {% if current_user.is_admin or can_delete %}
                <button id="deleteSelectedBtn" class="btn btn-outline-danger btn-sm d-flex align-items-center gap-2" style="display:none; border-color:var(--danger-color); color:var(--danger-color);" onmouseover="this.style.backgroundColor='var(--danger-color)'; this.style.color='white'" onmouseout="this.style.backgroundColor='transparent'; this.style.color='var(--danger-color)'">
                    <i class="fas fa-trash"></i> Delete Selected
                </button>
            {% endif %}
            </div>
        </div>
        <div class="card-body">
            <div id="uploadProgressContainer" style="display:none; margin-bottom: 1rem; width: 100%;">
                <div class="progress" style="height: 1.25rem; background-color: var(--primary-bg-light);">
                    <div id="uploadProgressBar" class="progress-bar" role="progressbar" style="width:0%; background-color:var(--primary-color); color:var(--white);">0%</div>
                </div>
                <div id="uploadProgressText" class="small text-muted mt-1"></div>
                <div id="uploadError" class="alert alert-danger alert-dismissible fade show mt-2" style="display:none;" role="alert">
                    <div id="uploadErrorContent"></div>
                    <button type="button" class="btn-close" onclick="document.getElementById('uploadError').style.display='none'; document.getElementById('uploadErrorContent').innerHTML='';"></button>
                </div>
            </div>
            <div class="d-flex align-items-center gap-2 mb-3">
                <button id="upBtn" class="btn btn-outline-secondary btn-sm" hidden style="display:none;" title="Go up one level" onclick="navigateToParent()">
                    <i class="fas fa-arrow-up"></i>
                </button>
                <div id="breadcrumb" class="d-flex align-items-center gap-2"></div>
                <div class="ms-auto" style="max-width: 300px; position: relative;">
                    <input type="text" id="quickSearchInput" class="form-control form-control-sm" placeholder="Quick search files..." autocomplete="off" style="padding-right: 2rem;" />
                    <button id="clearSearchBtn" type="button" style="position: absolute; right: 0.25rem; top: 50%; transform: translateY(-50%); display: none; border: none; background: transparent; font-size: 1.2rem; color: #888; cursor: pointer; z-index: 2;">&times;</button>
                </div>
            </div>
            <div id="fileGrid" class="row g-3" style="min-height: 200px; position: relative; margin-top: 0.5rem;">
                <div id="dropZoneOverlay" style="display: none; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(22, 118, 123, 0.1); border: 2px dashed #16767b; border-radius: 8px; z-index: 1000; pointer-events: none;">
                    <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #16767b;">
                        <i class="fas fa-cloud-upload-alt" style="font-size: 3rem; margin-bottom: 1rem;"></i>
                        <div style="font-size: 1.2rem; font-weight: 500;">Drop files here to upload</div>
                    </div>
@ -93,109 +133,118 @@
</div>

<div id="deleteConfirmModal" class="modal fade" tabindex="-1" aria-labelledby="deleteConfirmLabel" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="deleteConfirmLabel">Move to Trash</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div class="d-flex align-items-center gap-3 mb-3">
          <i class="fas fa-trash" style="font-size: 2rem; color: var(--danger-color);"></i>
          <div>
            <h6 class="mb-1">Move to Trash</h6>
            <p class="text-muted mb-0" id="deleteFileName"></p>
          </div>
        </div>
        <div class="alert alert-info">
          <i class="fas fa-info-circle me-2"></i>
          This item will be moved to trash. You can restore it from the trash page within 30 days.
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
        <button type="button" class="btn btn-danger" id="confirmDeleteBtn" style="background-color: var(--danger-color); border-color: var(--danger-color);">
          <i class="fas fa-trash me-1"></i>Move to Trash
        </button>
      </div>
    </div>
  </div>
</div>

<div id="newFolderModal" class="modal fade" tabindex="-1" aria-labelledby="newFolderLabel" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="newFolderLabel">Create New Folder</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <input type="text" id="folderNameInput" class="form-control" placeholder="Folder name" autocomplete="off" />
        <div id="folderError" class="text-danger mt-2"></div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
        <button type="button" class="btn btn-primary" id="createFolderBtn" style="background-color: var(--primary-color); border-color: var(--primary-color);">Create</button>
      </div>
    </div>
  </div>
</div>

<div id="renameModal" class="modal fade" tabindex="-1" aria-labelledby="renameLabel" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="renameLabel">Rename</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div id="renameInputGroup"></div>
        <div id="renameError" class="text-danger mt-2"></div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
        <button type="button" class="btn btn-primary" id="confirmRenameBtn" style="background-color: var(--primary-color); border-color: var(--primary-color);">Rename</button>
      </div>
    </div>
  </div>
</div>

<!-- Details Modal -->
<div id="detailsModal" class="modal fade" tabindex="-1" aria-labelledby="detailsModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="detailsModalLabel">Item Details</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body" id="detailsModalBody">
        <!-- Populated by JS -->
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

<div id="overwriteConfirmModal" class="modal fade" tabindex="-1" aria-labelledby="overwriteConfirmLabel" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="overwriteConfirmLabel">Overwrite File?</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <p id="overwriteFileMsg">A file with this name already exists. Do you want to overwrite <span id="overwriteFileName" class="fw-bold"></span>?</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" id="skipOverwriteBtn">Skip</button>
        <button type="button" class="btn btn-secondary" id="skipAllOverwriteBtn">Skip All</button>
        <button type="button" class="btn btn-danger" id="confirmOverwriteBtn" style="background-color: var(--danger-color); border-color: var(--danger-color);">Overwrite</button>
        <button type="button" class="btn btn-danger" id="confirmAllOverwriteBtn" style="background-color: var(--danger-color); border-color: var(--danger-color);">Overwrite All</button>
      </div>
    </div>
  </div>
</div>

<!-- Move Modal -->
@ -217,1713 +266,29 @@
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-primary" id="confirmMoveBtn" style="background-color: var(--primary-color); border-color: var(--primary-color);">Move</button>
            </div>
        </div>
    </div>
</div>

<style>
.file-name-ellipsis {
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: inline-block;
    vertical-align: bottom;
}
@media (min-width: 992px) {
    .file-name-ellipsis { max-width: 180px; }
}
.file-action-btn {
    min-width: 32px;
    min-height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 5px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s;
}
.card:hover > .card-footer .file-action-btn {
    opacity: 1;
    pointer-events: auto;
}
.card-footer.bg-white.border-0.d-flex.justify-content-center.gap-2 {
    min-height: 40px;
}
.card.file-card {
    cursor: pointer;
}
.card.file-card .select-item-checkbox,
.card.file-card .file-action-btn {
    cursor: pointer;
}
#upBtn.hidden {
    display: none !important;
}
#fileGrid.list-view {
    display: block;
    padding: 0;
    width: 100%;
}
#fileGrid.list-view table {
    width: 100%;
    border-collapse: collapse;
    background: var(--white);
    margin: 0;
}
#fileGrid.list-view th, #fileGrid.list-view td {
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--border-light);
    text-align: left;
    font-size: 0.95rem;
    vertical-align: middle;
}
#fileGrid.list-view th {
    background: var(--bg-color);
    color: var(--text-muted);
    font-weight: 500;
    position: sticky;
    top: 0;
    z-index: 1;
}
#fileGrid.list-view tr:hover td {
    background-color: var(--primary-opacity-8);
    transition: background 0.15s;
}
#fileGrid.list-view .file-icon {
    width: 40px;
    text-align: center;
}
#fileGrid.list-view .file-actions {
    min-width: 90px;
    text-align: right;
}
#fileGrid.list-view .file-action-btn {
    opacity: 1;
    pointer-events: auto;
    min-width: 28px;
    min-height: 28px;
    font-size: 0.875rem;
    margin-left: 0.25rem;
}
.list-view-header {
    display: grid;
    grid-template-columns: 40px 2fr 1fr 1fr 1fr;
    padding: 0.5rem 1rem;
    background-color: var(--bg-color);
    border-bottom: 1px solid var(--border-light);
    color: var(--text-muted);
    font-size: 0.875rem;
    font-weight: 500;
    margin-bottom: 0.5rem;
}
.btn-group.btn-group-sm .btn {
    background-color: var(--white);
    border-color: var(--border-light);
    color: var(--text-muted);
    transition: background-color 0.15s, color 0.15s;
}
.btn-group.btn-group-sm .btn.active, .btn-group.btn-group-sm .btn:active {
    background-color: var(--primary-bg-light) !important;
    color: var(--primary-color) !important;
    border-color: var(--primary-color) !important;
    box-shadow: none;
}
.btn-group.btn-group-sm .btn:focus {
    box-shadow: 0 0 0 0.1rem var(--primary-opacity-20);
}
.btn-group.btn-group-sm .btn:hover:not(.active) {
    background-color: var(--bg-color);
    color: var(--primary-color);
}
#fileGrid.table-mode {
    padding: 0;
}
#fileGrid.table-mode table {
    width: 100%;
    border-collapse: collapse;
    background: var(--white);
}
#fileGrid.table-mode th, #fileGrid.table-mode td {
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--border-light);
    text-align: left;
    font-size: 0.95rem;
    vertical-align: middle;
}
#fileGrid.table-mode th {
    background: var(--bg-color);
    color: var(--text-muted);
    font-weight: 500;
}
#fileGrid.table-mode tr:hover td {
    background-color: var(--primary-opacity-8);
    transition: background 0.15s;
}
#fileGrid.table-mode .file-icon {
    width: 40px;
    text-align: center;
}
#fileGrid.table-mode .file-actions {
    min-width: 90px;
    text-align: right;
}
#fileGrid.table-mode .file-action-btn {
    opacity: 1;
    pointer-events: auto;
    min-width: 28px;
    min-height: 28px;
    font-size: 0.875rem;
    margin-left: 0.25rem;
}
#fileGrid.table-mode tr.selected {
    background-color: var(--primary-bg-light) !important;
}
/* Disable text selection for file grid and table rows/cards */
#fileGrid, #fileGrid * {
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
}
#fileGrid .card.file-card {
    cursor: pointer;
}
#fileGrid.list-view tr {
    cursor: pointer;
}
#fileGrid.table-mode tr {
    cursor: pointer;
}
#fileGrid.table-mode tr.selected {
    background-color: #e6f3f4 !important;
}
.details-sidebar {
    background: #f8fafc;
    border-left: 1.5px solid #e6f3f4;
    box-shadow: -2px 0 8px rgba(0,0,0,0.08);
    font-size: 0.97rem;
    width: 320px;
    height: 100%;
    right: 0;
    top: 0;
    left: auto;
    border-radius: 0;
    position: fixed;
    z-index: 1050;
    padding: 1.3rem 1.2rem 1.2rem 1.2rem;
    overflow-y: auto;
}
.sidebar-ellipsis {
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
}
.sidebar-path-wrap {
    max-width: 220px;
    overflow-x: auto;
    white-space: nowrap;
    text-overflow: ellipsis;
    display: block;
    font-size: 0.91rem;
}
.details-sidebar h5, .details-sidebar .fw-bold {
    font-size: 1.05rem;
    color: #16767b;
}
.details-sidebar strong {
    color: #16767b;
    font-weight: 500;
}
.details-sidebar .rounded-circle {
    border: 1.5px solid #e6f3f4;
}
.details-sidebar hr {
    margin: 0.7rem 0 0.5rem 0;
    border-color: #e6f3f4;
}
.sidebar-meta-grid {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 0.2rem 0.7rem;
    font-size: 0.91rem;
    color: #555;
    margin-bottom: 0.2rem;
}
.sidebar-meta-grid div:first-child {
    color: #16767b;
    font-weight: 500;
}
@media (max-width: 900px) {
    .details-sidebar {
        width: 100vw !important;
        right: 0;
        left: 0;
        border-radius: 0;
        top: 0;
        transform: none;
        max-width: 100vw;
        max-height: 100vh;
        padding: 1.1rem 0.7rem 0.7rem 0.7rem;
    }
    .sidebar-ellipsis, .sidebar-path-wrap {
        max-width: 90vw;
    }
}
.progress-bar {
    background-color: #16767b !important;
    color: #fff !important;
    transition: background-color 0.2s;
}
</style>

<script>
// Define showDetailsModal function first
function showDetailsModal(idx) {
    // Check if currentFiles exists and idx is valid
    if (!window.currentFiles || !Array.isArray(window.currentFiles) || idx < 0 || idx >= window.currentFiles.length) {
        console.error('Invalid file index or currentFiles not initialized');
        return;
    }

    const item = window.currentFiles[idx];
    if (!item) {
        console.error('File item not found at index:', idx);
        return;
    }

    const icon = item.type === 'folder'
        ? `<i class='fas fa-folder' style='font-size:2.2rem;color:var(--primary-color);'></i>`
        : `<i class='fas fa-file-alt' style='font-size:2.2rem;color:var(--secondary-color);'></i>`;
    const uploaderPic = item.uploader_profile_pic
        ? `/uploads/profile_pics/${item.uploader_profile_pic}`
        : '/static/default-avatar.png';
    
    // Get room information from the current page
    const roomId = "{{ room.id }}";
    const roomName = "{{ room.name }}";
    
    const detailsHtml = `
      <div class='d-flex align-items-center gap-3 mb-3'>
        <div>${icon}</div>
        <div style='min-width:0;'>
          <div class='fw-bold' style='font-size:1.1rem;max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;' title='${item.name}'>${item.name}</div>
          <div class='text-muted small'>${item.type === 'folder' ? 'Folder' : 'File'}</div>
        </div>
      </div>
      <div class='mb-2 d-flex align-items-center gap-2'>
        <img src='${uploaderPic}' alt='Profile Picture' class='rounded-circle border' style='width:28px;height:28px;object-fit:cover;'>
        <span class='fw-semibold' style='font-size:0.98rem;'>${item.uploaded_by || '-'}</span>
      </div>
      <div class='mb-2 text-muted' style='font-size:0.92rem;'><i class='far fa-clock me-1'></i>${formatDate(item.modified)}</div>
      <hr style='margin:0.7rem 0 0.5rem 0; border-color:var(--border-light);'>
      <div style='font-size:0.91rem;color:var(--text-muted);'><strong style='color:var(--primary-color);'>Room:</strong> <button class='btn btn-sm' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='window.location.href=\"/rooms/${roomId}\"'><i class='fas fa-door-open me-1'></i>${roomName}</button></div>
      <div style='font-size:0.91rem;color:var(--text-muted);'><strong style='color:var(--primary-color);'>Path:</strong> <span style='word-break:break-all;'>${(item.path ? item.path + '/' : '') + item.name}</span></div>
      <div style='font-size:0.91rem;color:var(--text-muted);'><strong style='color:var(--primary-color);'>Size:</strong> ${item.size === '-' ? '-' : (item.size > 0 ? (item.size < 1024*1024 ? (item.size/1024).toFixed(1)+' KB' : (item.size/1024/1024).toFixed(2)+' MB') : '0 KB')}</div>
      <div style='font-size:0.91rem;color:var(--text-muted);'><strong style='color:var(--primary-color);'>Uploaded at:</strong> ${item.uploaded_at ? new Date(item.uploaded_at).toLocaleString() : '-'}</div>
    `;
    document.getElementById('detailsModalBody').innerHTML = detailsHtml;
    var modal = new bootstrap.Modal(document.getElementById('detailsModal'));
    modal.show();
}

const roomId = "{{ room.id }}";
const canDelete = "{{ 'true' if current_user.is_admin or can_delete else 'false' }}";
const canShare = "{{ 'true' if current_user.is_admin or can_share else 'false' }}";
const canUpload = "{{ 'true' if current_user.is_admin or can_upload else 'false' }}";
const canDownload = "{{ 'true' if current_user.is_admin or can_download else 'false' }}";
const canRename = "{{ 'true' if current_user.is_admin or can_rename else 'false' }}";
const canMove = "{{ 'true' if current_user.is_admin or can_move else 'false' }}";
let fileToDelete = null;
let fileToDeletePath = '';
let currentPath = '';
let renameTarget = null;
let renameIsFile = false;
let renameOrigExt = '';
let selectedItems = [];
let currentFiles = [];
let currentView = 'grid';
let lastSelectedIndex = -1;
let sortColumn = 'name';  // Set default sort column to name
let sortDirection = 1; // 1 for ascending, -1 for descending
let batchDeleteItems = null;
let deleteModal = null;
let pendingUploads = null;
let pendingUploadIdx = null;
let pendingUploadFormData = null;
let pendingUploadXhr = null;
let overwriteModal = null;
let overwriteResolve = null;
let overwriteModalResult = null;
let overwriteAll = false;
let skipAll = false;
let moveModal = null;
let fileToMove = null;
let fileToMovePath = '';
let modalPromise = null;
let modalResolve = null;

// Initialize the view and fetch files
async function initializeView() {
    try {
        const response = await fetch('/api/user/preferred_view');
        const data = await response.json();
        currentView = data.preferred_view || 'grid';
    } catch (error) {
        console.error('Error fetching preferred view:', error);
        currentView = 'grid';
    }
    
    // First fetch files
    await fetchFiles();
    
    // Then toggle view after files are loaded
    toggleView(currentView);
}

function formatDate(ts) {
    if (!ts) return '';
    const d = new Date(ts * 1000);
    return d.toLocaleDateString() + ' ' + d.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
}

function renderBreadcrumb() {
    const bc = document.getElementById('breadcrumb');
    bc.innerHTML = '';
    const parts = currentPath ? currentPath.split('/') : [];
    let pathSoFar = '';
    bc.innerHTML += `<a href="#" onclick="navigateTo('')" class="text-decoration-none" style="color:var(--primary-color);">Root</a>`;
    parts.forEach((part, idx) => {
        pathSoFar += (pathSoFar ? '/' : '') + part;
        bc.innerHTML += ` <span class="text-muted">/</span> <a href="#" onclick="navigateTo('${pathSoFar}')" class="text-decoration-none" style="color:var(--primary-color);">${part}</a>`;
    });
    // Show/hide up button
    const upBtn = document.getElementById('upBtn');
    if (upBtn) {
        if (currentPath && currentPath.trim().length > 0) {
            upBtn.hidden = false;
            upBtn.style.display = '';
        } else {
            upBtn.hidden = true;
            upBtn.style.display = 'none';
        }
    }
}

function toggleView(view) {
    currentView = view;
    console.log('toggleView:', currentView);
    const grid = document.getElementById('fileGrid');
    const gridBtn = document.getElementById('gridViewBtn');
    const listBtn = document.getElementById('listViewBtn');
    if (view === 'grid') {
        grid.classList.remove('list-view');
        gridBtn.classList.add('active');
        listBtn.classList.remove('active');
    } else {
        grid.classList.add('list-view');
        gridBtn.classList.remove('active');
        listBtn.classList.add('active');
    }
    renderFiles(window.currentFiles);
    // Save the new preference
    fetch('/api/user/preferred_view', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
        },
        body: JSON.stringify({ preferred_view: view })
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        return response.json();
    })
    .then(data => {
        console.log('Preferred view saved:', data);
    })
    .catch(error => console.error('Error saving preferred view:', error));
}

function sortFiles(column) {
    if (sortColumn === column) {
        sortDirection *= -1; // Toggle direction
    } else {
        sortColumn = column;
        sortDirection = 1;
    }
    window.currentFiles.sort((a, b) => {
        let valA = a[column];
        let valB = b[column];
        // For size, convert to number
        if (column === 'size') {
            valA = typeof valA === 'number' ? valA : 0;
            valB = typeof valB === 'number' ? valB : 0;
        }
        // For name/type, compare as strings
        if (typeof valA === 'string' && typeof valB === 'string') {
            return valA.localeCompare(valB) * sortDirection;
        }
        // For date (modified), compare as numbers
        return (valA - valB) * sortDirection;
    });
    renderFiles(window.currentFiles);
}

// Add this function before renderFiles
function initializeSelectAllCheckbox() {
    const selectAll = document.getElementById('selectAllTableCheckbox');
    if (selectAll) {
        // Remove any existing event listeners
        const newSelectAll = selectAll.cloneNode(true);
        selectAll.parentNode.replaceChild(newSelectAll, selectAll);
        
        // Add the event listener to the new element
        newSelectAll.addEventListener('change', function() {
            const grid = document.getElementById('fileGrid');
            const checkboxes = grid.querySelectorAll('.select-item-checkbox');
            checkboxes.forEach(function(cb) { cb.checked = newSelectAll.checked; });
            updateMultiSelectUI();
        });
    }
}

function renderFiles(files) {
    // Initialize window.currentFiles if not set
    if (!window.currentFiles) {
        window.currentFiles = [];
    }
    
    // If files parameter is provided, update window.currentFiles
    if (files) {
        window.currentFiles = files;
    }
    
    console.log('renderFiles view:', currentView);
    renderBreadcrumb();
    const grid = document.getElementById('fileGrid');
    grid.innerHTML = '';
    
    // Use window.currentFiles as the source of truth
    const filesToRender = window.currentFiles;
    
    if (!filesToRender || !filesToRender.length) {
        grid.innerHTML = '<div class="col"><div class="text-muted">No files or folders yet.</div></div>';
        return;
    }
    
    if (currentView === 'list') {
        // Create table header with the checkbox included
        let table = `<table><thead><tr>
            <th style='width:40px'><input type='checkbox' class='select-all-checkbox' style='margin-left: 0.3rem; margin-right: 1rem;'/></th>
            <th onclick="sortFiles('name')" style="cursor:pointer;">Name ${(sortColumn==='name') ? (sortDirection===1?'▲':'▼') : ''}</th>
            <th onclick="sortFiles('modified')" style="cursor:pointer;">Date Modified ${(sortColumn==='modified') ? (sortDirection===1?'▲':'▼') : ''}</th>
            <th onclick="sortFiles('type')" style="cursor:pointer;">Type ${(sortColumn==='type') ? (sortDirection===1?'▲':'▼') : ''}</th>
            <th onclick="sortFiles('size')" style="cursor:pointer;">Size ${(sortColumn==='size') ? (sortDirection===1?'▲':'▼') : ''}</th>
            <th class='file-actions'></th>
        </tr></thead><tbody>`;
        filesToRender.forEach((file, idx) => {
            let icon = file.type === 'folder'
                ? `<i class='fas fa-folder' style='font-size:1.5rem;color:var(--primary-color);'></i>`
                : `<i class='fas fa-file-alt' style='font-size:1.5rem;color:var(--secondary-color);'></i>`;
            let size = file.size !== '-' ? (file.size > 0 ? (file.size < 1024*1024 ? (file.size/1024).toFixed(1)+' KB' : (file.size/1024/1024).toFixed(2)+' MB') : '0 KB') : '-';
            let actionsArr = [];
            const canRenameAction = (canRename === 'true');
            let checkbox = `<input type='checkbox' class='select-item-checkbox form-check-input' data-idx='${idx}' title='Select' />`;
            let dblClickAction = '';
            if (file.type === 'folder') {
                dblClickAction = `ondblclick=\"navigateTo('${currentPath ? currentPath + '/' : ''}${file.name}')\"`;
            } else if (canDownload === 'true') {
                dblClickAction = `ondblclick=\"downloadFile('${file.name}')\"`;
            }
            if (file.type === 'file') {
                if (canDownload === 'true') {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Download' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='downloadFile("${file.name}")'><i class='fas fa-download'></i></button>`);
                }
                if (canRenameAction) {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Rename' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showRenameModal("${file.name}")'><i class='fas fa-pen'></i></button>`);
                }
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Details' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showDetailsModal(${idx})'><i class='fas fa-info-circle'></i></button>`);
                if (canMove === 'true') {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Move' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showMoveModal("${file.name}", "${file.path}")'><i class='fas fa-arrows-alt'></i></button>`);
                }
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='${file.starred ? 'Unstar' : 'Star'}' style='background-color:${file.starred ? 'var(--warning-opacity-15)' : 'var(--primary-opacity-8)'};color:${file.starred ? 'var(--warning-color)' : 'var(--primary-color)'};' onclick='event.stopPropagation(); toggleStar("${file.name}", "${file.path || ''}")'><i class='fas fa-star'></i></button>`);
                if (canDelete === true || canDelete === 'true') {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Delete' style='background-color:var(--danger-opacity-15);color:var(--danger-color);' onclick='showDeleteModal("${file.name}", "${file.path}")'><i class='fas fa-trash'></i></button>`);
                }
            } else {
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Open Folder' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='navigateTo(\"${currentPath ? currentPath + '/' : ''}${file.name}\")'><i class='fas fa-folder-open'></i></button>`);
                if (canRenameAction) {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Rename' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showRenameModal(\"${file.name}\")'><i class='fas fa-pen'></i></button>`);
                }
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Details' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showDetailsModal(${idx})'><i class='fas fa-info-circle'></i></button>`);
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='${file.starred ? 'Unstar' : 'Star'}' style='background-color:${file.starred ? 'var(--warning-opacity-15)' : 'var(--primary-opacity-8)'};color:${file.starred ? 'var(--warning-color)' : 'var(--primary-color)'};' onclick='event.stopPropagation(); toggleStar("${file.name}", "${file.path || ''}")'><i class='fas fa-star'></i></button>`);
                if (canDelete === true || canDelete === 'true') {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Delete' style='background-color:var(--danger-opacity-15);color:var(--danger-color);' onclick='showDeleteModal("${file.name}", "${file.path}")'><i class='fas fa-trash'></i></button>`);
                }
            }
            // Move Delete to the end if present
            const deleteIdx = actionsArr.findIndex(a => a.includes('fa-trash'));
            if (deleteIdx !== -1) {
                const [delBtn] = actionsArr.splice(deleteIdx, 1);
                actionsArr.push(delBtn);
            }
            const actions = actionsArr.join('');
            table += `<tr ${dblClickAction} onclick='toggleSelection(${idx}, event)'>
                <td class='file-icon'><span style="display:inline-flex;align-items:center;gap:1.2rem;">${checkbox}${icon}</span></td>
                <td class='file-name' title='${file.name}'>${file.displayName || file.name}</td>
                <td class='file-date'>${formatDate(file.modified)}</td>
                <td class='file-type'>${file.type}</td>
                <td class='file-size'>${size}</td>
                <td class='file-actions'>${actions}</td>
            </tr>`;
        });
        table += '</tbody></table>';
        grid.innerHTML = table;
        
        // Add event listener to the checkbox after the table is rendered
        const selectAll = grid.querySelector('.select-all-checkbox');
        if (selectAll) {
            selectAll.addEventListener('change', function() {
                const checkboxes = grid.querySelectorAll('.select-item-checkbox');
                checkboxes.forEach(function(cb) { cb.checked = selectAll.checked; });
                updateMultiSelectUI();
            });
        }
    } else {
        filesToRender.forEach((file, idx) => {
            let icon = file.type === 'folder'
                ? `<i class='fas fa-folder' style='font-size:2.5rem;color:#16767b;'></i>`
                : `<i class='fas fa-file-alt' style='font-size:2.5rem;color:#741b5f;'></i>`;
            let size = file.size !== '-' ? (file.size > 0 ? (file.size < 1024*1024 ? (file.size/1024).toFixed(1)+' KB' : (file.size/1024/1024).toFixed(2)+' MB') : '0 KB') : '-';
            let actionsArr = [];
            const canRenameAction = (canRename === 'true');
            let checkbox = `<input type='checkbox' class='select-item-checkbox form-check-input' data-idx='${idx}' style='margin-top:0;' title='Select' />`;
            let dblClickAction = '';
            if (file.type === 'folder') {
                dblClickAction = `ondblclick=\"navigateTo('${currentPath ? currentPath + '/' : ''}${file.name}')\"`;
            } else if (canDownload === 'true') {
                dblClickAction = `ondblclick=\"downloadFile('${file.name}')\"`;
            }
            if (file.type === 'file') {
                if (canDownload === 'true') {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Download' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='downloadFile("${file.name}")'><i class='fas fa-download'></i></button>`);
                }
                if (canRenameAction) {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Rename' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showRenameModal("${file.name}")'><i class='fas fa-pen'></i></button>`);
                }
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Details' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showDetailsModal(${idx})'><i class='fas fa-info-circle'></i></button>`);
                if (canMove === 'true') {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Move' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showMoveModal("${file.name}", "${file.path}")'><i class='fas fa-arrows-alt'></i></button>`);
                }
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='${file.starred ? 'Unstar' : 'Star'}' style='background-color:${file.starred ? 'var(--warning-opacity-15)' : 'var(--primary-opacity-8)'};color:${file.starred ? 'var(--warning-color)' : 'var(--primary-color)'};' onclick='event.stopPropagation(); toggleStar("${file.name}", "${file.path || ''}")'><i class='fas fa-star'></i></button>`);
                if (canDelete === true || canDelete === 'true') {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Delete' style='background-color:var(--danger-opacity-15);color:var(--danger-color);' onclick='showDeleteModal("${file.name}", "${file.path}")'><i class='fas fa-trash'></i></button>`);
                }
            } else {
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Open Folder' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='navigateTo(\"${currentPath ? currentPath + '/' : ''}${file.name}\")'><i class='fas fa-folder-open'></i></button>`);
                if (canRenameAction) {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Rename' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showRenameModal(\"${file.name}\")'><i class='fas fa-pen'></i></button>`);
                }
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Details' style='background-color:var(--primary-opacity-8);color:var(--primary-color);' onclick='showDetailsModal(${idx})'><i class='fas fa-info-circle'></i></button>`);
                actionsArr.push(`<button class='btn btn-sm file-action-btn' title='${file.starred ? 'Unstar' : 'Star'}' style='background-color:${file.starred ? 'var(--warning-opacity-15)' : 'var(--primary-opacity-8)'};color:${file.starred ? 'var(--warning-color)' : 'var(--primary-color)'};' onclick='event.stopPropagation(); toggleStar("${file.name}", "${file.path || ''}")'><i class='fas fa-star'></i></button>`);
                if (canDelete === true || canDelete === 'true') {
                    actionsArr.push(`<button class='btn btn-sm file-action-btn' title='Delete' style='background-color:var(--danger-opacity-15);color:var(--danger-color);' onclick='showDeleteModal("${file.name}", "${file.path}")'><i class='fas fa-trash'></i></button>`);
                }
            }
            // Move Delete to the end if present
            const deleteIdx = actionsArr.findIndex(a => a.includes('fa-trash'));
            if (deleteIdx !== -1) {
                const [delBtn] = actionsArr.splice(deleteIdx, 1);
                actionsArr.push(delBtn);
            }
            const actions = actionsArr.join('');
            grid.innerHTML += `
            <div class='col'>
                <div class='card file-card h-100 border-0 shadow-sm position-relative' ${dblClickAction} onclick='toggleSelection(${idx}, event)'>
                    <div class='card-body d-flex flex-column align-items-center justify-content-center text-center'>
                        <div class='mb-2 w-100 d-flex justify-content-start'>${checkbox}</div>
                        <div class='mb-2'>${icon}</div>
                        <div class='fw-semibold file-name-ellipsis' title='${file.name}'>${file.displayName || file.name}</div>
                        <div class='text-muted small'>${formatDate(file.modified)}</div>
                        <div class='text-muted small'>${size}</div>
                    </div>
                    <div class='card-footer bg-white border-0 d-flex justify-content-center gap-2'>${actions}</div>
                </div>
            </div>`;
        });
    }
    updateMultiSelectUI();
}

function toggleSelection(idx, event) {
    // Prevent selection if clicking on a checkbox or action button
    if (event.target.classList.contains('select-item-checkbox') || event.target.closest('.file-action-btn')) {
        return;
    }
    const checkboxes = document.querySelectorAll('.select-item-checkbox');
    const checkbox = checkboxes[idx];
    if (!checkbox) return;

    if (event.ctrlKey) {
        // CTRL + Click: Toggle individual selection
        checkbox.checked = !checkbox.checked;
    } else if (event.shiftKey && lastSelectedIndex !== -1) {
        // SHIFT + Click: Select range
        const start = Math.min(lastSelectedIndex, idx);
        const end = Math.max(lastSelectedIndex, idx);
        for (let i = start; i <= end; i++) {
            checkboxes[i].checked = true;
        }
    } else {
        // Normal click: Select single item
        const wasChecked = checkbox.checked;
        checkboxes.forEach(cb => cb.checked = false);
        checkbox.checked = !wasChecked;
    }

    lastSelectedIndex = idx;
    updateMultiSelectUI();
}

function fetchFiles() {
    let url = `/api/rooms/${roomId}/files`;
    if (currentPath) url += `?path=${encodeURIComponent(currentPath)}`;
    console.log('Fetching files from:', url);
    
    return fetch(url)
        .then(r => {
            console.log('Response status:', r.status);
            if (!r.ok) {
                throw new Error('Failed to load files');
            }
            return r.json();
        })
        .then(files => {
            console.log('Received files:', files);
            if (files) {
                window.currentFiles = files;
                // Sort files by name by default
                window.currentFiles.sort((a, b) => {
                    if (a.name < b.name) return -1;
                    if (a.name > b.name) return 1;
                    return 0;
                });
                renderFiles(files);
            }
        })
        .catch(error => {
            console.error('Error loading files:', error);
            document.getElementById('fileGrid').innerHTML = '<div class="col"><div class="text-danger">Failed to load files. Please try refreshing the page.</div></div>';
        });
}

function navigateTo(path) {
    currentPath = path;
    // Update the URL with the current path
    const url = new URL(window.location);
    if (currentPath) {
        url.searchParams.set('path', currentPath);
    } else {
        url.searchParams.delete('path');
    }
    window.history.replaceState({}, '', url);
    fetchFiles();
    return false;
}

// On page load, set currentPath from URL if present
function getPathFromUrl() {
    const urlParams = new URLSearchParams(window.location.search);
    return urlParams.get('path') || '';
}

function downloadFile(filename) {
    let url = `/api/rooms/${roomId}/files/${encodeURIComponent(filename)}`;
    if (currentPath) url += `?path=${encodeURIComponent(currentPath)}`;
    window.location = url;
}

function showDeleteModal(filename, path = '') {
    fileToDelete = filename;
    fileToDeletePath = path;
    batchDeleteItems = null;
    
    // Get the modal element
    const modalEl = document.getElementById('deleteConfirmModal');
    if (!modalEl) {
        console.error('Delete modal element not found');
        return;
    }
    
    // Initialize the modal if it hasn't been initialized
    if (!deleteModal) {
        deleteModal = new bootstrap.Modal(modalEl);
    }
    
    // Update modal content
    const fileNameEl = document.getElementById('deleteFileName');
    const labelEl = document.getElementById('deleteConfirmLabel');
    
    if (fileNameEl) fileNameEl.textContent = filename;
    if (labelEl) labelEl.textContent = 'Move to Trash';
    
    // Show the modal
    deleteModal.show();
}

// Add event listener for the delete confirmation button
document.getElementById('confirmDeleteBtn').addEventListener('click', deleteFileConfirmed);

// Add event listener for download selected
if (canDownload === true || canDownload === 'true') {
    document.getElementById('downloadSelectedBtn').addEventListener('click', function() {
        const selectedCheckboxes = document.querySelectorAll('.select-item-checkbox:checked');
        if (selectedCheckboxes.length === 0) return;
        
        const selectedItems = Array.from(selectedCheckboxes).map(cb => {
            const idx = parseInt(cb.dataset.idx);
            return window.currentFiles[idx];
        });
        
        // Submit the request to download the zip
        const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
        fetch(`/api/rooms/${roomId}/download-zip`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRF-Token': csrfToken
            },
            body: JSON.stringify({ items: selectedItems })
        })
        .then(response => {
            if (!response.ok) {
                throw new Error('Download failed');
            }
            return response.blob();
        })
        .then(blob => {
            // Create a download link and trigger it
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = 'download.zip';
            document.body.appendChild(a);
            a.click();
            window.URL.revokeObjectURL(url);
            a.remove();
        })
        .catch(error => {
            console.error('Error downloading files:', error);
            document.getElementById('fileError').textContent = 'Failed to download files.';
        });
    });
}

// Add event listener for batch delete
if (canDelete === true || canDelete === 'true') {
    document.getElementById('deleteSelectedBtn').addEventListener('click', function() {
        const selectedCheckboxes = document.querySelectorAll('.select-item-checkbox:checked');
        if (selectedCheckboxes.length === 0) return;
        
        batchDeleteItems = Array.from(selectedCheckboxes).map(cb => {
            const idx = parseInt(cb.dataset.idx);
            return window.currentFiles[idx];
        });
        
        // Get the modal element
        const modalEl = document.getElementById('deleteConfirmModal');
        if (!modalEl) {
            console.error('Delete modal element not found');
            return;
        }
        
        // Initialize the modal if it hasn't been initialized
        if (!deleteModal) {
            deleteModal = new bootstrap.Modal(modalEl);
        }
        
        // Update modal content
        const fileNameEl = document.getElementById('deleteFileName');
        const labelEl = document.getElementById('deleteConfirmLabel');
        
        if (fileNameEl) fileNameEl.textContent = `${selectedCheckboxes.length} item${selectedCheckboxes.length > 1 ? 's' : ''}`;
        if (labelEl) labelEl.textContent = 'Move to Trash';
        
        // Show the modal
        deleteModal.show();
    });
}

function deleteFileConfirmed() {
    const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
    if (batchDeleteItems && batchDeleteItems.length) {
        // Batch delete
        let completed = 0;
        function deleteNext() {
            if (completed >= batchDeleteItems.length) {
                fetchFiles();
                batchDeleteItems = null;
                fileToDelete = null;
                fileToDeletePath = '';
                deleteModal.hide();
                document.getElementById('fileError').textContent = '';
                return;
            }
            const item = batchDeleteItems[completed];
            let url = `/api/rooms/${roomId}/files/${encodeURIComponent(item.name)}`;
            if (item.path) url += `?path=${encodeURIComponent(item.path)}`;
            fetch(url, {
                method: 'DELETE',
                headers: { 'X-CSRF-Token': csrfToken }
            })
            .then(r => r.json())
            .then(() => {
                completed++;
                deleteNext();
            })
            .catch(() => {
                completed++;
                deleteNext();
            });
        }
        deleteNext();
        return;
    }
    if (!fileToDelete) return;
    let url = `/api/rooms/${roomId}/files/${encodeURIComponent(fileToDelete)}`;
    if (fileToDeletePath) url += `?path=${encodeURIComponent(fileToDeletePath)}`;
    fetch(url, {
        method: 'DELETE',
        headers: {
            'X-CSRF-Token': csrfToken
        }
    })
    .then(r => r.json())
    .then(res => {
        if (res.success) {
            fetchFiles();
            fileToDelete = null;
            fileToDeletePath = '';
            deleteModal.hide();
            document.getElementById('fileError').textContent = '';
        } else {
            document.getElementById('fileError').textContent = res.error || 'Delete failed.';
        }
    })
    .catch(() => {
        document.getElementById('fileError').textContent = 'Delete failed.';
    });
}

function showRenameModal(filename) {
    renameTarget = filename;
    document.getElementById('renameError').textContent = '';
    // Determine if file or folder by extension
    const ext = filename.includes('.') ? filename.substring(filename.lastIndexOf('.')) : '';
    const isFile = ext && filename.lastIndexOf('.') > 0;
    renameIsFile = isFile;
    renameOrigExt = ext;
    const inputGroup = document.getElementById('renameInputGroup');
    if (isFile) {
        const base = filename.substring(0, filename.lastIndexOf('.'));
        inputGroup.innerHTML = `<div class="input-group"><input type="text" id="renameInput" class="form-control" value="${base}" autocomplete="off" /><span class="input-group-text">${ext}</span></div>`;
    } else {
        inputGroup.innerHTML = `<input type="text" id="renameInput" class="form-control" value="${filename}" autocomplete="off" />`;
    }
    var modal = new bootstrap.Modal(document.getElementById('renameModal'));
    modal.show();
    // Focus the input field after the modal is shown
    setTimeout(() => {
        document.getElementById('renameInput').focus();
    }, 100);
}

document.getElementById('confirmRenameBtn').addEventListener('click', function() {
    if (!renameTarget) return;
    let newName = document.getElementById('renameInput').value.trim();
    if (renameIsFile) {
        if (!newName) {
            document.getElementById('renameError').textContent = 'New name is required.';
            return;
        }
        newName = newName + renameOrigExt;
    }
    const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
    if (!newName) {
        document.getElementById('renameError').textContent = 'New name is required.';
        return;
    }
    fetch(`/api/rooms/${roomId}/rename`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-Token': csrfToken
        },
        body: JSON.stringify({
            old_name: renameTarget,
            new_name: newName,
            path: currentPath
        })
    })
    .then(r => r.json())
    .then(res => {
        if (res.success) {
            fetchFiles();
            var modalEl = document.getElementById('renameModal');
            var modal = bootstrap.Modal.getInstance(modalEl);
            modal.hide();
        } else {
            document.getElementById('renameError').textContent = res.error || 'Rename failed.';
        }
    })
    .catch(() => {
        document.getElementById('renameError').textContent = 'Rename failed.';
    });
});

function updateMultiSelectUI() {
    const checkboxes = document.querySelectorAll('.select-item-checkbox');
    selectedItems = Array.from(checkboxes)
        .map((cb, idx) => ({ checked: cb.checked, idx }))
        .filter(item => item.checked)
        .map(item => item.idx);
    
    const selectedCount = selectedItems.length;
    const downloadBtn = document.getElementById('downloadSelectedBtn');
    const deleteBtn = document.getElementById('deleteSelectedBtn');
    
    if (downloadBtn) downloadBtn.style.display = selectedCount > 0 ? 'flex' : 'none';
    if (deleteBtn) deleteBtn.style.display = selectedCount > 0 ? 'flex' : 'none';
}

function toggleStar(filename, path) {
    console.log('Toggling star for:', filename, 'path:', path);
    const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
    
    // Find and update the button immediately for better UX
    const starButton = event.target.closest('.file-action-btn');
    if (starButton) {
        // Get the current state from the button's title
        const isStarred = starButton.title === 'Unstar';
        
        // Update button appearance using CSS variables
        starButton.style.backgroundColor = isStarred ? 'var(--primary-opacity-8)' : 'var(--warning-opacity-15)';
        starButton.style.color = isStarred ? 'var(--primary-color)' : 'var(--warning-color)';
        starButton.title = isStarred ? 'Star' : 'Unstar';
    }
    
    fetch(`/api/rooms/${roomId}/star`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-Token': csrfToken
        },
        body: JSON.stringify({
            filename: filename,
            path: path || ''
        })
    })
    .then(response => {
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        return response.json();
    })
    .then(data => {
        console.log('Star toggle response:', data);
        if (data.success) {
            // Update the file's starred status in currentFiles
            const fileIndex = currentFiles.findIndex(f => f.name === filename && f.path === path);
            if (fileIndex !== -1) {
                currentFiles[fileIndex].starred = data.starred;
            }
        } else {
            // Revert the button if the server request failed
            if (starButton) {
                const isStarred = starButton.title === 'Unstar';
                starButton.style.backgroundColor = isStarred ? 'var(--primary-opacity-8)' : 'var(--warning-opacity-15)';
                starButton.style.color = isStarred ? 'var(--primary-color)' : 'var(--warning-color)';
                starButton.title = isStarred ? 'Star' : 'Unstar';
            }
            console.error('Failed to toggle star:', data.error);
        }
    })
    .catch(error => {
        // Revert the button if there was an error
        if (starButton) {
            const isStarred = starButton.title === 'Unstar';
            starButton.style.backgroundColor = isStarred ? 'var(--primary-opacity-8)' : 'var(--warning-opacity-15)';
            starButton.style.color = isStarred ? 'var(--primary-color)' : 'var(--warning-color)';
            starButton.title = isStarred ? 'Star' : 'Unstar';
        }
        console.error('Error toggling star:', error);
    });
}

function showMoveModal(filename, path) {
    fileToMove = filename;
    fileToMovePath = path;
    
    // Clear any previous errors
    document.getElementById('moveError').textContent = '';
    
    // Fetch available folders
    fetch(`/api/rooms/${roomId}/folders`)
        .then(r => r.json())
        .then(folders => {
            const select = document.getElementById('moveTargetFolder');
            select.innerHTML = '<option value="">Root Folder</option>';
            
            // Sort folders by path to ensure proper hierarchy
            folders.sort((a, b) => {
                if (!a) return -1;
                if (!b) return 1;
                return a.localeCompare(b);
            });
            
            // Add all folders except the current one
            folders.forEach(folderPath => {
                // Skip the current folder and its subfolders
                if (folderPath === path || (path && folderPath.startsWith(path + '/'))) {
                    return;
                }
                
                // Create a display name that shows the folder hierarchy
                const pathParts = folderPath.split('/');
                const displayName = pathParts[pathParts.length - 1];
                const indent = '&nbsp;&nbsp;&nbsp;&nbsp;'.repeat(pathParts.length - 1);
                
                select.innerHTML += `<option value="${folderPath}">${indent}${displayName}</option>`;
            });
            
            // Show the modal
            moveModal.show();
        })
        .catch(error => {
            document.getElementById('moveError').textContent = 'Failed to load folders.';
            console.error('Error loading folders:', error);
        });
}

function moveFileConfirmed() {
    const targetPath = document.getElementById('moveTargetFolder').value;
    const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
    
    fetch(`/api/rooms/${roomId}/move`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-Token': csrfToken
        },
        body: JSON.stringify({
            filename: fileToMove,
            source_path: fileToMovePath,
            target_path: targetPath
        })
    })
    .then(r => r.json())
    .then(res => {
        if (res.success) {
            fetchFiles();
            fileToMove = null;
            fileToMovePath = '';
            moveModal.hide();
            document.getElementById('moveError').textContent = '';
        } else {
            document.getElementById('moveError').textContent = res.error || 'Move failed.';
        }
    })
    .catch(() => {
        document.getElementById('moveError').textContent = 'Move failed.';
    });
}

document.addEventListener('DOMContentLoaded', function() {
    currentPath = getPathFromUrl();
    initializeView();
    updateMultiSelectUI();
    
    // Initialize the overwrite modal with static backdrop
    overwriteModal = new bootstrap.Modal(document.getElementById('overwriteConfirmModal'), {
        backdrop: 'static',
        keyboard: false
    });
    
    // Initialize new folder modal
    const newFolderModal = new bootstrap.Modal(document.getElementById('newFolderModal'));
    
    // Initialize move modal
    moveModal = new bootstrap.Modal(document.getElementById('moveModal'));
    
    // Add click handler for move confirmation button
    if (canMove === true || canMove === 'true') {
        document.getElementById('confirmMoveBtn').addEventListener('click', moveFileConfirmed);
    }
    
    // Add click handler for new folder button
    if (canUpload === true || canUpload === 'true') {
        document.getElementById('newFolderBtn').addEventListener('click', function() {
            document.getElementById('folderNameInput').value = '';
            document.getElementById('folderError').textContent = '';
            newFolderModal.show();
            // Focus the input field after the modal is shown
            setTimeout(() => {
                document.getElementById('folderNameInput').focus();
            }, 100);
        });

        // Add click handler for create folder button
        document.getElementById('createFolderBtn').addEventListener('click', function() {
            const folderName = document.getElementById('folderNameInput').value.trim();
            if (!folderName) {
                document.getElementById('folderError').textContent = 'Folder name is required.';
                return;
            }
            
            const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
            fetch(`/api/rooms/${roomId}/folders`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-Token': csrfToken
                },
                body: JSON.stringify({
                    name: folderName,
                    path: currentPath
                })
            })
            .then(r => r.json())
            .then(res => {
                if (res.success) {
                    newFolderModal.hide();
                    fetchFiles();
                } else {
                    if (res.error === 'A folder with this name exists in the trash') {
                        document.getElementById('folderError').textContent = `Cannot create folder "${folderName}" because this name is currently in the trash. Please restore or permanently delete the trashed item first.`;
                    } else if (res.error === 'A folder with this name already exists in this location') {
                        document.getElementById('folderError').textContent = `A folder named "${folderName}" already exists in this location. Please choose a different name.`;
                    } else {
                        document.getElementById('folderError').textContent = res.error || 'Failed to create folder.';
                    }
                }
            })
            .catch(() => {
                document.getElementById('folderError').textContent = 'Failed to create folder.';
            });
        });
    }
    
    if (canUpload === true || canUpload === 'true') {
        const uploadBtn = document.getElementById('uploadBtn');
        const fileInput = document.getElementById('fileInput');
        const uploadForm = document.getElementById('uploadForm');
        const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
        const fileGrid = document.getElementById('fileGrid');
        const dropZoneOverlay = document.getElementById('dropZoneOverlay');
        const uploadProgressContainer = document.getElementById('uploadProgressContainer');
        const uploadProgressBar = document.getElementById('uploadProgressBar');
        const uploadProgressText = document.getElementById('uploadProgressText');

        let pendingUploads = [];
        let pendingUploadIdx = 0;
        let overwriteAll = false;
        let skipAll = false;

        // Prevent default drag behaviors
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            fileGrid.addEventListener(eventName, preventDefaults, false);
            document.body.addEventListener(eventName, preventDefaults, false);
        });

        // Highlight drop zone when item is dragged over it
        ['dragenter', 'dragover'].forEach(eventName => {
            fileGrid.addEventListener(eventName, highlight, false);
        });

        ['dragleave', 'drop'].forEach(eventName => {
            fileGrid.addEventListener(eventName, unhighlight, false);
        });

        // Handle dropped files
        fileGrid.addEventListener('drop', handleDrop, false);

        function preventDefaults(e) {
            e.preventDefault();
            e.stopPropagation();
        }

        function highlight(e) {
            dropZoneOverlay.style.display = 'block';
        }

        function unhighlight(e) {
            dropZoneOverlay.style.display = 'none';
        }

        async function handleDrop(e) {
            const dt = e.dataTransfer;
            const files = dt.files;
            
            if (files.length > 0) {
                uploadProgressContainer.style.display = 'block';
                uploadProgressBar.style.width = '0%';
                uploadProgressBar.classList.remove('bg-success');
                uploadProgressBar.classList.add('bg-info');
                uploadProgressText.textContent = '';
                
                pendingUploads = Array.from(files);
                pendingUploadIdx = 0;
                overwriteAll = false;
                skipAll = false;
                
                await uploadFilesSequentially();
            }
        }

        uploadBtn.addEventListener('click', () => fileInput.click());
        fileInput.addEventListener('change', async function() {
            if (!fileInput.files.length) return;
            const files = Array.from(fileInput.files);
            uploadProgressContainer.style.display = 'block';
            uploadProgressBar.style.width = '0%';
            uploadProgressBar.classList.remove('bg-success');
            uploadProgressBar.classList.add('bg-info');
            uploadProgressText.textContent = '';
            pendingUploads = files;
            pendingUploadIdx = 0;
            overwriteAll = false;
            skipAll = false;
            await uploadFilesSequentially();
        });

        async function uploadFilesSequentially() {
            console.log('[Upload] Starting uploadFilesSequentially');
            let completedFiles = 0;
            let currentFileIndex = 0;
            
            const updateProgress = () => {
                if (!pendingUploads || currentFileIndex >= pendingUploads.length) {
                    // All files processed, set to 100%
                    uploadProgressBar.style.width = '100%';
                    uploadProgressBar.textContent = '100%';
                    uploadProgressText.textContent = 'Upload complete!';
                    return;
                }
                
                const progress = Math.round((completedFiles / pendingUploads.length) * 100);
                uploadProgressBar.style.width = progress + '%';
                uploadProgressBar.textContent = progress + '%';
                uploadProgressText.textContent = `Uploading ${pendingUploads[currentFileIndex].name} (${currentFileIndex + 1}/${pendingUploads.length})`;
            };

            const processNextFile = async () => {
                if (currentFileIndex >= pendingUploads.length) {
                    // All files processed
                    uploadProgressBar.style.width = '100%';
                    uploadProgressBar.textContent = '100%';
                    uploadProgressBar.classList.remove('bg-info');
                    uploadProgressBar.classList.add('bg-success');
                    uploadProgressText.textContent = 'Upload complete!';
                    
                    // Reset state
                    pendingUploads = null;
                    pendingUploadIdx = null;
                    overwriteAll = false;
                    skipAll = false;
                    
                    // Hide progress after delay
                    setTimeout(() => {
                        uploadProgressContainer.style.display = 'none';
                        uploadProgressText.textContent = '';
                        uploadProgressBar.style.backgroundColor = '#16767b';
                        uploadProgressBar.style.color = '#fff';
                    }, 3000);
                    
                    // Refresh file list
                    await fetchFiles();
                    return;
                }

                const file = pendingUploads[currentFileIndex];
                console.log(`[Upload] Processing file ${currentFileIndex + 1}/${pendingUploads.length}: ${file.name}`);

                const formData = new FormData(uploadForm);
                if (currentPath) {
                    formData.append('path', currentPath);
                }
                formData.set('file', file);

                try {
                    updateProgress();
                    
                    let uploadFormData = formData;
                    if (overwriteAll) {
                        console.log(`[Upload] Using overwrite for file: ${file.name}`);
                        uploadFormData = new FormData(uploadForm);
                        if (currentPath) {
                            uploadFormData.append('path', currentPath);
                        }
                        uploadFormData.set('file', file);
                        uploadFormData.append('overwrite', 'true');
                    }

                    const response = await fetch(`/api/rooms/${roomId}/files/upload`, {
                        method: 'POST',
                        headers: { 'X-CSRF-Token': csrfToken },
                        body: uploadFormData
                    });

                    const resJson = await response.json();

                    if (response.ok) {
                        console.log(`[Upload] Success: ${file.name}`);
                        completedFiles++;
                        currentFileIndex++;
                        updateProgress();
                        await processNextFile();
                    } else if (response.status === 400 && resJson.error === 'File type not allowed') {
                        const allowedTypes = [
                            'Documents: PDF, DOCX, DOC, TXT, RTF, ODT, MD, CSV',
                            'Spreadsheets: XLSX, XLS, ODS, XLSM',
                            'Presentations: PPTX, PPT, ODP',
                            'Images: JPG, JPEG, PNG, GIF, BMP, SVG, WEBP, TIFF',
                            'Archives: ZIP, RAR, 7Z, TAR, GZ',
                            'Code/Text: PY, JS, HTML, CSS, JSON, XML, SQL, SH, BAT',
                            'Audio: MP3, WAV, OGG, M4A, FLAC',
                            'Video: MP4, AVI, MOV, WMV, FLV, MKV, WEBM',
                            'CAD/Design: DWG, DXF, AI, PSD, EPS, INDD',
                            'Other: EML, MSG, VCF, ICS'
                        ].join('\n');
                        
                        const uploadError = document.getElementById('uploadError');
                        const uploadErrorContent = document.getElementById('uploadErrorContent');
                        
                        // Append new error message
                        const newError = `<div class="mb-2"><strong>File type not allowed:</strong> ${file.name}</div>`;
                        if (uploadErrorContent.innerHTML === '') {
                            // First error, add the allowed types list
                            uploadErrorContent.innerHTML = newError + `<div class='mt-2'><strong>Allowed file types:</strong><br>${allowedTypes}</div>`;
                        } else {
                            // Append to existing errors
                            uploadErrorContent.innerHTML = newError + uploadErrorContent.innerHTML;
                        }
                        
                        uploadError.style.display = 'block';
                        uploadProgressBar.style.backgroundColor = '#ef4444';
                        uploadProgressBar.style.color = '#fff';
                        currentFileIndex++;
                        updateProgress();
                        await processNextFile();
                    } else if (response.status === 409) {
                        console.log(`[Upload] Conflict for ${file.name}:`, resJson.error);
                        
                        if (resJson.error.includes('exists in the trash')) {
                            console.log('[Upload] Auto-overwriting trashed file');
                            uploadFormData.append('overwrite', 'true');
                            const retryResponse = await fetch(`/api/rooms/${roomId}/files/upload`, {
                                method: 'POST',
                                headers: { 'X-CSRF-Token': csrfToken },
                                body: uploadFormData
                            });
                            
                            if (retryResponse.ok) {
                                completedFiles++;
                                currentFileIndex++;
                                updateProgress();
                                await processNextFile();
                            }
                            return;
                        }

                        if (overwriteAll) {
                            uploadFormData.append('overwrite', 'true');
                            const retryResponse = await fetch(`/api/rooms/${roomId}/files/upload`, {
                                method: 'POST',
                                headers: { 'X-CSRF-Token': csrfToken },
                                body: uploadFormData
                            });
                            
                            if (retryResponse.ok) {
                                completedFiles++;
                                currentFileIndex++;
                                updateProgress();
                                await processNextFile();
                            }
                            return;
                        }

                        if (skipAll) {
                            console.log(`[Upload] Skip All is set, skipping conflicting file: ${file.name}`);
                            completedFiles++;
                            currentFileIndex++;
                            updateProgress();
                            await processNextFile();
                            return;
                        }

                        uploadProgressText.textContent = resJson.error || `Conflict for ${file.name}`;
                        uploadProgressBar.style.backgroundColor = '#ef4444';
                        uploadProgressBar.style.color = '#fff';

                        const userChoice = await showOverwriteModal(file.name);
                        console.log(`[Upload] Modal choice for ${file.name}:`, userChoice);

                        if (userChoice === 'overwrite' || userChoice === 'overwrite_all') {
                            if (userChoice === 'overwrite_all') {
                                overwriteAll = true;
                            }
                            uploadFormData.append('overwrite', 'true');
                            const retryResponse = await fetch(`/api/rooms/${roomId}/files/upload`, {
                                method: 'POST',
                                headers: { 'X-CSRF-Token': csrfToken },
                                body: uploadFormData
                            });
                            
                            if (retryResponse.ok) {
                                completedFiles++;
                                currentFileIndex++;
                                updateProgress();
                                await processNextFile();
                            }
                        } else if (userChoice === 'skip' || userChoice === 'skip_all') {
                            if (userChoice === 'skip_all') {
                                skipAll = true;
                            }
                            completedFiles++;
                            currentFileIndex++;
                            updateProgress();
                            await processNextFile();
                        }
                    } else {
                        console.error(`[Upload] Error for ${file.name}:`, resJson.error);
                        uploadProgressText.textContent = resJson.error || `Error uploading ${file.name}`;
                        uploadProgressBar.style.backgroundColor = '#ef4444';
                        uploadProgressBar.style.color = '#fff';
                        currentFileIndex++;
                        updateProgress();
                        await processNextFile();
                    }
                } catch (err) {
                    console.error('[Upload] Upload error:', err);
                    uploadProgressText.textContent = `Error uploading ${file.name}`;
                    uploadProgressBar.style.backgroundColor = '#ef4444';
                    uploadProgressBar.style.color = '#fff';
                    currentFileIndex++;
                    updateProgress();
                    await processNextFile();
                }
            };

            // Start processing files
            await processNextFile();
        }
    }
});

// Add event listener for delete confirmation button
if (canDelete === true || canDelete === 'true') {
    document.getElementById('confirmDeleteBtn').addEventListener('click', deleteFileConfirmed);
}

// Add event listener for rename confirmation button
if (canRename === true || canRename === 'true') {
    document.getElementById('confirmRenameBtn').addEventListener('click', function() {
        if (!renameTarget) return;
        let newName = document.getElementById('renameInput').value.trim();
        if (renameIsFile) {
            if (!newName) {
                document.getElementById('renameError').textContent = 'New name is required.';
                return;
            }
            newName = newName + renameOrigExt;
        }
        const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
        if (!newName) {
            document.getElementById('renameError').textContent = 'New name is required.';
            return;
        }
        fetch(`/api/rooms/${roomId}/rename`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRF-Token': csrfToken
            },
            body: JSON.stringify({
                old_name: renameTarget,
                new_name: newName,
                path: currentPath
            })
        })
        .then(r => r.json())
        .then(res => {
            if (res.success) {
                fetchFiles();
                var modalEl = document.getElementById('renameModal');
                var modal = bootstrap.Modal.getInstance(modalEl);
                modal.hide();
            } else {
                document.getElementById('renameError').textContent = res.error || 'Rename failed.';
            }
        })
        .catch(() => {
            document.getElementById('renameError').textContent = 'Rename failed.';
        });
    });
}

// Add event listener for download selected
if (canDownload === true || canDownload === 'true') {
    document.getElementById('downloadSelectedBtn').addEventListener('click', function() {
        const selectedCheckboxes = document.querySelectorAll('.select-item-checkbox:checked');
        if (selectedCheckboxes.length === 0) return;
        
        const selectedItems = Array.from(selectedCheckboxes).map(cb => {
            const idx = parseInt(cb.dataset.idx);
            return window.currentFiles[idx];
        });
        
        // Submit the request to download the zip
        const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
        fetch(`/api/rooms/${roomId}/download-zip`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRF-Token': csrfToken
            },
            body: JSON.stringify({ items: selectedItems })
        })
        .then(response => {
            if (!response.ok) {
                throw new Error('Download failed');
            }
            return response.blob();
        })
        .then(blob => {
            // Create a download link and trigger it
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = 'download.zip';
            document.body.appendChild(a);
            a.click();
            window.URL.revokeObjectURL(url);
            a.remove();
        })
        .catch(error => {
            console.error('Error downloading files:', error);
            document.getElementById('fileError').textContent = 'Failed to download files.';
        });
    });
}

// Add event listener for batch delete
if (canDelete === true || canDelete === 'true') {
    document.getElementById('deleteSelectedBtn').addEventListener('click', function() {
        const selectedCheckboxes = document.querySelectorAll('.select-item-checkbox:checked');
        if (selectedCheckboxes.length === 0) return;
        
        batchDeleteItems = Array.from(selectedCheckboxes).map(cb => {
            const idx = parseInt(cb.dataset.idx);
            return window.currentFiles[idx];
        });
        
        // Get the modal element
        const modalEl = document.getElementById('deleteConfirmModal');
        if (!modalEl) {
            console.error('Delete modal element not found');
            return;
        }
        
        // Initialize the modal if it hasn't been initialized
        if (!deleteModal) {
            deleteModal = new bootstrap.Modal(modalEl);
        }
        
        // Update modal content
        const fileNameEl = document.getElementById('deleteFileName');
        const labelEl = document.getElementById('deleteConfirmLabel');
        
        if (fileNameEl) fileNameEl.textContent = `${selectedCheckboxes.length} item${selectedCheckboxes.length > 1 ? 's' : ''}`;
        if (labelEl) labelEl.textContent = 'Move to Trash';
        
        // Show the modal
        deleteModal.show();
    });
}

function navigateToParent() {
    if (!currentPath) return;
    const parts = currentPath.split('/');
    parts.pop(); // Remove the last part
    const parentPath = parts.join('/');
    navigateTo(parentPath);
}

// Add debounce function
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

// Add search functionality
function performSearch(searchTerm) {
    if (!window.currentFiles) return;
    
    const filteredFiles = window.currentFiles.filter(file => {
        const searchLower = searchTerm.toLowerCase();
        return file.name.toLowerCase().includes(searchLower) ||
               (file.type && file.type.toLowerCase().includes(searchLower));
    });
    
    renderFiles(filteredFiles);
}

// Add event listeners for search
document.addEventListener('DOMContentLoaded', function() {
    const searchInput = document.getElementById('quickSearchInput');
    const clearSearchBtn = document.getElementById('clearSearchBtn');
    
    if (searchInput) {
        // Create debounced search function
        const debouncedSearch = debounce((searchTerm) => {
            if (searchTerm) {
                performSearch(searchTerm);
                clearSearchBtn.style.display = 'block';
            } else {
                fetchFiles(); // Reset to show all files
                clearSearchBtn.style.display = 'none';
            }
        }, 300);

        searchInput.addEventListener('input', function(e) {
            const searchTerm = e.target.value.trim();
            debouncedSearch(searchTerm);
        });
        
        // Add clear search button functionality
        if (clearSearchBtn) {
            clearSearchBtn.addEventListener('click', function() {
                searchInput.value = '';
                fetchFiles(); // Reset to show all files
                clearSearchBtn.style.display = 'none';
            });
        }
    }
});
</script>
{% endblock %} 