<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Share Files</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: "Courier New", monospace;
      background: white;
      color: black;
      line-height: 1.4;
    }

    .container {
      max-width: 100%;
      margin: 0 auto;
      padding: 20px 10px;
    }

    .header {
      border-bottom: 2px solid black;
      padding-bottom: 15px;
      margin-bottom: 20px;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .header h1 {
      font-size: 24px;
      font-weight: bold;
    }

    .breadcrumb {
      font-size: 14px;
      color: #666;
    }

    .breadcrumb a {
      color: black;
      text-decoration: none;
    }

    .breadcrumb a:hover {
      text-decoration: underline;
    }

    .selection-panel {
      background: #f9f9f9;
      border: 1px solid #ccc;
      padding: 15px;
      margin-bottom: 20px;
      border-radius: 4px;
    }

    .selected-files {
      margin-bottom: 10px;
      min-height: 20px;
    }

    .selected-file {
      display: inline-block;
      background: black;
      color: white;
      padding: 2px 8px;
      margin: 2px;
      border-radius: 3px;
      font-size: 12px;
      cursor: pointer;
    }

    .selected-file:hover {
      background: #333;
    }

    .action-buttons {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
    }

    .cloud-browser-modal {
      max-width: 720px;
      width: 100%;
    }

    .cloud-controls {
      display: flex;
      gap: 10px;
      align-items: center;
      margin-bottom: 10px;
      font-size: 12px;
    }

    .cloud-controls select {
      padding: 4px 6px;
      border: 1px solid #ccc;
      border-radius: 3px;
      font-family: 'Courier New', monospace;
      font-size: 12px;
    }

    .cloud-upload {
      display: flex;
      gap: 8px;
      align-items: center;
      margin-bottom: 8px;
      flex-wrap: wrap;
      font-size: 12px;
    }

    .cloud-upload input[type="file"] {
      font-family: 'Courier New', monospace;
      font-size: 12px;
    }

    .cloud-upload-status {
      font-size: 12px;
      color: #0066cc;
      min-height: 16px;
      margin-bottom: 10px;
    }

    .cloud-upload-status.error {
      color: #cc3300;
    }

    .cloud-path {
      font-size: 12px;
      color: #555;
      margin-bottom: 8px;
      word-break: break-word;
    }

    .cloud-status {
      min-height: 18px;
      font-size: 12px;
      color: #0066cc;
      margin-bottom: 10px;
    }

    .cloud-status.error {
      color: #cc3300;
    }

    .cloud-table-wrapper {
      max-height: 360px;
      overflow-y: auto;
      border: 1px solid #ccc;
      border-radius: 3px;
    }

    .cloud-table-wrapper .file-table th,
    .cloud-table-wrapper .file-table td {
      font-size: 12px;
    }

    .btn {
      font-family: "Courier New", monospace;
      border: 1px solid black;
      background: white;
      color: black;
      padding: 8px 12px;
      cursor: pointer;
      text-decoration: none;
      font-size: 12px;
      border-radius: 3px;
    }

    .btn:hover {
      background: #f0f0f0;
    }

    .btn:disabled {
      background: #eee;
      color: #999;
      cursor: not-allowed;
    }

    .btn.primary {
      background: black;
      color: white;
    }

    .btn.primary:hover {
      background: #333;
    }

    .file-table {
      width: 100%;
      border-collapse: collapse;
      border: 1px solid black;
      background: white;
      table-layout: fixed;
    }

    .file-table th {
      background: black;
      color: white;
      padding: 10px 12px;
      text-align: left;
      font-weight: bold;
      border-bottom: 2px solid black;
    }

    .file-table td {
      padding: 8px 12px;
      border-bottom: 1px solid #ddd;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .file-table tbody tr:hover {
      background: #f5f5f5;
    }

    .file-table tbody tr.selected {
      background: #e6f3ff;
    }

    .select-col {
      width: 40px;
    }

    .name-col {
      width: 50%;
    }

    .size-col {
      width: 15%;
    }

    .modified-col {
      width: 20%;
    }

    .actions-col {
      width: 15%;
    }

    .file-link {
      color: black;
      text-decoration: none;
      display: inline-block;
      cursor: pointer;
      white-space: nowrap;
    }

    .file-link:hover {
      text-decoration: underline;
    }

    .file-icon {
      margin-right: 8px;
      display: inline-block;
      vertical-align: middle;
    }

    .shared-icon {
      cursor: pointer;
      color: #0066cc;
      font-size: 14px;
      transition: all 0.2s ease;
      display: inline-block;
      vertical-align: middle;
      padding: 2px 4px;
      border-radius: 3px;
      background: rgba(0, 102, 204, 0.1);
    }

    .shared-icon:hover {
      color: #004499;
      transform: scale(1.2);
      background: rgba(0, 102, 204, 0.2);
    }

    .share-result {
      background: #e8f5e8;
      border: 1px solid #4a934a;
      padding: 10px;
      margin-top: 15px;
      border-radius: 4px;
      display: none;
    }

    .active-shares {
      margin-top: 30px;
      border-top: 2px solid #ccc;
      padding-top: 20px;
    }

    .shares-table {
      width: 100%;
      border-collapse: collapse;
      border: 1px solid #ccc;
      margin-top: 10px;
    }

    .shares-table th,
    .shares-table td {
      border: 1px solid #ccc;
      padding: 8px;
      text-align: left;
    }

    .shares-table th {
      background: #f0f0f0;
    }

    .loading {
      text-align: center;
      padding: 40px;
      color: #666;
    }

    /* Share Popup Styles */
    .popup-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.5);
      z-index: 1000;
      opacity: 0;
      visibility: hidden;
      transition: all 0.3s ease;
    }

    .popup-overlay.show {
      opacity: 1;
      visibility: visible;
    }

    .popup-content {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%) scale(0.8);
      background: white;
      border: 2px solid black;
      border-radius: 8px;
      padding: 20px;
      max-width: 500px;
      width: 90%;
      max-height: 80vh;
      overflow-y: auto;
      transition: all 0.3s ease;
      box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
    }

    .popup-overlay.show .popup-content {
      transform: translate(-50%, -50%) scale(1);
    }

    .popup-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;
      padding-bottom: 10px;
      border-bottom: 1px solid #ccc;
    }

    .popup-title {
      font-size: 18px;
      font-weight: bold;
      margin: 0;
    }

    .popup-close {
      background: none;
      border: none;
      font-size: 24px;
      cursor: pointer;
      padding: 0;
      width: 30px;
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .popup-close:hover {
      background: #f0f0f0;
      border-radius: 50%;
    }

    .share-item {
      border: 1px solid #ddd;
      border-radius: 4px;
      padding: 15px;
      margin-bottom: 15px;
      background: #fafafa;
    }

    .share-item:last-child {
      margin-bottom: 0;
    }

    .share-id {
      font-family: monospace;
      background: #e6f3ff;
      padding: 4px 8px;
      border-radius: 3px;
      font-size: 12px;
      margin-bottom: 8px;
      display: inline-block;
    }

    .share-url {
      margin-bottom: 10px;
    }

    .share-url a {
      color: #0066cc;
      text-decoration: none;
      font-size: 14px;
    }

    .share-url a:hover {
      text-decoration: underline;
    }

    .share-access {
      margin-bottom: 10px;
      font-size: 14px;
    }

    .share-access.public {
      color: #4a934a;
    }

    .share-access.restricted {
      color: #cc6600;
    }

    .share-users {
      margin-top: 10px;
    }

    .share-users-title {
      font-size: 12px;
      color: #666;
      margin-bottom: 5px;
    }

    .user-tag {
      display: inline-block;
      background: #e6f3ff;
      color: #0066cc;
      padding: 2px 6px;
      margin: 2px;
      border-radius: 3px;
      font-size: 11px;
    }

    .share-actions {
      margin-top: 15px;
      display: flex;
      gap: 10px;
    }

    .share-actions .btn {
      font-size: 11px;
      padding: 6px 10px;
    }

    /* Share Management Modal Styles */
    .share-management-modal {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.6);
      z-index: 1001;
      display: none;
      align-items: center;
      justify-content: center;
    }

    .share-management-modal.show {
      display: flex;
    }

    .share-management-content {
      background: white;
      border: 2px solid black;
      border-radius: 8px;
      max-width: 800px;
      width: 95%;
      max-height: 90vh;
      overflow-y: auto;
      box-shadow: 0 10px 40px rgba(0, 0, 0, 0.4);
    }

    .share-management-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 20px;
      border-bottom: 1px solid #ddd;
      background: #f9f9f9;
    }

    .share-management-title {
      font-size: 20px;
      font-weight: bold;
      margin: 0;
    }

    .share-management-close {
      background: none;
      border: none;
      font-size: 24px;
      cursor: pointer;
      padding: 5px;
      width: 35px;
      height: 35px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
    }

    .share-management-close:hover {
      background: #e0e0e0;
    }

    .share-management-body {
      padding: 20px;
    }

    .share-management-footer {
      padding: 15px 20px;
      border-top: 1px solid #ddd;
      display: flex;
      gap: 10px;
      justify-content: flex-end;
    }

    .share-info-section {
      margin-bottom: 25px;
      padding: 15px;
      border: 1px solid #ddd;
      border-radius: 6px;
      background: #fafafa;
    }

    .share-info-section h3 {
      margin: 0 0 10px 0;
      font-size: 16px;
      color: #333;
    }

    .share-files-list {
      max-height: 200px;
      overflow-y: auto;
      border: 1px solid #ccc;
      border-radius: 4px;
      background: white;
    }

    .share-file-item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 8px 12px;
      border-bottom: 1px solid #eee;
      font-size: 13px;
    }

    .share-file-item:last-child {
      border-bottom: none;
    }

    .share-file-item:hover {
      background: #f5f5f5;
    }

    .share-file-remove {
      background: #dc3545;
      color: white;
      border: none;
      border-radius: 3px;
      padding: 4px 8px;
      font-size: 11px;
      cursor: pointer;
    }

    .share-file-remove:hover {
      background: #c82333;
    }

    .access-list-section {
      margin-top: 20px;
    }

    .access-users-list {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-bottom: 15px;
      min-height: 40px;
      padding: 10px;
      border: 1px solid #ccc;
      border-radius: 4px;
      background: white;
    }

    .access-user-tag {
      display: inline-flex;
      align-items: center;
      background: #007bff;
      color: white;
      padding: 4px 8px;
      border-radius: 15px;
      font-size: 12px;
      gap: 4px;
    }

    .access-user-remove {
      background: none;
      border: none;
      color: white;
      cursor: pointer;
      font-size: 14px;
      padding: 0;
      margin-left: 4px;
    }

    .access-user-remove:hover {
      color: #ccc;
    }

    .access-user-input-section {
      display: flex;
      gap: 10px;
      margin-bottom: 15px;
    }

    .access-user-input {
      flex: 1;
      padding: 8px;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 13px;
    }

    .access-user-add {
      background: #28a745;
      color: white;
      border: none;
      border-radius: 4px;
      padding: 8px 12px;
      cursor: pointer;
      font-size: 13px;
    }

    .access-user-add:hover {
      background: #218838;
    }

    .access-user-add:disabled {
      background: #6c757d;
      cursor: not-allowed;
    }

    .share-management-actions {
      display: flex;
      justify-content: flex-end;
      gap: 10px;
      padding-top: 20px;
      border-top: 1px solid #ddd;
    }

    .share-management-save {
      background: #28a745;
      color: white;
      border: none;
      border-radius: 4px;
      padding: 10px 20px;
      cursor: pointer;
      font-size: 14px;
    }

    .share-management-save:hover {
      background: #218838;
    }

    .share-management-cancel {
      background: #6c757d;
      color: white;
      border: none;
      border-radius: 4px;
      padding: 10px 20px;
      cursor: pointer;
      font-size: 14px;
    }

    .share-management-cancel:hover {
      background: #5a6268;
    }

    .share-files-actions {
      margin-top: 15px;
      padding-top: 15px;
      border-top: 1px solid #eee;
    }

    .share-files-actions .btn {
      background: #007bff;
      color: white;
      border: none;
      border-radius: 4px;
      padding: 8px 16px;
      cursor: pointer;
      font-size: 14px;
    }

    .share-files-actions .btn:hover {
      background: #0056b3;
    }

    /* Custom dialog modal styles */
    .custom-dialog-modal {
      display: none;
      position: fixed;
      z-index: 2000;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      align-items: center;
      justify-content: center;
    }

    .custom-dialog-modal.show {
      display: flex;
    }

    .custom-dialog-modal-content {
      background-color: #fff;
      padding: 25px;
      border-radius: 8px;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
      width: 90%;
      max-width: 400px;
      text-align: center;
    }

    .custom-dialog-modal-content h2 {
      margin-top: 0;
      font-size: 1.25rem;
    }

    .custom-dialog-modal-content p {
      margin: 15px 0;
      font-size: 1rem;
      color: #333;
    }

    .custom-dialog-input {
      width: calc(100% - 20px);
      padding: 10px;
      margin-bottom: 20px;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 14px;
    }

    .custom-dialog-buttons {
      display: flex;
      justify-content: center;
      gap: 10px;
    }

    .custom-dialog-buttons button {
      padding: 10px 20px;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      font-weight: bold;
      font-size: 14px;
    }

    .custom-dialog-buttons button#dialogConfirmBtn {
      background-color: #007bff;
      color: white;
    }

    .custom-dialog-buttons button#dialogConfirmBtn:hover {
      background-color: #0056b3;
    }

    .custom-dialog-buttons button#dialogCancelBtn {
      background-color: #ccc;
      color: #333;
    }

    .custom-dialog-buttons button#dialogCancelBtn:hover {
      background-color: #999;
    }

    /* Add Files Modal Styles */
    .add-files-modal {
      display: none;
      position: fixed;
      z-index: 2000;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      align-items: center;
      justify-content: center;
    }

    .add-files-modal.show {
      display: flex;
    }

    .add-files-modal-content {
      background-color: #fff;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
      width: 90%;
      max-width: 800px;
      max-height: 80vh;
      overflow-y: auto;
    }

    .add-files-close {
      color: #aaa;
      float: right;
      font-size: 28px;
      font-weight: bold;
      cursor: pointer;
      line-height: 1;
    }

    .add-files-close:hover {
      color: #000;
    }

    .add-files-body {
      display: flex;
      gap: 20px;
      margin: 20px 0;
    }

    .file-browser {
      flex: 2;
      border: 1px solid #ddd;
      border-radius: 4px;
      overflow: hidden;
    }

    .file-browser-header {
      background: #f8f9fa;
      padding: 10px;
      border-bottom: 1px solid #ddd;
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .file-browser-content {
      max-height: 300px;
      overflow-y: auto;
      padding: 10px;
    }

    .file-browser-item {
      display: flex;
      align-items: center;
      padding: 8px;
      cursor: pointer;
      border-radius: 4px;
      margin-bottom: 2px;
    }

    .file-browser-item:hover {
      background: #f8f9fa;
    }

    .file-browser-item.selected {
      background: #e3f2fd;
    }

    .file-browser-item input[type="checkbox"] {
      margin-right: 8px;
    }

    .selected-files-preview {
      flex: 1;
      border: 1px solid #ddd;
      border-radius: 4px;
      padding: 15px;
      background: #f8f9fa;
    }

    .selected-files-preview h4 {
      margin: 0 0 10px 0;
      font-size: 14px;
      color: #333;
    }

    .selected-file-item {
      background: #e3f2fd;
      padding: 4px 8px;
      margin: 2px 0;
      border-radius: 3px;
      font-size: 12px;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .selected-file-item .remove-btn {
      background: none;
      border: none;
      color: #666;
      cursor: pointer;
      font-size: 14px;
      padding: 0;
      width: 16px;
      height: 16px;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .add-files-actions {
      display: flex;
      justify-content: flex-end;
      gap: 10px;
      padding-top: 20px;
      border-top: 1px solid #ddd;
    }

    .btn-secondary {
      background: #6c757d;
      color: white;
    }

    .btn-secondary:hover {
      background: #5a6268;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="header">
      <div>
        <h1>Share Files</h1>
        <div class="breadcrumb">
          <a href="/files/">🏠 Home</a> /
          <span id="currentPath">Browse & Select Files</span>
        </div>
      </div>
      <div style="display: flex; align-items: center; gap: 10px;">
        <a href="/profile" style="font-size: 12px; color: #666; margin-right: 15px; text-decoration: none;">👤 {{
          handler.get_display_username() }}</a>
        <a href="/files/" class="btn">📁 Browse Files</a>
        <a href="/logout" class="btn">↩ Logout</a>
      </div>
    </div>

    <!-- Selection Panel -->
    <div class="selection-panel">
      <div>
        <strong>Selected Files (<span id="selectedCount">0</span>):</strong>
      </div>
      <div class="selected-files" id="selectedFiles">
        <em style="color: #666;">No files selected</em>
      </div>

      <!-- User Access Control -->
      <div style="margin: 15px 0; padding: 10px; border: 1px solid #ddd; border-radius: 4px; background: #fafafa;">
        <div style="margin-bottom: 10px;">
          <strong>Access Control:</strong>
        </div>
        <div style="margin-bottom: 10px;">
          <label style="display: flex; align-items: center; gap: 8px;">
            <input type="radio" name="accessType" value="public" checked onchange="toggleUserSelectionPanel()">
            <span>Public (Anyone with link can access)</span>
          </label>
        </div>
        <div style="margin-bottom: 10px;">
          <label style="display: flex; align-items: center; gap: 8px;">
            <input type="radio" name="accessType" value="restricted" onchange="toggleUserSelectionPanel()">
            <span>Restricted (Only selected users can access)</span>
          </label>
        </div>
        <div id="userSelection" style="display: none; margin-top: 10px;">
          <div style="margin-bottom: 8px;">
            <strong>Select Users:</strong>
          </div>
          <div style="margin-bottom: 8px;">
            <input type="text" id="userSearchInput" placeholder="Type to search users..."
              style="width: 100%; padding: 6px; border: 1px solid #ccc; border-radius: 3px; font-family: 'Courier New', monospace; font-size: 12px;">
          </div>
          <div id="userList"
            style="max-height: 120px; overflow-y: auto; border: 1px solid #ccc; padding: 8px; background: white;">
            <em style="color: #666;">Type to search for users...</em>
          </div>
          <div id="selectedUsers" style="margin-top: 8px; min-height: 20px;">
            <div style="font-size: 12px; color: #666; margin-bottom: 5px;">Selected users:</div>
            <div id="selectedUsersList" style="min-height: 20px;">
              <em style="color: #999; font-size: 11px;">No users selected</em>
            </div>
          </div>
        </div>
      </div>

      <!-- Share Type Selection -->
      <div style="margin: 15px 0; padding: 10px; border: 1px solid #ddd; border-radius: 4px; background: #fafafa;">
        <div style="margin-bottom: 10px;">
          <strong>Share Type:</strong>
        </div>
        <div style="margin-bottom: 10px;">
          <label style="display: flex; align-items: center; gap: 8px;">
            <input type="radio" name="shareType" value="static" checked onchange="toggleShareTypeInfo()">
            <span>Static (Snapshot of current files)</span>
          </label>
        </div>
        <div style="margin-bottom: 10px;">
          <label style="display: flex; align-items: center; gap: 8px;">
            <input type="radio" name="shareType" value="dynamic" onchange="toggleShareTypeInfo()">
            <span>Dynamic (Live folder sharing)</span>
          </label>
        </div>
        <div id="shareTypeInfo"
          style="margin-top: 8px; padding: 8px; background: #e8f4fd; border-radius: 3px; font-size: 12px; color: #0066cc;">
          <strong>Static Share:</strong> Creates a snapshot of all files at the time of sharing. New files added later
          won't appear in the share.
        </div>
      </div>

      <!-- Token Security -->
      <div style="margin: 15px 0; padding: 10px; border: 1px solid #ddd; border-radius: 4px; background: #fafafa;">
        <div style="margin-bottom: 10px;">
          <strong>Security Options:</strong>
        </div>
        <div style="margin-bottom: 10px;">
          <label style="display: flex; align-items: center; gap: 8px;">
            <input type="checkbox" id="disableToken" onchange="toggleTokenInfo()">
            <span>Disable Secret Token (Public Access)</span>
          </label>
        </div>
        <div id="tokenInfo"
          style="margin-top: 8px; padding: 8px; background: #e8f4fd; border-radius: 3px; font-size: 12px; color: #0066cc;">
          <strong>🔐 Token Enabled:</strong> Users will need to enter a secret token to access the shared files.
        </div>
      </div>

      <!-- Expiry Date -->
      <div style="margin: 15px 0; padding: 10px; border: 1px solid #ddd; border-radius: 4px; background: #fafafa;">
        <div style="margin-bottom: 10px;">
          <strong>Expiry Date (Optional):</strong>
        </div>
        <div style="margin-bottom: 10px;">
          <label style="display: block; margin-bottom: 5px; font-size: 12px;">
            <strong>Share Expires On:</strong>
          </label>
          <input type="datetime-local" id="expiryDate"
            style="width: 100%; padding: 6px; border: 1px solid #ccc; border-radius: 3px; font-family: 'Courier New', monospace; font-size: 12px;">
          <div style="font-size: 11px; color: #666; margin-top: 3px;">
            Leave empty for no expiration. The share will automatically become inaccessible after this date/time.
          </div>
        </div>
        <div
          style="margin-top: 8px; padding: 8px; background: #fff3cd; border-radius: 3px; font-size: 12px; color: #856404;">
          <strong>⏰ Note:</strong> After expiration, users will receive a "share has expired" message when attempting to
          access it.
        </div>
      </div>

      <!-- File Filtering -->
      <div style="margin: 15px 0; padding: 10px; border: 1px solid #ddd; border-radius: 4px; background: #fafafa;">
        <div style="margin-bottom: 10px;">
          <strong>File Filtering (Optional):</strong>
        </div>
        <div style="margin-bottom: 10px;">
          <label style="display: block; margin-bottom: 5px; font-size: 12px;">
            <strong>Allow List (Glob Patterns):</strong>
          </label>
          <textarea id="allowList" placeholder="*.txt, *.pdf, images/*.jpg, documents/**"
            style="width: 100%; padding: 6px; border: 1px solid #ccc; border-radius: 3px; font-family: 'Courier New', monospace; font-size: 12px; height: 60px; resize: vertical;"></textarea>
          <div style="font-size: 11px; color: #666; margin-top: 3px;">
            Comma-separated glob patterns. If empty, all files are allowed (unless in avoid list).
          </div>
        </div>
        <div style="margin-bottom: 10px;">
          <label style="display: block; margin-bottom: 5px; font-size: 12px;">
            <strong>Avoid List (Glob Patterns):</strong>
          </label>
          <textarea id="avoidList" placeholder="*.tmp, *.log, temp/*, .git/**"
            style="width: 100%; padding: 6px; border: 1px solid #ccc; border-radius: 3px; font-family: 'Courier New', monospace; font-size: 12px; height: 60px; resize: vertical;"></textarea>
          <div style="font-size: 11px; color: #666; margin-top: 3px;">
            Comma-separated glob patterns. Files matching these patterns will be excluded (takes priority over allow
            list).
          </div>
        </div>
        <div
          style="margin-top: 8px; padding: 8px; background: #fff3cd; border-radius: 3px; font-size: 12px; color: #856404;">
          <strong>💡 Examples:</strong><br>
          • Allow: <code>*.pdf, *.docx, images/*</code><br>
          • Avoid: <code>*.tmp, .git/**, temp/*</code><br>
          • Use <code>**</code> for recursive matching
        </div>
      </div>

      <div class="action-buttons">
        <button class="btn primary" id="generateLink" disabled>Generate Share Link</button>
        <button class="btn" id="clearSelection">Clear Selection</button>
        <button class="btn" id="openCloudBrowser">Browse Cloud Drives</button>
        <button class="btn" id="selectAllVisible">Select All (Current Dir)</button>
      </div>
      <div class="share-result" id="shareResult"></div>
    </div>

    <!-- File Browser -->
    <table class="file-table" id="fileTable">
      <thead>
        <tr>
          <th class="select-col">✓</th>
          <th class="name-col">📁 Name</th>
          <th class="size-col">📏 Size</th>
          <th class="modified-col">🕒 Modified</th>
          <th class="actions-col">⚡ Actions</th>
        </tr>
      </thead>
      <tbody id="fileTableBody">
        <tr>
          <td colspan="5" class="loading">Loading files...</td>
        </tr>
      </tbody>
    </table>

    <!-- Active Shares -->
    <div class="active-shares">
      <h2>Active Shares (<span id="activeSharesCount">0</span>)</h2>
      <table class="shares-table" id="sharesTable">
        <thead>
          <tr>
            <th>Share ID</th>
            <th>Files Count</th>
            <th>Access</th>
            <th>Created</th>
            <th>Actions</th>

          </tr>
        </thead>
        <tbody id="sharesTableBody">
          <tr>
            <td colspan="6" class="loading">Loading active shares...</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

  <!-- Cloud Browser Modal -->
  <div id="cloudBrowserModal" class="popup-overlay">
    <div class="popup-content cloud-browser-modal">
      <div class="popup-header">
        <h3 class="popup-title">Cloud Drives</h3>
        <button class="popup-close" id="cloudBrowserClose">&times;</button>
      </div>
      <div class="cloud-controls">
        <label for="cloudProviderSelect">Provider:</label>
        <select id="cloudProviderSelect"></select>
        <button class="btn" type="button" id="cloudUpButton">⬆️ Up</button>
      </div>
      <div class="cloud-upload">
        <input type="file" id="cloudUploadInput" title="Choose a file to upload to the selected cloud folder">
        <button class="btn" type="button" id="cloudUploadButton">Upload to folder</button>
      </div>
      <div class="cloud-upload-status" id="cloudUploadStatus"></div>
      <div class="cloud-path" id="cloudPathDisplay"></div>
      <div class="cloud-status" id="cloudStatusMessage"></div>
      <div class="cloud-table-wrapper">
        <table class="file-table">
          <thead>
            <tr>
              <th class="name-col">📁 Name</th>
              <th class="size-col">📏 Size</th>
              <th class="modified-col">🕒 Modified</th>
              <th class="actions-col">⚡ Actions</th>
            </tr>
          </thead>
          <tbody id="cloudFilesTableBody">
            <tr>
              <td colspan="4" class="loading">Loading...</td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>

  <!-- Share Details Popup -->
  <div id="sharePopup" class="popup-overlay">
    <div class="popup-content">
      <div class="popup-header">
        <h3 class="popup-title">Share Details</h3>
        <button class="popup-close" id="sharePopupClose">&times;</button>
      </div>
      <div id="sharePopupContent">
        <div class="loading">Loading share details...</div>
      </div>
    </div>
  </div>

  <!-- Share Management Modal -->
  <div id="shareManagementModal" class="share-management-modal">
    <div class="share-management-content">
      <div class="share-management-header">
        <h2 class="share-management-title">Manage Share</h2>
        <button class="share-management-close" id="shareManagementClose">&times;</button>
      </div>
      <div class="share-management-body" id="shareManagementBody">
        <div class="loading">Loading share details...</div>
      </div>
      <div class="share-management-footer">
        <button class="btn primary" id="updateShareBtn">Update Share</button>
        <button class="btn" id="shareManagementCancel">Cancel</button>
      </div>
    </div>
  </div>

  <div id="customDialogModal" class="custom-dialog-modal">
    <div class="custom-dialog-modal-content">
      <h2 id="dialogTitle">Dialog</h2>
      <p id="dialogMessage"></p>
      <div id="dialogInputContainer" style="display: none;">
        <input type="text" id="dialogInput" class="custom-dialog-input">
      </div>
      <div class="custom-dialog-buttons">
        <button id="dialogConfirmBtn">Confirm</button>
        <button id="dialogCancelBtn">Cancel</button>
      </div>
    </div>
  </div>

  <!-- Add Files Modal -->
  <div id="addFilesModal" class="add-files-modal">
    <div class="add-files-modal-content">
      <span class="add-files-close" id="addFilesClose">&times;</span>
      <h2>Add Files to Share</h2>
      <div class="add-files-body">
        <div class="file-browser">
          <div class="file-browser-header">
            <button class="btn" id="navigateUpBtn">↑ Up</button>
            <span id="currentBrowsePath">Root Directory</span>
          </div>
          <div class="file-browser-content" id="fileBrowserContent">
            <div class="loading">Loading files...</div>
          </div>
        </div>
        <div class="selected-files-preview">
          <h4>Selected Files:</h4>
          <div id="selectedFilesPreview"></div>
        </div>
      </div>
      <div class="add-files-actions">
        <button class="btn" id="addSelectedFilesBtn">Add Selected Files</button>
        <button class="btn btn-secondary" id="addFilesCancel">Cancel</button>
      </div>
    </div>
  </div>

  <script nonce="{{ csp_nonce }}">
    let currentPath = '';
    let selectedFiles = new Set();
    let allFiles = [];
    let allUsers = [];
    let selectedUsers = new Set();

    const elements = {
      currentPath: document.getElementById('currentPath'),
      selectedCount: document.getElementById('selectedCount'),
      selectedFilesDiv: document.getElementById('selectedFiles'),
      generateLink: document.getElementById('generateLink'),
      clearSelection: document.getElementById('clearSelection'),
      selectAllVisible: document.getElementById('selectAllVisible'),
      shareResult: document.getElementById('shareResult'),
      fileTableBody: document.getElementById('fileTableBody'),
      sharesTableBody: document.getElementById('sharesTableBody'),
      activeSharesCount: document.getElementById('activeSharesCount')
    };

    const selectedFileMetadata = new Map();

    const cloudElements = {
      modal: document.getElementById('cloudBrowserModal'),
      providerSelect: document.getElementById('cloudProviderSelect'),
      pathDisplay: document.getElementById('cloudPathDisplay'),
      statusMessage: document.getElementById('cloudStatusMessage'),
      tableBody: document.getElementById('cloudFilesTableBody'),
      upButton: document.getElementById('cloudUpButton'),
      uploadInput: document.getElementById('cloudUploadInput'),
      uploadButton: document.getElementById('cloudUploadButton'),
      uploadStatus: document.getElementById('cloudUploadStatus')
    };

    const cloudState = {
      providers: [],
      currentProvider: null,
      currentFolder: null,
      currentFiles: [],
      pathStack: [],
      loading: false,
      uploading: false
    };

    function getFileIcon(filename) {
      const ext = filename.toLowerCase().split('.').pop();
      const lowerFilename = filename.toLowerCase();

      // Special files by name - IDE-style
      if (['readme', 'readme.md', 'readme.txt'].includes(lowerFilename)) return '📖';
      if (['license', 'licence', 'copying'].includes(lowerFilename)) return '📜';
      if (['makefile', 'cmake', 'cmakelists.txt'].includes(lowerFilename)) return '🔨';
      if (['dockerfile', 'docker-compose.yml', 'docker-compose.yaml'].includes(lowerFilename)) return '🐳';
      if (['.gitignore', '.gitattributes', '.gitmodules'].includes(lowerFilename)) return '🔧';
      if (lowerFilename.startsWith('.env')) return '🔐';

      const iconMap = {
        // Document files - IDE-style
        'txt': '📄', 'md': '📄', 'rst': '📄', 'text': '📄',
        'doc': '📝', 'docx': '📝', 'rtf': '📝', 'odt': '📝',
        'pdf': '📕',
        'xls': '📊', 'xlsx': '📊', 'ods': '📊', 'csv': '📊',
        'ppt': '📋', 'pptx': '📋', 'odp': '📋',

        // Image files - IDE-style
        'jpg': '🖼️', 'jpeg': '🖼️', 'png': '🖼️', 'gif': '🖼️', 'bmp': '🖼️', 'webp': '🖼️', 'tiff': '🖼️', 'tif': '🖼️',
        'svg': '🎨', 'ico': '🎨',
        'psd': '🎭', 'ai': '🎭', 'sketch': '🎭',

        // Programming files - IDE-style (VS Code inspired)
        'py': '🐍', 'pyw': '🐍', 'pyc': '🐍', 'pyo': '🐍',
        'js': '🟨', 'jsx': '🟨', 'ts': '🟨', 'tsx': '🟨', 'mjs': '🟨',
        'java': '☕', 'class': '☕', 'jar': '☕',
        'cpp': '⚙️', 'cxx': '⚙️', 'cc': '⚙️', 'c': '⚙️', 'h': '⚙️', 'hpp': '⚙️',
        'cs': '🔷', 'vb': '🔷', 'fs': '🔷',
        'php': '🐘', 'phtml': '🐘',
        'rb': '💎', 'rake': '💎', 'gem': '💎',
        'go': '🐹',
        'rs': '🦀',
        'swift': '🦉',
        'kt': '🟣', 'kts': '🟣',
        'scala': '🔴',
        'r': '📊', 'rmd': '📊',
        'm': '🍎', 'mm': '🍎',
        'pl': '🐪', 'pm': '🐪',
        'sh': '📟', 'bash': '📟', 'zsh': '📟', 'fish': '📟', 'bat': '📟', 'cmd': '📟', 'ps1': '📟',
        'lua': '🌙',
        'dart': '🎯',

        // Web files - IDE-style
        'html': '🌐', 'htm': '🌐', 'xhtml': '🌐',
        'css': '🎨', 'scss': '🎨', 'sass': '🎨', 'less': '🎨',
        'xml': '📰', 'xsl': '📰', 'xsd': '📰',
        'json': '📋', 'jsonl': '📋',
        'yaml': '📄', 'yml': '📄',
        'toml': '⚙️', 'ini': '⚙️', 'cfg': '⚙️', 'conf': '⚙️',

        // Archive files - IDE-style
        'zip': '🗜️', 'rar': '🗜️', '7z': '🗜️', 'tar': '🗜️', 'gz': '🗜️', 'bz2': '🗜️', 'xz': '🗜️', 'lz': '🗜️', 'lzma': '🗜️',
        'deb': '📦', 'rpm': '📦', 'pkg': '📦', 'dmg': '📦', 'msi': '📦', 'exe': '📦',

        // Video files - IDE-style
        'mp4': '🎬', 'avi': '🎬', 'mkv': '🎬', 'mov': '🎬', 'wmv': '🎬', 'flv': '🎬', 'webm': '🎬', 'm4v': '🎬', '3gp': '🎬', 'ogv': '🎬', 'mpg': '🎬', 'mpeg': '🎬',

        // Audio files - IDE-style
        'mp3': '🎵', 'wav': '🎵', 'flac': '🎵', 'aac': '🎵', 'ogg': '🎵', 'm4a': '🎵', 'wma': '🎵', 'opus': '🎵', 'aiff': '🎵',

        // Font files - IDE-style
        'ttf': '🔤', 'otf': '🔤', 'woff': '🔤', 'woff2': '🔤', 'eot': '🔤',

        // Database files - IDE-style
        'db': '🗃️', 'sqlite': '🗃️', 'sqlite3': '🗃️', 'mdb': '🗃️', 'accdb': '🗃️',

        // Log files - IDE-style
        'log': '📜', 'out': '📜', 'err': '📜',

        // Data files - IDE-style
        'sql': '🗄️',
        'parquet': '📊', 'avro': '📊', 'orc': '📊',

        // Notebook files - IDE-style
        'ipynb': '📓'
      };

      return iconMap[ext] || '📦';
    }

    function formatFileSize(bytes) {
      if (bytes === 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    function escapeHtml(text) {
      if (text === undefined || text === null) {
        return '';
      }
      return String(text)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
    }

    function cloudSelectionKey(providerName, fileId) {
      return `cloud:${providerName}:${fileId}`;
    }

    function isCloudFileSelected(providerName, fileId) {
      return selectedFiles.has(cloudSelectionKey(providerName, fileId));
    }

    function setCloudStatus(message, isError = false) {
      if (!cloudElements.statusMessage) return;
      cloudElements.statusMessage.textContent = message || '';
      cloudElements.statusMessage.classList.toggle('error', Boolean(isError) && Boolean(message));
    }

    function clearCloudStatus() {
      setCloudStatus('');
    }

    function setCloudUploadStatus(message, isError = false) {
      if (!cloudElements.uploadStatus) return;
      cloudElements.uploadStatus.textContent = message || '';
      cloudElements.uploadStatus.classList.toggle('error', Boolean(isError) && Boolean(message));
    }

    function clearCloudUploadStatus() {
      setCloudUploadStatus('');
    }

    function updateCloudPathDisplay() {
      if (!cloudElements.pathDisplay) return;
      if (!cloudState.currentProvider) {
        cloudElements.pathDisplay.textContent = '';
        return;
      }

      const providerLabel = cloudState.currentProvider.label || cloudState.currentProvider.name;
      if (!cloudState.pathStack.length) {
        cloudElements.pathDisplay.textContent = providerLabel;
        return;
      }

      const parts = cloudState.pathStack.map(entry => entry.name).filter(Boolean);
      cloudElements.pathDisplay.textContent = `${providerLabel} / ${parts.join(' / ')}`;
    }

    function updateCloudNavigationState() {
      if (cloudElements.upButton) {
        const disableUp = cloudState.loading || cloudState.uploading || cloudState.pathStack.length === 0;
        cloudElements.upButton.disabled = disableUp;
      }
      if (cloudElements.uploadButton) {
        const disableUpload = cloudState.loading || cloudState.uploading || !cloudState.currentProvider;
        cloudElements.uploadButton.disabled = disableUpload;
      }
      if (cloudElements.providerSelect) {
        cloudElements.providerSelect.disabled = cloudState.uploading;
      }
    }

    function renderCloudProviders(providers) {
      if (!cloudElements.providerSelect) return;

      cloudElements.providerSelect.innerHTML = '';

      if (!providers || providers.length === 0) {
        const option = document.createElement('option');
        option.value = '';
        option.textContent = 'No providers available';
        option.disabled = true;
        option.selected = true;
        cloudElements.providerSelect.appendChild(option);
        setCloudStatus('No cloud providers configured.', true);
        return;
      }

      providers.forEach((provider, index) => {
        const option = document.createElement('option');
        option.value = provider.name;
        option.textContent = provider.label || provider.name;
        if (index === 0) {
          option.selected = true;
        }
        cloudElements.providerSelect.appendChild(option);
      });

      clearCloudStatus();
    }

    async function loadCloudProviders(forceReload = false) {
      if (!cloudElements.providerSelect) return;

      clearCloudUploadStatus();

      if (!forceReload && cloudState.providers.length) {
        renderCloudProviders(cloudState.providers);
        if (!cloudState.currentProvider && cloudState.providers.length) {
          switchCloudProvider(cloudState.providers[0].name);
        }
        return;
      }

      try {
        setCloudStatus('Loading providers...');
        const response = await fetch('/api/cloud/providers');
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}`);
        }
        const payload = await response.json();
        cloudState.providers = Array.isArray(payload.providers) ? payload.providers : [];
        renderCloudProviders(cloudState.providers);

        if (cloudState.providers.length) {
          switchCloudProvider(cloudState.providers[0].name);
        } else {
          cloudState.currentProvider = null;
          cloudState.currentFiles = [];
          cloudState.pathStack = [];
          if (cloudElements.tableBody) {
            cloudElements.tableBody.innerHTML = '<tr><td colspan="4" class="loading">Connect a cloud provider to browse files.</td></tr>';
          }
        }
      } catch (error) {
        console.error('Failed to load cloud providers:', error);
        setCloudStatus('Unable to load cloud providers.', true);
        if (cloudElements.tableBody) {
          cloudElements.tableBody.innerHTML = '<tr><td colspan="4" class="loading">Error loading providers</td></tr>';
        }
      }
    }

    function switchCloudProvider(providerName) {
      if (!providerName) return;
      const provider = cloudState.providers.find(p => p.name === providerName);
      if (!provider) {
        setCloudStatus('Selected provider is not configured.', true);
        return;
      }

      cloudState.currentProvider = provider;
      cloudState.currentFolder = provider.root || 'root';
      cloudState.currentFiles = [];
      cloudState.pathStack = [];

      if (cloudElements.uploadInput) {
        cloudElements.uploadInput.value = '';
      }
      clearCloudUploadStatus();

      if (cloudElements.providerSelect && cloudElements.providerSelect.value !== provider.name) {
        cloudElements.providerSelect.value = provider.name;
      }

      updateCloudPathDisplay();
      updateCloudNavigationState();
      loadCloudFolder(cloudState.currentFolder, { reset: true });
    }

    function openCloudBrowser() {
      const shareTypeRadio = document.querySelector('input[name="shareType"]:checked');
      if (shareTypeRadio && shareTypeRadio.value === 'dynamic') {
        showDialog('Cloud files are not supported when creating a dynamic share.', 'Cloud Files');
        return;
      }

      clearCloudUploadStatus();
      if (cloudElements.uploadInput) {
        cloudElements.uploadInput.value = '';
        cloudElements.uploadInput.disabled = false;
      }
      cloudState.uploading = false;
      updateCloudNavigationState();

      if (cloudElements.modal) {
        cloudElements.modal.classList.add('show');
      }

      if (cloudElements.tableBody) {
        cloudElements.tableBody.innerHTML = '<tr><td colspan="4" class="loading">Loading cloud files...</td></tr>';
      }

      loadCloudProviders();
    }

    function closeCloudBrowser() {
      if (cloudElements.modal) {
        cloudElements.modal.classList.remove('show');
      }
      clearCloudStatus();
      clearCloudUploadStatus();
    }

    async function loadCloudFolder(folderId, options = {}) {
      if (!cloudState.currentProvider) return;

      const provider = cloudState.currentProvider;
      const targetFolder = folderId || provider.root || 'root';

      if (cloudElements.tableBody) {
        cloudElements.tableBody.innerHTML = '<tr><td colspan="4" class="loading">Loading...</td></tr>';
      }
      setCloudStatus('Loading files...');
      cloudState.loading = true;
      updateCloudNavigationState();

      const previousFolder = cloudState.currentFolder;
      const previousStack = cloudState.pathStack.slice();

      try {
        const params = new URLSearchParams();
        if (targetFolder) {
          params.set('folder', targetFolder);
        }
        const query = params.toString();
        const url = query ? `/api/cloud/${provider.name}/files?${query}` : `/api/cloud/${provider.name}/files`;
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}`);
        }
        const payload = await response.json();
        const files = Array.isArray(payload.files) ? payload.files : [];

        if (options.reset) {
          cloudState.pathStack = [];
        } else if (options.pop) {
          cloudState.pathStack = cloudState.pathStack.slice(0, -1);
        } else if (options.pushEntry) {
          cloudState.pathStack = cloudState.pathStack.concat(options.pushEntry);
        }

        cloudState.currentFolder = targetFolder;
        cloudState.currentFiles = files;

        renderCloudFiles(files);
        clearCloudStatus();
      } catch (error) {
        console.error('Failed to load cloud files:', error);
        cloudState.currentFolder = previousFolder;
        cloudState.pathStack = previousStack;
        setCloudStatus('Failed to load cloud files.', true);
        if (cloudElements.tableBody) {
          cloudElements.tableBody.innerHTML = '<tr><td colspan="4" class="loading">Error loading files</td></tr>';
        }
      } finally {
        cloudState.loading = false;
        updateCloudPathDisplay();
        updateCloudNavigationState();
      }
    }

    function cloudNavigateUp() {
      if (!cloudState.currentProvider || cloudState.pathStack.length === 0 || cloudState.loading) {
        return;
      }

      const parentEntry = cloudState.pathStack.length > 1
        ? cloudState.pathStack[cloudState.pathStack.length - 2]
        : null;
      const parentFolder = parentEntry ? parentEntry.id : (cloudState.currentProvider.root || 'root');
      loadCloudFolder(parentFolder, { pop: true });
    }

    function handleCloudFolderNavigation(file) {
      if (!file || !file.is_dir) return;
      const entry = { id: file.id, name: file.name || 'Folder' };
      loadCloudFolder(file.id, { pushEntry: entry });
    }

    function renderCloudFiles(files) {
      if (!cloudElements.tableBody) return;

      cloudElements.tableBody.innerHTML = '';

      if (!files || files.length === 0) {
        cloudElements.tableBody.innerHTML = '<tr><td colspan="4" class="loading">No items found in this folder.</td></tr>';
        return;
      }

      files.forEach(file => {
        const row = document.createElement('tr');

        const nameCell = document.createElement('td');
        nameCell.className = 'name-col';
        const icon = file.is_dir ? '📁' : '📄';

        if (file.is_dir) {
          const link = document.createElement('a');
          link.href = '#';
          link.className = 'file-link';
          link.innerHTML = `<span class="file-icon">${icon}</span>${escapeHtml(file.name || 'Unnamed')}`;
          link.addEventListener('click', event => {
            event.preventDefault();
            handleCloudFolderNavigation(file);
          });
          nameCell.appendChild(link);
        } else {
          nameCell.innerHTML = `<span class="file-icon">${icon}</span>${escapeHtml(file.name || 'Unnamed')}`;
        }

        const sizeCell = document.createElement('td');
        sizeCell.className = 'size-col';
        if (file.is_dir || typeof file.size !== 'number') {
          sizeCell.textContent = '-';
        } else {
          sizeCell.textContent = formatFileSize(file.size);
        }

        const modifiedCell = document.createElement('td');
        modifiedCell.className = 'modified-col';
        modifiedCell.textContent = file.modified ? file.modified : '-';

        const actionCell = document.createElement('td');
        actionCell.className = 'actions-col';

        if (file.is_dir) {
          const openBtn = document.createElement('button');
          openBtn.className = 'btn';
          openBtn.type = 'button';
          openBtn.textContent = 'Open';
          openBtn.addEventListener('click', () => handleCloudFolderNavigation(file));
          actionCell.appendChild(openBtn);
        } else {
          const key = cloudSelectionKey(cloudState.currentProvider.name, file.id);
          const button = document.createElement('button');
          button.className = isCloudFileSelected(cloudState.currentProvider.name, file.id) ? 'btn' : 'btn primary';
          button.type = 'button';
          button.textContent = isCloudFileSelected(cloudState.currentProvider.name, file.id) ? 'Remove' : 'Select';
          button.addEventListener('click', () => {
            if (isCloudFileSelected(cloudState.currentProvider.name, file.id)) {
              removeCloudSelection(key);
            } else {
              selectCloudFile(file);
            }
          });
          actionCell.appendChild(button);

          if (isCloudFileSelected(cloudState.currentProvider.name, file.id)) {
            row.classList.add('selected');
          }
        }

        row.appendChild(nameCell);
        row.appendChild(sizeCell);
        row.appendChild(modifiedCell);
        row.appendChild(actionCell);

        cloudElements.tableBody.appendChild(row);
      });
    }

    async function handleCloudUpload() {
      if (!cloudState.currentProvider) {
        setCloudUploadStatus('Select a cloud provider before uploading.', true);
        return;
      }

      if (!cloudElements.uploadInput || !cloudElements.uploadInput.files || !cloudElements.uploadInput.files.length) {
        setCloudUploadStatus('Choose a file to upload.', true);
        return;
      }

      const file = cloudElements.uploadInput.files[0];
      const formData = new FormData();
      formData.append('file', file);

      const targetFolder = cloudState.currentFolder || cloudState.currentProvider.root;
      if (targetFolder) {
        formData.append('parent_id', targetFolder);
      }

      cloudState.uploading = true;
      setCloudUploadStatus(`Uploading ${file.name || 'file'}...`);
      updateCloudNavigationState();

      if (cloudElements.uploadInput) {
        cloudElements.uploadInput.disabled = true;
      }

      try {
        const response = await fetch(`/api/cloud/${cloudState.currentProvider.name}/upload`, {
          method: 'POST',
          body: formData
        });
        const payload = await response.json().catch(() => ({}));
        if (!response.ok) {
          const message = payload && payload.error ? payload.error : `Upload failed (HTTP ${response.status})`;
          throw new Error(message);
        }

        const uploadedName = payload && payload.file && payload.file.name ? payload.file.name : (file.name || 'file');
        setCloudUploadStatus(`Uploaded ${uploadedName}.`);

        if (cloudElements.uploadInput) {
          cloudElements.uploadInput.value = '';
        }

        const folderToReload = cloudState.currentFolder;
        await loadCloudFolder(folderToReload, {});
        setCloudStatus(`Uploaded ${uploadedName} to ${cloudState.currentProvider.label || cloudState.currentProvider.name}.`);
      } catch (error) {
        console.error('Cloud upload failed:', error);
        setCloudUploadStatus(error && error.message ? error.message : 'Upload failed.', true);
      } finally {
        cloudState.uploading = false;
        if (cloudElements.uploadInput) {
          cloudElements.uploadInput.disabled = false;
        }
        updateCloudNavigationState();
      }
    }

    function selectCloudFile(file) {
      if (!cloudState.currentProvider || !file || file.is_dir) return;

      const key = cloudSelectionKey(cloudState.currentProvider.name, file.id);
      const metadata = {
        type: 'cloud',
        provider: cloudState.currentProvider.name,
        id: file.id,
        name: file.name,
        is_dir: !!file.is_dir
      };

      addToSelection(key, metadata);
      setCloudStatus(`Added ${file.name || 'Unnamed file'} from ${cloudState.currentProvider.label || cloudState.currentProvider.name}.`);
      renderCloudFiles(cloudState.currentFiles);
    }

    function removeCloudSelection(key) {
      removeFromSelection(key);
      renderCloudFiles(cloudState.currentFiles);
    }

    const openCloudButton = document.getElementById('openCloudBrowser');
    if (openCloudButton) {
      openCloudButton.addEventListener('click', openCloudBrowser);
    }

    if (cloudElements.providerSelect) {
      cloudElements.providerSelect.addEventListener('change', event => {
        switchCloudProvider(event.target.value);
      });
    }

    if (cloudElements.upButton) {
      cloudElements.upButton.addEventListener('click', cloudNavigateUp);
    }

    if (cloudElements.uploadButton) {
      cloudElements.uploadButton.addEventListener('click', handleCloudUpload);
    }

    if (cloudElements.uploadInput) {
      cloudElements.uploadInput.addEventListener('change', () => {
        clearCloudUploadStatus();
      });
    }

    if (cloudElements.modal) {
      cloudElements.modal.addEventListener('click', event => {
        if (event.target === cloudElements.modal) {
          closeCloudBrowser();
        }
      });
    }

    document.addEventListener('keydown', function (event) {
      if (event.key === 'Escape' && cloudElements.modal && cloudElements.modal.classList.contains('show')) {
        closeCloudBrowser();
      }
    });

    function updateSelectedDisplay() {
      elements.selectedCount.textContent = selectedFiles.size;
      elements.generateLink.disabled = selectedFiles.size === 0;

      if (selectedFiles.size === 0) {
        elements.selectedFilesDiv.innerHTML = '<em style="color: #666;">No files or folders selected</em>';
      } else {
        elements.selectedFilesDiv.innerHTML = Array.from(selectedFiles)
          .map(file => {
            const meta = selectedFileMetadata.get(file);
            let icon = '📄';
            let label = '';

            if (meta && meta.type === 'cloud') {
              const providerLabel = meta.provider ? meta.provider.toUpperCase() : 'CLOUD';
              icon = '☁️';
              label = `${providerLabel} · ${meta.name || 'Unnamed'}`;
            } else {
              const fileName = file.split('/').pop();
              const isDir = file.endsWith('/') || (allFiles.find(f => f.name === fileName && f.is_dir));
              icon = isDir ? '📁' : '📄';
              label = fileName;
            }

            const safeKey = file.replace(/'/g, "\\'");
            return `<span class="selected-file" onclick="removeFromSelection('${safeKey}')">${icon} ${escapeHtml(label)} ×</span>`;
          })
          .join('');
      }

      // Update row highlighting
      document.querySelectorAll('#fileTableBody tr').forEach(row => {
        const checkbox = row.querySelector('input[type="checkbox"]');
        if (checkbox) {
          row.classList.toggle('selected', checkbox.checked);
        }
      });

    }

    function addToSelection(filePath, metadata = null) {
      selectedFiles.add(filePath);
      if (metadata) {
        selectedFileMetadata.set(filePath, metadata);
      }
      updateSelectedDisplay();
    }

    function removeFromSelection(filePath) {
      selectedFiles.delete(filePath);
      if (selectedFileMetadata.has(filePath)) {
        selectedFileMetadata.delete(filePath);
      }
      const checkbox = document.querySelector(`input[value="${filePath}"]`);
      if (checkbox) checkbox.checked = false;
      updateSelectedDisplay();
    }

    function clearSelection() {
      selectedFiles.clear();
      selectedFileMetadata.clear();
      document.querySelectorAll('#fileTableBody input[type="checkbox"]').forEach(cb => cb.checked = false);
      updateSelectedDisplay();
    }
    function selectAllVisible() {
      const visibleFiles = document.querySelectorAll('#fileTableBody input[type="checkbox"]');
      visibleFiles.forEach(checkbox => {
        checkbox.checked = true;
        selectedFiles.add(checkbox.value);
      });
      updateSelectedDisplay();
    }

    async function loadDirectory(path = '') {
      try {
        currentPath = path;
        elements.currentPath.textContent = path || 'Root Directory';
        elements.fileTableBody.innerHTML = '<tr><td colspan="5" class="loading">Loading...</td></tr>';

        console.log('Loading directory:', path);

        // Use the API endpoint instead of parsing HTML
        const response = await fetch(`/api/files/${path}`);

        console.log('API response status:', response.status);

        if (response.ok) {
          const data = await response.json();
          console.log('API data:', data);
          allFiles = data.files;
          renderFiles();
        } else {
          const errorText = await response.text();
          console.error('API error:', errorText);
          throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }

      } catch (error) {
        console.error('Error loading directory:', error);
        elements.fileTableBody.innerHTML = '<tr><td colspan="5" style="text-align: center; padding: 20px; color: red;">Error loading files</td></tr>';
      }
    }

    function renderFiles() {
      if (allFiles.length === 0) {
        elements.fileTableBody.innerHTML = '<tr><td colspan="5" class="loading">No files in this directory</td></tr>';
        return;
      }

      elements.fileTableBody.innerHTML = '';

      // Parent directory link
      if (currentPath) {
        const parentPath = currentPath.split('/').filter(p => p).slice(0, -1).join('/');
        const row = document.createElement('tr');
        row.innerHTML = `
          <td></td>
          <td><a href="#" onclick="loadDirectory('${parentPath}')" class="file-link"><span class="file-icon">📁</span>..</a></td>
          <td>-</td>
          <td>-</td>
          <td>-</td>
        `;
        elements.fileTableBody.appendChild(row);
      }

      allFiles.forEach(file => {
        const row = document.createElement('tr');
        const filePath = currentPath ? `${currentPath}/${file.name}` : file.name;
        const isSelected = selectedFiles.has(filePath);


        if (file.is_dir) {
          const newPath = currentPath ? `${currentPath}/${file.name}` : file.name;
          row.innerHTML = `
            <td style="text-align: center;">
              <input type="checkbox" value="${filePath}" ${isSelected ? 'checked' : ''} 
                     onchange="this.checked ? addToSelection('${filePath}') : removeFromSelection('${filePath}')">
            </td>
            <td>
              <div style="display: flex; align-items: center; gap: 8px;">
                <a href="#" onclick="loadDirectory('${newPath}')" class="file-link">
                  <span class="file-icon">📁</span>${file.name}
                </a>
                ${file.is_shared ? '<span class="shared-icon" title="Click to view share details" onclick="showShareDetails(\'' + filePath + '\'); event.stopPropagation();" style="cursor: pointer; color: #0066cc;">🔗</span>' : ''}
              </div>
            </td>
            <td>-</td>
            <td>${file.modified || '-'}</td>
            <td>
              <button class="btn" onclick="loadDirectory('${newPath}')">Open</button>
            </td>
          `;
        } else {
          row.innerHTML = `
            <td style="text-align: center;">
              <input type="checkbox" value="${filePath}" ${isSelected ? 'checked' : ''} 
                     onchange="this.checked ? addToSelection('${filePath}') : removeFromSelection('${filePath}')">
            </td>
            <td>
              <div style="display: flex; align-items: center; gap: 8px;">
                <span class="file-link" style="cursor: pointer;" onclick="previewFile('${filePath}')">
                  <span class="file-icon">${getFileIcon(file.name)}</span>${file.name}
                </span>
                ${file.is_shared ? '<span class="shared-icon" title="Click to view share details" onclick="showShareDetails(\'' + filePath + '\'); event.stopPropagation();" style="cursor: pointer; color: #0066cc;">🔗</span>' : ''}
              </div>
            </td>
            <td>${file.size_str || '-'}</td>
            <td>${file.modified || '-'}</td>
            <td>
              <button class="btn" onclick="previewFile('${filePath}')">Preview</button>
            </td>
          `;
        }

        if (isSelected) row.classList.add('selected');
        elements.fileTableBody.appendChild(row);
      });
    }

    // CSRF Protection: Get XSRF token from cookie
    function getXSRFToken() {
      const match = document.cookie.match(/_xsrf=([^;]*)/);
      return match ? decodeURIComponent(match[1]) : '';
    }

    // Share management functions
    let currentShareData = null;

    async function manageShare(shareId) {
      const modal = document.getElementById('shareManagementModal');
      const body = document.getElementById('shareManagementBody');

      modal.classList.add('show');
      body.innerHTML = '<div class="loading">Loading share details...</div>';

      try {
        // Fetch details for the specific share
        const detailsResponse = await fetch(`/api/share/details_by_id?id=${shareId}`, {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json',
            'X-XSRFToken': getXSRFToken()
          }
        });

        const detailsData = await detailsResponse.json();

        if (detailsData.error) {
          body.innerHTML = `<div style="color: red; text-align: center; padding: 20px;">Error: ${detailsData.error}</div>`;
          return;
        }

        currentShareData = detailsData.share;
        console.log('Share data received:', currentShareData);
        renderShareManagementModal(currentShareData);

      } catch (error) {
        console.error('Error loading share details:', error);
        body.innerHTML = '<div style="color: red; text-align: center; padding: 20px;">Failed to load share details</div>';
      }
    }

    function renderShareManagementModal(share) {
      const body = document.getElementById('shareManagementBody');
      const accessInfo = share.allowed_users ?
        `Restricted (${share.allowed_users.length} user${share.allowed_users.length !== 1 ? 's' : ''})` :
        'Public';

      console.log('Rendering share management modal with data:', {
        share_type: share.share_type,
        secret_token: share.secret_token ? 'present' : 'none',
        allow_list: share.allow_list,
        avoid_list: share.avoid_list
      });

      body.innerHTML = `
          <div class="share-info-section">
            <h3>Share Information</h3>
            <div><strong>Share ID:</strong> <code>${share.id}</code></div>
            <div><strong>Access:</strong> <span class="${share.allowed_users ? 'restricted' : 'public'}">${accessInfo}</span></div>
            <div><strong>Created:</strong> Just now</div>
            <div><strong>URL:</strong> <a href="${share.url}" target="_blank">${window.location.origin}${share.url}</a></div>
            ${share.secret_token ? `
            <div style="margin-top: 15px;">
              <strong>🔐 Secret Token:</strong><br>
              <code style="background: #f0f0f0; padding: 4px 8px; border-radius: 3px; font-family: monospace; font-size: 12px; word-break: break-all; display: inline-block; margin: 5px 0;">${share.secret_token}</code>
              <button class="btn" onclick="copyToClipboard('${share.secret_token}', this)" style="margin-left: 10px; font-size: 11px; padding: 4px 8px;">Copy Token</button>
              <div style="background: #fff3cd; border: 1px solid #ffeaa7; padding: 8px; border-radius: 4px; font-size: 11px; color: #856404; margin-top: 8px;">
                <strong>⚠️ Important:</strong> Users need this token to access the share.
              </div>
            </div>
            ` : ''}
          </div>

          <!-- Share Type Configuration -->
          <div class="share-info-section">
            <h3>Share Type</h3>
            <div style="margin-bottom: 10px;">
              <label style="display: flex; align-items: center; gap: 8px;">
                <input type="radio" name="shareTypeEdit" value="static" ${(share.share_type || 'static') === 'static' ? 'checked' : ''}>
                <span>Static (Snapshot of current files)</span>
                ${(share.share_type || 'static') === 'static' ? '<span style="color: #28a745; font-weight: bold;">← Current</span>' : ''}
              </label>
            </div>
            <div style="margin-bottom: 10px;">
              <label style="display: flex; align-items: center; gap: 8px;">
                <input type="radio" name="shareTypeEdit" value="dynamic" ${share.share_type === 'dynamic' ? 'checked' : ''}>
                <span>Dynamic (Live folder sharing)</span>
                ${share.share_type === 'dynamic' ? '<span style="color: #28a745; font-weight: bold;">← Current</span>' : ''}
              </label>
            </div>
          </div>

          <!-- Token Security -->
          <div class="share-info-section">
            <h3>Security Options</h3>
            <div style="margin-bottom: 10px;">
              <label style="display: flex; align-items: center; gap: 8px;">
                <input type="checkbox" id="disableTokenEdit" ${!share.secret_token ? 'checked' : ''}>
                <span>Disable Secret Token (Public Access)</span>
                ${!share.secret_token ? '<span style="color: #28a745; font-weight: bold;">← Current</span>' : ''}
              </label>
            </div>
            <div style="margin-bottom: 10px;">
              <label style="display: flex; align-items: center; gap: 8px;">
                <input type="checkbox" id="enableTokenEdit" ${share.secret_token ? 'checked' : ''}>
                <span>Enable Secret Token (Secure Access)</span>
                ${share.secret_token ? '<span style="color: #28a745; font-weight: bold;">← Current</span>' : ''}
              </label>
            </div>
          </div>

          <!-- Expiry Date -->
          <div class="share-info-section">
            <h3>Expiry Date</h3>
            <div style="margin-bottom: 10px;">
              <label style="display: block; margin-bottom: 5px; font-size: 12px;">
                <strong>Share Expires On:</strong>
              </label>
              <input type="datetime-local" id="expiryDateEdit" value="${share.expiry_date ? new Date(share.expiry_date).toISOString().slice(0, 16) : ''}"
                     style="width: 100%; padding: 6px; border: 1px solid #ccc; border-radius: 3px; font-family: 'Courier New', monospace; font-size: 12px;">
              <div style="font-size: 11px; color: #666; margin-top: 3px;">
                Leave empty for no expiration. Current: ${share.expiry_date ? `<strong>${new Date(share.expiry_date).toLocaleString()}</strong>` : '<strong>No expiration</strong>'}
              </div>
            </div>
          </div>

          <!-- File Filtering -->
          <div class="share-info-section">
            <h3>File Filtering</h3>
            <div style="margin-bottom: 10px;">
              <label style="display: block; margin-bottom: 5px; font-size: 12px;">
                <strong>Allow List (Glob Patterns):</strong>
              </label>
              <textarea id="allowListEdit" placeholder="*.txt, *.pdf, images/*.jpg, documents/**" 
                        style="width: 100%; padding: 6px; border: 1px solid #ccc; border-radius: 3px; font-family: 'Courier New', monospace; font-size: 12px; height: 60px; resize: vertical;">${(share.allow_list || []).join(', ')}</textarea>
            </div>
            <div style="margin-bottom: 10px;">
              <label style="display: block; margin-bottom: 5px; font-size: 12px;">
                <strong>Avoid List (Glob Patterns):</strong>
              </label>
              <textarea id="avoidListEdit" placeholder="*.tmp, *.log, temp/*, .git/**" 
                        style="width: 100%; padding: 6px; border: 1px solid #ccc; border-radius: 3px; font-family: 'Courier New', monospace; font-size: 12px; height: 60px; resize: vertical;">${(share.avoid_list || []).join(', ')}</textarea>
            </div>
          </div>

          <!-- Access Control -->
          <div class="share-info-section access-list-section">
            <h3>Access Control</h3>
            <div class="access-users-list" id="accessUsersList">
              ${share.allowed_users && share.allowed_users.length > 0 ?
          share.allowed_users.map(user => `
                  <span class="access-user-tag">
                    ${user}
                    <button class="access-user-remove" onclick="removeUserFromShare('${user}')">&times;</button>
                  </span>
                `).join('') :
          '<div style="color: #666; font-style: italic;">No users specified (public access)</div>'
        }
            </div>
            <div class="access-user-input-section">
              <input type="text" class="access-user-input" id="newUserInput" placeholder="Enter username to add">
              <button class="access-user-add" id="addUserBtn" onclick="addUserToShare()">Add User</button>
            </div>
          </div>

          <!-- Files in Share -->
          <div class="share-info-section">
            <h3>Files in Share (${share.paths ? share.paths.length : 0})</h3>
            <div class="share-files-list" id="shareFilesList">
              ${share.paths && share.paths.length > 0 ?
          share.paths.map(path => `
                  <div class="share-file-item">
                    <span>${path}</span>
                    <button class="share-file-remove" onclick="removeFileFromShare('${path}')">Remove</button>
                  </div>
                `).join('') :
          '<div style="padding: 20px; text-align: center; color: #666;">No files in this share</div>'
        }
            </div>
            <div class="share-files-actions">
              <button class="btn" onclick="showAddFilesModal()">Add Files</button>
            </div>
          </div>
        `;

      // Store current share data for updates
      currentShareData = share;

      // Update modal title
      document.querySelector('.share-management-title').textContent = `Manage Share: ${share.id}`;

      // Add event listeners for mutually exclusive checkboxes
      setTimeout(() => {
        const disableTokenCheckbox = document.getElementById('disableTokenEdit');
        const enableTokenCheckbox = document.getElementById('enableTokenEdit');

        if (disableTokenCheckbox && enableTokenCheckbox) {
          disableTokenCheckbox.addEventListener('change', function () {
            if (this.checked) {
              enableTokenCheckbox.checked = false;
            }
          });

          enableTokenCheckbox.addEventListener('change', function () {
            if (this.checked) {
              disableTokenCheckbox.checked = false;
            }
          });
        }
      }, 100);
    }

    async function updateShare() {
      if (!currentShareData) {
        showDialog('No share data available', 'Error');
        return;
      }

      try {
        // Get form values
        const shareType = document.querySelector('input[name="shareTypeEdit"]:checked').value;
        const disableToken = document.getElementById('disableTokenEdit').checked;
        const enableToken = document.getElementById('enableTokenEdit').checked;
        const allowListText = document.getElementById('allowListEdit').value.trim();
        const avoidListText = document.getElementById('avoidListEdit').value.trim();

        // Determine token setting
        // If disableToken is checked, we want to disable the token (set to null)
        // If enableToken is checked, we want to enable the token (generate new token)
        // If neither is checked, we don't change the token setting
        let tokenDisabled = null;
        if (disableToken) {
          tokenDisabled = true;  // Disable token (set to null)
        } else if (enableToken) {
          tokenDisabled = false; // Enable token (generate new token)
        }
        // If neither is checked, tokenDisabled remains null (no change)

        const allowList = allowListText ? allowListText.split(',').map(s => s.trim()).filter(s => s) : [];
        const avoidList = avoidListText ? avoidListText.split(',').map(s => s.trim()).filter(s => s) : [];

        // Get expiry date (store as system time)
        const expiryDateInput = document.getElementById('expiryDateEdit').value;
        const expiryDate = expiryDateInput ? new Date(expiryDateInput).toISOString().replace('Z', '') : null;

        console.log('Updating share with values:', {
          share_id: currentShareData.id,
          share_type: shareType,
          disable_token: tokenDisabled,
          disableToken_checked: disableToken,
          enableToken_checked: enableToken,
          allow_list: allowList,
          avoid_list: avoidList,
          expiry_date: expiryDate
        });

        const response = await fetch('/share/update', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-XSRFToken': getXSRFToken()
          },
          body: JSON.stringify({
            share_id: currentShareData.id,
            share_type: shareType,
            disable_token: tokenDisabled,
            allow_list: allowList,
            avoid_list: avoidList,
            expiry_date: expiryDate
          })
        });

        const data = await response.json();

        if (data.error) {
          showDialog('Error: ' + data.error, 'Error');
        } else {
          let message = 'Share updated successfully!';
          if (data.new_token) {
            message += `\n\nNew secret token: ${data.new_token}\n\nPlease save this token - it won't be shown again!`;
          }
          showDialog(message, 'Success');
          closeShareManagementModal();
          loadActiveShares();
        }
      } catch (error) {
        console.error('Error updating share:', error);
        showDialog('Failed to update share', 'Error');
      }
    }

    function closeShareManagementModal() {
      const modal = document.getElementById('shareManagementModal');
      modal.classList.remove('show');
      currentShareData = null;
    }

    // Add Files Modal Functions
    let addFilesModalData = {
      currentPath: '',
      selectedFiles: new Set(),
      allFiles: []
    };

    function showAddFilesModal() {
      const modal = document.getElementById('addFilesModal');
      modal.classList.add('show');
      addFilesModalData.currentPath = '';
      addFilesModalData.selectedFiles.clear();
      loadFilesForAddModal();
    }

    function closeAddFilesModal() {
      const modal = document.getElementById('addFilesModal');
      modal.classList.remove('show');
      addFilesModalData.selectedFiles.clear();
      updateSelectedFilesPreview();
    }

    async function loadFilesForAddModal() {
      const content = document.getElementById('fileBrowserContent');
      const pathDisplay = document.getElementById('currentBrowsePath');

      content.innerHTML = '<div class="loading">Loading files...</div>';
      pathDisplay.textContent = addFilesModalData.currentPath || 'Root Directory';

      try {
        const apiPath = addFilesModalData.currentPath || '';
        console.log('Loading files for path:', apiPath);
        const response = await fetch(`/api/files/${apiPath}`);

        if (response.ok) {
          const data = await response.json();
          console.log('API response:', data);

          // Transform the API response to include full paths
          addFilesModalData.allFiles = data.files.map(file => ({
            ...file,
            path: addFilesModalData.currentPath ? `${addFilesModalData.currentPath}/${file.name}` : file.name
          }));

          console.log('Transformed files:', addFilesModalData.allFiles);
          renderFilesForAddModal();
        } else {
          const errorText = await response.text();
          console.error('API error:', response.status, errorText);
          content.innerHTML = `<div style="color: red; text-align: center; padding: 20px;">Error loading files: ${response.status}</div>`;
        }
      } catch (error) {
        console.error('Error loading files:', error);
        content.innerHTML = '<div style="color: red; text-align: center; padding: 20px;">Error loading files</div>';
      }
    }

    function renderFilesForAddModal() {
      const content = document.getElementById('fileBrowserContent');
      const files = addFilesModalData.allFiles;

      console.log('Rendering files:', files);

      if (!files || files.length === 0) {
        content.innerHTML = '<div style="text-align: center; padding: 20px; color: #666;">No files in this directory</div>';
        return;
      }

      content.innerHTML = files.map(file => {
        const isSelected = addFilesModalData.selectedFiles.has(file.path);
        const icon = file.is_dir ? '📁' : getFileIcon(file.name);

        console.log('Rendering file:', file.name, 'is_dir:', file.is_dir, 'path:', file.path);

        if (file.is_dir) {
          return `
              <div class="file-browser-item" onclick="navigateToDirectory('${file.path}')">
                <span>${icon} ${file.name}</span>
              </div>
            `;
        } else {
          return `
              <div class="file-browser-item ${isSelected ? 'selected' : ''}" onclick="toggleFileSelection('${file.path}')">
                <input type="checkbox" ${isSelected ? 'checked' : ''} onchange="toggleFileSelection('${file.path}')">
                <span>${icon} ${file.name}</span>
              </div>
            `;
        }
      }).join('');
    }

    function toggleFileSelection(filePath) {
      console.log('Toggling file selection:', filePath);
      if (addFilesModalData.selectedFiles.has(filePath)) {
        addFilesModalData.selectedFiles.delete(filePath);
        console.log('Removed from selection');
      } else {
        addFilesModalData.selectedFiles.add(filePath);
        console.log('Added to selection');
      }
      console.log('Current selection:', Array.from(addFilesModalData.selectedFiles));
      renderFilesForAddModal();
      updateSelectedFilesPreview();
    }

    function updateSelectedFilesPreview() {
      const preview = document.getElementById('selectedFilesPreview');
      const selectedFiles = Array.from(addFilesModalData.selectedFiles);

      if (selectedFiles.length === 0) {
        preview.innerHTML = '<div style="color: #666; font-style: italic;">No files selected</div>';
        return;
      }

      preview.innerHTML = selectedFiles.map(filePath => {
        const fileName = filePath.split('/').pop();
        return `
            <div class="selected-file-item">
              <span>${fileName}</span>
              <button class="remove-btn" onclick="removeFromAddModalSelection('${filePath}')">&times;</button>
            </div>
          `;
      }).join('');
    }

    function removeFromAddModalSelection(filePath) {
      addFilesModalData.selectedFiles.delete(filePath);
      renderFilesForAddModal();
      updateSelectedFilesPreview();
    }

    function navigateUp() {
      if (addFilesModalData.currentPath) {
        const pathParts = addFilesModalData.currentPath.split('/').filter(part => part.length > 0);
        pathParts.pop();
        addFilesModalData.currentPath = pathParts.join('/');
        console.log('Navigating up to:', addFilesModalData.currentPath);
        loadFilesForAddModal();
      }
    }

    function navigateToDirectory(dirPath) {
      console.log('Navigating to directory:', dirPath);
      addFilesModalData.currentPath = dirPath;
      loadFilesForAddModal();
    }

    async function addSelectedFilesToShare() {
      if (!currentShareData || addFilesModalData.selectedFiles.size === 0) {
        showDialog('Please select files to add', 'No Files Selected');
        return;
      }

      const filesToAdd = Array.from(addFilesModalData.selectedFiles);
      const currentPaths = currentShareData.paths || [];
      const newPaths = [...currentPaths, ...filesToAdd];

      try {
        const response = await fetch('/share/update', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-XSRFToken': getXSRFToken()
          },
          body: JSON.stringify({
            share_id: currentShareData.id,
            paths: newPaths
          })
        });

        const data = await response.json();

        if (data.error) {
          showDialog('Error adding files: ' + data.error, 'Error');
        } else {
          showDialog('Files added successfully!', 'Success');
          closeAddFilesModal();
          // Refresh the share management modal
          manageShare(currentShareData.id);
        }
      } catch (error) {
        console.error('Error adding files:', error);
        showDialog('Failed to add files', 'Error');
      }
    }

    async function removeFileFromShare(filePath) {
      if (!currentShareData) return;

      const confirmed = await showDialog(`Remove "${filePath}" from this share?`, 'Confirm Removal', { showCancel: true });
      if (!confirmed) return;

      try {
        const response = await fetch('/share/update', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-XSRFToken': getXSRFToken()
          },
          body: JSON.stringify({
            share_id: currentShareData.id,
            remove_files: [filePath]
          })
        });

        const data = await response.json();

        if (data.error) {
          showDialog('Error removing file: ' + data.error, 'Error');
        } else {
          showDialog('File removed successfully!', 'Success');
          // Refresh the modal
          manageShare(currentShareData.id);
        }
      } catch (error) {
        console.error('Error removing file:', error);
        showDialog('Failed to remove file', 'Error');
      }
    }

    async function addUserToShare() {
      if (!currentShareData) return;

      const input = document.getElementById('newUserInput');
      const username = input.value.trim();

      if (!username) {
        showDialog('Please enter a username', 'Input Required');
        return;
      }

      if (currentShareData.allowed_users && currentShareData.allowed_users.includes(username)) {
        showDialog('User already has access', 'User Exists');
        return;
      }

      try {
        const response = await fetch('/share/update', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-XSRFToken': getXSRFToken()
          },
          body: JSON.stringify({
            share_id: currentShareData.id,
            allowed_users: [...currentShareData.allowed_users, username]
          })
        });

        const data = await response.json();

        if (data.error) {
          showDialog('Error adding user: ' + data.error, 'Error');
        } else {
          showDialog('User added successfully!', 'Success');
          input.value = '';
          // Refresh the modal
          manageShare(currentShareData.id);
        }
      } catch (error) {
        console.error('Error adding user:', error);
        showDialog('Failed to add user', 'Error');
      }
    }

    async function removeUserFromShare(username) {
      if (!currentShareData) return;

      const confirmed = await showDialog(`Remove access for "${username}"?`, 'Confirm Removal', { showCancel: true });
      if (!confirmed) return;

      const currentUsers = currentShareData.allowed_users || [];
      const updatedUsers = currentUsers.filter(u => u !== username);

      try {
        const response = await fetch('/share/update', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-XSRFToken': getXSRFToken()
          },
          body: JSON.stringify({
            share_id: currentShareData.id,
            allowed_users: updatedUsers
          })
        });

        const data = await response.json();

        if (data.error) {
          showDialog('Error removing user: ' + data.error, 'Error');
        } else {
          showDialog('User access removed successfully!', 'Success');
          // Refresh the modal
          manageShare(currentShareData.id);
        }
      } catch (error) {
        console.error('Error removing user:', error);
        showDialog('Failed to remove user', 'Error');
      }
    }

    // Close modal when clicking outside
    document.addEventListener('click', function (event) {
      const modal = document.getElementById('shareManagementModal');
      if (event.target === modal) {
        closeShareManagementModal();
      }
    });

    // Close modal with Escape key
    document.addEventListener('keydown', function (event) {
      if (event.key === 'Escape') {
        closeShareManagementModal();
      }
    });

    // Share access editing functions
    async function editShareAccess(shareId, currentAllowedUsers) {
      const newAllowedUsers = await showDialog('Enter allowed users (comma-separated usernames, empty for public access):', 'Update Access', {
        prompt: true,
        defaultValue: currentAllowedUsers.join(', ') || '',
        showCancel: true
      });

      if (newAllowedUsers === null) {
        return; // User cancelled
      }

      let allowedUsersArray = [];
      if (newAllowedUsers.trim() !== '') {
        allowedUsersArray = newAllowedUsers.split(',').map(user => user.trim()).filter(user => user !== '');
      }

      try {
        const response = await fetch('/share/update', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-XSRFToken': getXSRFToken()
          },
          body: JSON.stringify({
            share_id: shareId,
            allowed_users: allowedUsersArray
          })
        });

        const data = await response.json();

        if (data.error) {
          showDialog('Error updating share access: ' + data.error, 'Error');
        } else {
          showDialog('Share access updated successfully!', 'Success');
          // Reload the active shares list
          loadActiveShares();
        }
      } catch (error) {
        console.error('Error updating share access:', error);
        showDialog('Failed to update share access', 'Error');
      }
    }

    // User management functions
    let searchTimeout = null;

    function toggleUserSelectionPanel() {
      const accessType = document.querySelector('input[name="accessType"]:checked').value;
      const userSelection = document.getElementById('userSelection');

      if (accessType === 'restricted') {
        userSelection.style.display = 'block';
        // Clear previous search and selections
        document.getElementById('userSearchInput').value = '';
        document.getElementById('userList').innerHTML = '<em style="color: #666;">Type to search for users...</em>';
        updateSelectedUsersDisplay();
      } else {
        userSelection.style.display = 'none';
        selectedUsers.clear();
        updateSelectedUsersDisplay();
      }
    }

    function toggleShareTypeInfo() {
      const shareType = document.querySelector('input[name="shareType"]:checked').value;
      const shareTypeInfo = document.getElementById('shareTypeInfo');

      if (shareType === 'static') {
        shareTypeInfo.innerHTML = '<strong>Static Share:</strong> Creates a snapshot of all files at the time of sharing. New files added later won\'t appear in the share.';
        shareTypeInfo.style.background = '#e8f4fd';
        shareTypeInfo.style.color = '#0066cc';
      } else {
        shareTypeInfo.innerHTML = '<strong>Dynamic Share:</strong> Shares the folder in real-time. New files added to the folder will automatically appear in the share.';
        shareTypeInfo.style.background = '#e8f5e8';
        shareTypeInfo.style.color = '#2d5a2d';
      }
    }

    function toggleTokenInfo() {
      const disableToken = document.getElementById('disableToken').checked;
      const tokenInfo = document.getElementById('tokenInfo');

      if (disableToken) {
        tokenInfo.innerHTML = '<strong>🌐 Public Access:</strong> Anyone with the link can access the shared files without entering a token.';
        tokenInfo.style.background = '#fff3cd';
        tokenInfo.style.color = '#856404';
      } else {
        tokenInfo.innerHTML = '<strong>🔐 Token Enabled:</strong> Users will need to enter a secret token to access the shared files.';
        tokenInfo.style.background = '#e8f4fd';
        tokenInfo.style.color = '#0066cc';
      }
    }

    function setupUserSearch() {
      const searchInput = document.getElementById('userSearchInput');
      searchInput.addEventListener('input', function () {
        const query = this.value.trim();

        // Clear previous timeout
        if (searchTimeout) {
          clearTimeout(searchTimeout);
        }

        if (query.length < 1) {
          document.getElementById('userList').innerHTML = '<em style="color: #666;">Type to search for users...</em>';
          return;
        }

        // Debounce search requests
        searchTimeout = setTimeout(() => {
          searchUsers(query);
        }, 300);
      });
    }

    async function searchUsers(query) {
      try {
        const response = await fetch(`/api/users/search?q=${encodeURIComponent(query)}`);
        if (response.ok) {
          const data = await response.json();
          renderUserList(data.users || []);
        } else {
          document.getElementById('userList').innerHTML = '<em style="color: red;">Error searching users</em>';
        }
      } catch (error) {
        console.error('Error searching users:', error);
        document.getElementById('userList').innerHTML = '<em style="color: red;">Error searching users</em>';
      }
    }

    function renderUserList(users) {
      const userList = document.getElementById('userList');

      if (users.length === 0) {
        userList.innerHTML = '<em style="color: #666;">No users found</em>';
        return;
      }

      userList.innerHTML = '';
      users.forEach(user => {
        const userDiv = document.createElement('div');
        userDiv.style.marginBottom = '5px';
        const isSelected = selectedUsers.has(user.username);
        userDiv.innerHTML = `
          <label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
            <input type="checkbox" value="${user.username}" ${isSelected ? 'checked' : ''}
                   onchange="toggleUserSelection('${user.username}')">
            <span>${user.username} ${user.role === 'admin' ? '(Admin)' : ''}</span>
          </label>
        `;
        userList.appendChild(userDiv);
      });
    }

    function toggleUserSelection(username) {
      if (selectedUsers.has(username)) {
        selectedUsers.delete(username);
      } else {
        selectedUsers.add(username);
      }
      updateSelectedUsersDisplay();
    }

    function updateSelectedUsersDisplay() {
      const selectedUsersList = document.getElementById('selectedUsersList');

      if (selectedUsers.size === 0) {
        selectedUsersList.innerHTML = '<em style="color: #999; font-size: 11px;">No users selected</em>';
        return;
      }

      selectedUsersList.innerHTML = Array.from(selectedUsers)
        .map(username => `<span style="display: inline-block; background: #e6f3ff; color: #0066cc; padding: 2px 6px; margin: 2px; border-radius: 3px; font-size: 11px; cursor: pointer;" onclick="removeSelectedUser('${username}')">${username} ×</span>`)
        .join('');
    }

    function removeSelectedUser(username) {
      selectedUsers.delete(username);
      updateSelectedUsersDisplay();

      // Update checkbox in search results if visible
      const checkbox = document.querySelector(`input[value="${username}"]`);
      if (checkbox) {
        checkbox.checked = false;
      }
    }

    async function generateShareLink() {
      if (selectedFiles.size === 0) return;

      elements.generateLink.disabled = true;
      elements.generateLink.textContent = 'Generating...';

      try {
        // Determine access type, share type, allowed users, filter lists, and token settings
        const accessType = document.querySelector('input[name="accessType"]:checked').value;
        const shareType = document.querySelector('input[name="shareType"]:checked').value;
        const allowedUsers = accessType === 'restricted' ? Array.from(selectedUsers) : [];
        const disableToken = document.getElementById('disableToken').checked;

        // Get allow and avoid lists
        const allowListText = document.getElementById('allowList').value.trim();
        const avoidListText = document.getElementById('avoidList').value.trim();
        const allowList = allowListText ? allowListText.split(',').map(s => s.trim()).filter(s => s) : [];
        const avoidList = avoidListText ? avoidListText.split(',').map(s => s.trim()).filter(s => s) : [];

        // Get expiry date (store as system time)
        const expiryDateInput = document.getElementById('expiryDate').value;
        const expiryDate = expiryDateInput ? new Date(expiryDateInput).toISOString().replace('Z', '') : null;

        const pathsPayload = Array.from(selectedFiles).map(item => {
          const meta = selectedFileMetadata.get(item);
          if (meta && meta.type === 'cloud') {
            return {
              type: 'cloud',
              provider: meta.provider,
              id: meta.id,
              name: meta.name,
              is_dir: !!meta.is_dir
            };
          }
          return item;
        });

        const response = await fetch('/share/create', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-XSRFToken': getXSRFToken()
          },
          body: JSON.stringify({
            paths: pathsPayload,
            allowed_users: allowedUsers,
            share_type: shareType,
            allow_list: allowList,
            avoid_list: avoidList,
            disable_token: disableToken,
            expiry_date: expiryDate
          })
        });

        const data = await response.json();

        if (data.error) {
          showDialog('Error: ' + data.error, 'Error');
        } else {
          const fullUrl = `${window.location.origin}${data.url}`;
          const accessInfo = accessType === 'restricted' ?
            `<br><small>Access restricted to: ${allowedUsers.join(', ') || 'No users selected'}</small>` :
            '<br><small>Public access (anyone with link)</small>';
          const shareTypeInfo = shareType === 'dynamic' ?
            '<br><small>🔄 Dynamic share (live folder)</small>' :
            '<br><small>📸 Static share (snapshot)</small>';
          const tokenInfo = disableToken ?
            '<br><small>🌐 Public access (no token required)</small>' :
            '<br><small>🔐 Token required</small>';

          elements.shareResult.style.display = 'block';
          elements.shareResult.innerHTML = `
            <strong>Share link created:</strong><br>
            <a href="${data.url}" target="_blank">${data.url}</a>
            <button class="btn" onclick="copyToClipboard('${fullUrl}', this)" style="margin-left: 10px;">Copy Link</button>
            ${accessInfo}${shareTypeInfo}${tokenInfo}
            <br><br>
            ${disableToken ? '' : `<strong>🔐 Secret Token:</strong><br>
            <code style="background: #f0f0f0; padding: 4px 8px; border-radius: 3px; font-family: monospace; font-size: 12px; word-break: break-all;">${data.secret_token}</code>
            <button class="btn" onclick="copyToClipboard('${data.secret_token}', this)" style="margin-left: 10px;">Copy Token</button>
            <br><br>
            <div style="background: #fff3cd; border: 1px solid #ffeaa7; padding: 10px; border-radius: 4px; font-size: 12px; color: #856404;">
              <strong>⚠️ Important:</strong> Share this secret token with users who need access. They will need to enter this token to view the shared files.
            </div>`}
            ${accessInfo}
          `;

          // Clear selection after successful share creation
          clearSelection();

          // Reload active shares
          loadActiveShares();
        }
      } catch (error) {
        console.error('Error generating share link:', error);
        showDialog('Failed to generate share link', 'Error');
      } finally {
        elements.generateLink.disabled = false;
        elements.generateLink.textContent = 'Generate Share Link';
      }
    }

    async function loadActiveShares() {
      try {
        const response = await fetch('/share/list');
        const data = await response.json();


        // Convert shares object to array
        const sharesArray = data.shares ? Object.keys(data.shares).map(id => ({
          id: id,
          ...data.shares[id],
          count: data.shares[id].paths ? data.shares[id].paths.length : 0
        })) : [];

        elements.activeSharesCount.textContent = sharesArray.length;

        if (sharesArray.length === 0) {
          elements.sharesTableBody.innerHTML = '<tr><td colspan="6" class="loading">No active shares</td></tr>';
          return;
        }

        elements.sharesTableBody.innerHTML = '';
        sharesArray.forEach(share => {
          const row = document.createElement('tr');
          const accessInfo = share.allowed_users ?
            `Restricted (${share.allowed_users.length} user${share.allowed_users.length !== 1 ? 's' : ''})` :
            'Public';

          row.innerHTML = `
            <td><code>${share.id}</code></td>
            <td>${share.count} file${share.count !== 1 ? 's' : ''}</td>
            <td>${accessInfo}</td>
            <td>Just now</td>
            <td>
              <button class="btn" onclick="copyToClipboard('${window.location.origin}/shared/${share.id}', this)">Copy Link</button>
              ${share.secret_token ? `<button class="btn" onclick="copyToClipboard('${share.secret_token}', this)" title="Copy Secret Token">Copy Token</button>` : ''}
              <button class="btn" onclick="openShare('/shared/${share.id}')">Open</button>
              <button class="btn" onclick="manageShare('${share.id}')">Manage</button>
              <button class="btn" onclick="revokeShare('${share.id}')">Revoke</button>
            </td>
          `;
          elements.sharesTableBody.appendChild(row);
        });
      } catch (error) {
        console.error('Error loading active shares:', error);
        elements.sharesTableBody.innerHTML = '<tr><td colspan="6" class="loading">Error loading shares</td></tr>';
      }
    }

    function copyToClipboard(text, btn) {
      // Check if the modern clipboard API is available
      if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(text).then(() => {
          // Visual feedback
          if (btn) {
            const originalText = btn.textContent;
            btn.textContent = 'Copied!';
            setTimeout(() => btn.textContent = originalText, 1500);
          }
        }).catch(err => {
          console.error('Clipboard API failed: ', err);
          // Fall back to the old method
          fallbackCopyTextToClipboard(text, btn);
        });
      } else {
        // Fallback for older browsers or non-HTTPS contexts
        fallbackCopyTextToClipboard(text, btn);
      }
    }

    function fallbackCopyTextToClipboard(text, btn) {
      const textArea = document.createElement('textarea');
      textArea.value = text;
      textArea.style.position = 'fixed';
      textArea.style.top = '-9999px';
      textArea.style.left = '-9999px';
      document.body.appendChild(textArea);
      textArea.focus();
      textArea.select();

      try {
        const successful = document.execCommand('copy');
        if (successful && btn) {
          const originalText = btn.textContent;
          btn.textContent = 'Copied!';
          setTimeout(() => btn.textContent = originalText, 1500);
        } else if (!successful) {
          console.error('Fallback copy command failed');
          showDialog('Failed to copy to clipboard', 'Error');
        }
      } catch (err) {
        console.error('Fallback copy failed: ', err);
        showDialog('Failed to copy to clipboard', 'Error');
      } finally {
        document.body.removeChild(textArea);
      }
    }

    function openShare(url) {
      window.open(url, '_blank');
    }

    async function revokeShare(shareId) {
      const confirmed = await showDialog('Are you sure you want to revoke this share?', 'Confirm Revocation', { showCancel: true });
      if (!confirmed) return;

      try {
        const formData = new URLSearchParams();
        formData.append('id', shareId);
        await fetch('/share/revoke', {
          method: 'POST',
          headers: {
            'X-XSRFToken': getXSRFToken()
          },
          body: formData
        });

        loadActiveShares();
      } catch (error) {
        console.error('Error revoking share:', error);
        showDialog('Failed to revoke share', 'Error');
      }
    }

    function previewFile(filePath) {
      window.open(`/files/${filePath}`, '_blank');
    }

    // Share popup functions
    async function showShareDetails(filePath) {
      const popup = document.getElementById('sharePopup');
      const content = document.getElementById('sharePopupContent');

      // Show popup with loading state
      popup.classList.add('show');
      content.innerHTML = '<div class="loading">Loading share details...</div>';

      try {
        const response = await fetch(`/api/share/details?path=${encodeURIComponent(filePath)}`);
        const data = await response.json();

        if (data.error) {
          content.innerHTML = `<div style="color: red; text-align: center; padding: 20px;">Error: ${data.error}</div>`;
          return;
        }

        if (data.shares.length === 0) {
          content.innerHTML = '<div style="text-align: center; padding: 20px; color: #666;">This file is not currently shared.</div>';
          return;
        }

        // Update popup title with filename
        document.querySelector('.popup-title').textContent = `Share Details - ${filePath.split('/').pop()}`;

        // Render share details
        content.innerHTML = data.shares.map(share => `
          <div class="share-item">
            <div class="share-id">${share.id}</div>
            <div class="share-url">
              <a href="${share.url}" target="_blank">${window.location.origin}${share.url}</a>
            </div>
            <div class="share-access ${share.allowed_users ? 'restricted' : 'public'}">
              ${share.allowed_users ? `Restricted (${share.allowed_users.length} user${share.allowed_users.length !== 1 ? 's' : ''})` : 'Public Access'}
            </div>
            ${share.secret_token ? `
              <div style="margin: 10px 0; padding: 8px; background: #f8f9fa; border-radius: 4px;">
                <strong>🔐 Secret Token:</strong><br>
                <code style="background: #e9ecef; padding: 2px 6px; border-radius: 3px; font-family: monospace; font-size: 11px; word-break: break-all;">${share.secret_token}</code>
                <button class="btn" onclick="copyToClipboard('${share.secret_token}', this)" style="margin-left: 8px; font-size: 10px; padding: 2px 6px;">Copy</button>
              </div>
            ` : ''}
            ${share.allowed_users ? `
              <div class="share-users">
                <div class="share-users-title">Allowed Users:</div>
                ${share.allowed_users.map(username => `<span class="user-tag">${username}</span>`).join('')}
              </div>
            ` : ''}
            <div class="share-actions">
              <button class="btn" onclick="copyToClipboard('${window.location.origin}${share.url}', this)">Copy Link</button>
              <button class="btn" onclick="openShare('${share.url}')">Open Share</button>
              <button class="btn" onclick="revokeShare('${share.id}')">Revoke</button>
            </div>
          </div>
        `).join('');

      } catch (error) {
        console.error('Error loading share details:', error);
        content.innerHTML = '<div style="color: red; text-align: center; padding: 20px;">Failed to load share details</div>';
      }
    }

    function closeSharePopup() {
      const popup = document.getElementById('sharePopup');
      popup.classList.remove('show');
    }

    // Close popup when clicking outside
    document.addEventListener('click', function (event) {
      const popup = document.getElementById('sharePopup');
      if (event.target === popup) {
        closeSharePopup();
      }
    });

    // Close popup with Escape key
    document.addEventListener('keydown', function (event) {
      if (event.key === 'Escape') {
        closeSharePopup();
      }
    });

    function showDialog(message, title = 'Confirm', options = {}) {
      return new Promise((resolve) => {
        document.getElementById('dialogTitle').textContent = title;
        document.getElementById('dialogMessage').textContent = message;

        const confirmBtn = document.getElementById('dialogConfirmBtn');
        const cancelBtn = document.getElementById('dialogCancelBtn');
        const inputContainer = document.getElementById('dialogInputContainer');
        const input = document.getElementById('dialogInput');

        confirmBtn.textContent = options.confirmText || 'OK';
        cancelBtn.style.display = options.showCancel ? 'inline-block' : 'none';
        inputContainer.style.display = options.prompt ? 'block' : 'none';
        input.value = options.prompt ? (options.defaultValue || '') : '';

        document.getElementById('customDialogModal').classList.add('show');

        confirmBtn.onclick = () => {
          document.getElementById('customDialogModal').classList.remove('show');
          resolve(options.prompt ? input.value : true);
        };

        cancelBtn.onclick = () => {
          document.getElementById('customDialogModal').classList.remove('show');
          resolve(options.prompt ? null : false);
        };
      });
    }

    function closeShareModal() {
      const modal = document.getElementById('shareModal');
      modal.classList.remove('show');
    }

    // Event listeners
    elements.generateLink.onclick = generateShareLink;
    elements.clearSelection.onclick = clearSelection;
    elements.selectAllVisible.onclick = selectAllVisible;

    // Initialize
    document.addEventListener('DOMContentLoaded', () => {
      loadDirectory();
      loadActiveShares();
      setupUserSearch();

      // Refresh active shares every 30 seconds
      setInterval(loadActiveShares, 30000);

      // Event listeners for CSP compliance
      document.getElementById('cloudBrowserClose')?.addEventListener('click', closeCloudBrowser);
      document.getElementById('sharePopupClose')?.addEventListener('click', closeSharePopup);
      document.getElementById('shareManagementClose')?.addEventListener('click', closeShareManagementModal);
      document.getElementById('shareManagementCancel')?.addEventListener('click', closeShareManagementModal);
      document.getElementById('updateShareBtn')?.addEventListener('click', updateShare);
      document.getElementById('addFilesClose')?.addEventListener('click', closeAddFilesModal);
      document.getElementById('navigateUpBtn')?.addEventListener('click', navigateUp);
      document.getElementById('addSelectedFilesBtn')?.addEventListener('click', addSelectedFilesToShare);
      document.getElementById('addFilesCancel')?.addEventListener('click', closeAddFilesModal);
    });
  </script>
</body>

</html>