<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Browse</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 {
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-bottom: 2px solid black;
        padding-bottom: 15px;
        margin-bottom: 20px;
      }

      .header-left {
        display: flex;
        flex-direction: column;
      }

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

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

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

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

      .upload-zone {
        border: 2px dashed #ccc;
        padding: 20px;
        text-align: center;
        margin-bottom: 20px;
        background: #f9f9f9;
      }

      .upload-zone.dragover {
        border-color: black;
        background: #f0f0f0;
      }

      .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;
        position: relative;
      }

      .resizer {
        position: absolute;
        top: 0;
        right: 0;
        width: 5px;
        cursor: col-resize;
        user-select: none;
        height: 100%;
      }

      .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 th,
      .file-table td {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }

      .name-col {
        width: 50%;
      }
      .size-col {
        width: 15%;
      }
      .modified-col {
        width: 20%;
      }
      .actions-col {
        width: 15%;
        text-align: right;
      }

      .size-cell {
        text-align: left;
        font-family: monospace;
        font-size: 12px;
      }
      .actions-cell {
        text-align: right;
      }

      .modified-cell {
        font-family: monospace;
        font-size: 12px;
        color: #666;
      }

      .file-link {
        color: black;
        text-decoration: none;
        display: block;
      }

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

      .file-icon {
        margin-right: 8px;
      }

      .action-link {
        color: black;
        text-decoration: none;
        margin-right: 1px;
        font-size: 11px;
        padding: 2px 6px;
        border: 1px solid #ccc;
        background: #f9f9f9;
      }

      .action-link:hover {
        background: #e9e9e9;
        text-decoration: none;
      }

      .sort-header {
        cursor: pointer;
        user-select: none;
      }

      .sort-header:hover {
        background: #333;
      }

      /* Responsive design */
      @media (max-width: 768px) {
        .file-table thead {
          display: none;
        }

        .file-table,
        .file-table tbody,
        .file-table tr,
        .file-table td {
          display: block;
          width: 100%;
        }

        .file-table tr {
          margin-bottom: 15px;
          border: 1px solid #ddd;
          border-radius: 5px;
          overflow: hidden;
        }

        .file-table td {
          text-align: right;
          padding-left: 50%;
          position: relative;
          border-bottom: 1px solid #eee;
        }

        .file-table td:last-child {
          border-bottom: 0;
        }

        .file-table td::before {
          content: attr(data-label);
          position: absolute;
          left: 10px;
          width: 45%;
          padding-right: 10px;
          white-space: nowrap;
          text-align: left;
          font-weight: bold;
        }

        .name-cell {
          padding-left: 10px !important;
          text-align: left !important;
          font-size: 1.1em;
          font-weight: bold;
          background: #f8f8f8;
        }

        .name-cell::before {
          display: none;
        }

        .actions-cell {
          padding-left: 10px !important;
          text-align: left !important;
        }

        .actions-cell::before {
          display: none;
        }

        .action-link {
          display: inline-block;
          margin: 5px 5px 5px 0;
        }
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="header">
        <div class="header-left">
          <h1>Aird</h1>
          <div class="breadcrumb">
            <a href="/files/">🏠 Home</a>
            {% if current_user and current_path != "/" %} {% set path_parts = current_path.strip('/').split('/') %}
            {% for i, part in enumerate(path_parts) %} 
            {% set partial_path = '/files/' + '/'.join(path_parts[:i+1]) %} /
            <a href="{{ partial_path }}">{{ part }}</a>
            {% end %} {% end %}
          </div>
        </div>
        <div>
        {% if features.get('file_share') %}
        <a href="/share" style="display:inline-block;padding:6px 10px;border:1px solid #000;background:#fff;color:#000;text-decoration:none;font-size:12px;">🔗 Share Files</a>
        {% end %}
        <a href="/logout" style="display:inline-block;padding:6px 10px;border:1px solid #000;background:#fff;color:#000;text-decoration:none;font-size:12px;margin-left:8px;">↩ Logout</a>
        </div>
      </div>

      <!-- Upload Zone -->
      {% if features['file_upload'] %}
      <div class="upload-zone" id="uploadZone">
        <p><strong>📁 Drop files here to upload</strong></p>
        <p>Or click to select files</p>
        <input type="file" id="fileInput" multiple style="display: none" />
      </div>
      <div id="progressContainer" style="display:none;width:100%;"></div>
      {% end %}

      <!-- File Listing Table -->
      <table class="file-table" id="fileTable">
        <thead>
          <tr>
            <th class="name-col sort-header" onclick="sortTable(0)">📁 Name<div class="resizer"></div></th>
            <th class="size-col sort-header" onclick="sortTable(1)">📏 Size<div class="resizer"></div></th>
            <th class="modified-col sort-header" onclick="sortTable(2)">
              🕒 Modified<div class="resizer"></div>
            </th>
            <th class="actions-col">⚡ Actions</th>
          </tr>
        </thead>
        <tbody>
          <!-- Parent Directory Link -->
          {% if current_path and current_path != "/" %}
          <tr>
            <td class="name-cell" data-label="Name">
              <a href="/files/{{ parent_path or '' }}" class="file-link">
                <span class="file-icon">📁</span>..
              </a>
            </td>
            <td class="size-cell" data-label="Size">-</td>
            <td class="modified-cell" data-label="Modified">-</td>
            <td class="actions-cell" data-label="Actions">-</td>
          </tr>
          {% end %}

          <!-- File and Directory Listings -->
          {% for file in files %}
          <tr class="file-row">
            <td class="name-cell" data-label="Name">
              {% if file['is_dir'] %}
              <a
                href="/files/{{ escape(join_path(current_path, file['name'])) }}"
                class="file-link"
              >
                <span class="file-icon">📁</span>{{ escape(file['name']) }}
                {% if file.get('is_shared') %}
                <span class="shared-icon" title="This file is shared">🔗</span>
                {% end %}
              </a>
              {% else %}
              <a
                href="/files/{{ escape(join_path(current_path, file['name'])) }}?start_line=1&end_line=100"
                class="file-link"
              >
                <span class="file-icon">{{ get_file_icon(file["name"]) }}</span>{{
                escape(file['name']) }}
                {% if file.get('is_shared') %}
                <span class="shared-icon" title="This file is shared">🔗</span>
                {% end %}
              </a>
              {% end %}
            </td>
            <td class="size-cell" data-label="Size" data-bytes="{{ file.get('size_bytes', 0) }}">
              {{ file.get('size_str', '-') }}
            </td>
            <td
              class="modified-cell"
              data-label="Modified"
              data-timestamp="{{ file.get('modified_timestamp', 0) }}"
            >
              {{ file.get('modified', '-') }}
            </td>
            <td class="actions-cell" data-label="Actions">
              {% if not file["is_dir"] %}
                {% if features['file_download'] %}
                <a
                  href="/files/{{ escape(join_path(current_path, file['name'])) }}?download=1"
                  class="action-link"
                  >Download</a>
                {% end %}
                {% if features['file_edit'] %}
                <a
                  href="/edit/{{ escape(join_path(current_path, file['name'])) }}"
                  class="action-link"
                  >Edit</a>
                {% end %}
              {% end %}
              {% if features['file_rename'] %}
              <a
                href="#"
                onclick="renameItem('{{ escape(join_path(current_path, file['name'])) }}')"
                class="action-link"
                >Rename</a>
              {% end %}
              {% if features['file_delete'] %}
              <a
                href="#"
                onclick="deleteItem('{{ escape(join_path(current_path, file['name'])) }}')"
                class="action-link"
                >Delete</a>
              {% end %}
            </td>
          </tr>
          {% end %}

          <!-- Empty Directory Message -->
          {% if not files %}
          <tr>
            <td
              colspan="4"
              style="text-align: center; padding: 40px; color: #666"
            >
              📭 This directory is empty
            </td>
          </tr>
          {% end %}
        </tbody>
      </table>

    </div>

    <script>
      // Configurable constants
      const RELOAD_DELAY_MS = 500;
      const MIN_COLUMN_WIDTH = 50;
      const MAX_FILE_SIZE = {{ max_file_size }};

      // File upload functionality
      const uploadZone = document.getElementById("uploadZone");
      const fileInput = document.getElementById("fileInput");
      const progressContainer = document.getElementById("progressContainer");
      let uploadQueue = [];
      let isUploading = false;
      let reloadTimer = null;

      uploadZone.addEventListener("click", () => fileInput.click());
      uploadZone.addEventListener("dragover", (e) => {
        e.preventDefault();
        uploadZone.classList.add("dragover");
      });
      uploadZone.addEventListener("dragleave", () => {
        uploadZone.classList.remove("dragover");
      });
      uploadZone.addEventListener("drop", (e) => {
        e.preventDefault();
        uploadZone.classList.remove("dragover");
        handleFiles(e.dataTransfer.files);
      });

      fileInput.addEventListener("change", (e) => {
        handleFiles(e.target.files);
      });

      function handleFiles(files) {
        if (files.length === 0) return;
        const rejected = [];
        for (const file of files) {
          if (file.size > MAX_FILE_SIZE) {
            rejected.push(file.name);
            continue;
          }

          const item = document.createElement("div");
          item.style.marginTop = "5px";
          const nameEl = document.createElement("div");
          nameEl.textContent = file.name;
          const bar = document.createElement("progress");
          bar.max = 100;
          bar.value = 0;
          bar.style.width = "100%";
          const info = document.createElement("span");
          info.style.display = "block";
          info.style.fontSize = "12px";
          const cancelBtn = document.createElement("button");
          cancelBtn.textContent = "Cancel";
          cancelBtn.style.marginTop = "2px";

          item.appendChild(nameEl);
          item.appendChild(bar);
          item.appendChild(info);
          item.appendChild(cancelBtn);
          progressContainer.appendChild(item);

          const queueItem = { file, bar, info, cancelBtn, item, xhr: null, start: null };

          cancelBtn.addEventListener("click", () => {
            if (queueItem.xhr) {
              queueItem.xhr.abort();
            } else {
              const idx = uploadQueue.indexOf(queueItem);
              if (idx !== -1) {
                uploadQueue.splice(idx, 1);
              }
              progressContainer.removeChild(item);
              if (progressContainer.children.length === 0) {
                progressContainer.style.display = "none";
              }
            }
          });

          uploadQueue.push(queueItem);
        }

        if (rejected.length > 0) {
          const limitGB = (MAX_FILE_SIZE / (1024 * 1024 * 1024)).toFixed(2);
          alert(`Files exceed the ${limitGB} GB limit: ${rejected.join(", ")}`);
        }

        fileInput.value = "";
        clearTimeout(reloadTimer);
        if (!isUploading && uploadQueue.length > 0) {
          isUploading = true;
          progressContainer.style.display = "block";
          processQueue();
        }
      }

      async function processQueue() {
        if (uploadQueue.length === 0) {
          isUploading = false;
          if (progressContainer.children.length === 0) {
            progressContainer.style.display = "none";
          }
          scheduleReload();
          return;
        }

        const current = uploadQueue.shift();
        try {
          await uploadFile(current);
        } catch (err) {
          // error text already set in uploadFile
        }

        processQueue();
      }

      function scheduleReload() {
        clearTimeout(reloadTimer);
        reloadTimer = setTimeout(() => {
          if (uploadQueue.length === 0 && !isUploading) {
            location.reload();
          }
        }, RELOAD_DELAY_MS);
      }

      function formatBytes(bytes) {
        const units = ["B", "KB", "MB", "GB", "TB"];
        let i = 0;
        while (bytes >= 1024 && i < units.length - 1) {
          bytes /= 1024;
          i++;
        }
        return `${bytes.toFixed(1)} ${units[i]}`;
      }

      function uploadFile(item) {
        return new Promise((resolve, reject) => {
          const xhr = new XMLHttpRequest();
          item.xhr = xhr;
          item.start = Date.now();
          xhr.open("POST", "/upload");

          xhr.upload.addEventListener("progress", (e) => {
            if (e.lengthComputable) {
              const percent = (e.loaded / e.total) * 100;
              const elapsed = (Date.now() - item.start) / 1000;
              const speed = e.loaded / (elapsed || 1);
              const remaining = e.total - e.loaded;
              item.bar.value = percent;
              item.info.textContent = `${Math.round(percent)}% - ${formatBytes(e.loaded)} of ${formatBytes(e.total)} (${formatBytes(remaining)} left) @ ${formatBytes(speed)}/s`;
            }
          });

          xhr.addEventListener("load", () => {
            if (xhr.status >= 200 && xhr.status < 300) {
              item.bar.value = 100;
              item.info.textContent = "Completed";
              item.cancelBtn.remove();
              resolve();
            } else {
              item.info.textContent = "Failed";
              item.cancelBtn.remove();
              reject(new Error(xhr.responseText || `Upload of ${item.file.name} failed`));
            }
          });

          xhr.addEventListener("error", () => {
            item.info.textContent = "Error";
            item.cancelBtn.remove();
            reject(new Error(`Upload of ${item.file.name} failed`));
          });

          xhr.addEventListener("abort", () => {
            item.info.textContent = "Cancelled";
            item.cancelBtn.remove();
            reject(new Error(`Upload of ${item.file.name} cancelled`));
          });

          // Stream raw file bytes with headers the backend expects
          xhr.setRequestHeader("X-Upload-Dir", encodeURIComponent('{{ current_path or "" }}'));
          xhr.setRequestHeader("X-Upload-Filename", encodeURIComponent(item.file.name));
          xhr.setRequestHeader("Content-Type", "application/octet-stream");

          xhr.send(item.file);
        });
      }

      // Rename functionality
      function renameItem(filepath) {
        const newName = prompt("Enter new name:");
        if (!newName) return;
        const formData = new URLSearchParams();
        formData.append("path", filepath);
        formData.append("new_name", newName);
        fetch("/rename", {
          method: "POST",
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
          body: formData.toString(),
        })
          .then((res) => {
            if (res.ok) {
              location.reload();
            } else {
              res.text().then((t) => alert("Rename failed: " + t));
            }
          })
          .catch((err) => alert("Rename failed: " + err.message));
      }

      // Delete functionality
      function deleteItem(filepath) {
        if (!confirm("Are you sure you want to delete this item?")) return;
        const formData = new URLSearchParams();
        formData.append("path", filepath);
        fetch("/delete", {
          method: "POST",
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
          },
          body: formData.toString(),
        })
          .then((res) => {
            if (res.ok) {
              location.reload();
            } else {
              res.text().then((t) => alert("Delete failed: " + t));
            }
          })
          .catch((err) => alert("Delete failed: " + err.message));
      }

      function calculateSkipRows(allRows) {
        // Skip parent directory link if present
        if (
          allRows.length > 0 &&
          allRows[0].querySelector(".file-icon") &&
          allRows[0].querySelector(".file-icon").textContent === "📁" &&
          allRows[0].querySelector(".file-link") &&
          allRows[0].querySelector(".file-link").textContent.trim() === ".."
        ) {
          return 1;
        }
        // Skip empty directory message
        if (
          allRows.length > 0 &&
          allRows[0].children.length === 1 &&
          allRows[0].children[0].textContent.includes("This directory is empty")
        ) {
          return 1;
        }
        return 0;
      }

      // Table sorting functionality
      function sortTable(columnIndex) {
        const table = document.getElementById("fileTable");
        const tbody = table.querySelector("tbody");
        const allRows = Array.from(tbody.querySelectorAll("tr"));
        const skipRows = calculateSkipRows(allRows);
        const rows = allRows.slice(skipRows);

        rows.sort((a, b) => {
          let aVal = a.children[columnIndex].textContent.trim();
          let bVal = b.children[columnIndex].textContent.trim();

          if (columnIndex === 1) {
            // Size column
            aVal = parseInt(a.children[columnIndex].dataset.bytes) || -1;
            bVal = parseInt(b.children[columnIndex].dataset.bytes) || -1;
            return bVal - aVal;
          } else if (columnIndex === 2) {
            // Modified column
            aVal = parseInt(a.children[columnIndex].dataset.timestamp) || 0;
            bVal = parseInt(b.children[columnIndex].dataset.timestamp) || 0;
            return bVal - aVal;
          }

          const aIsDir =
            a.children[0].querySelector(".file-icon").textContent === "📁";
          const bIsDir =
            b.children[0].querySelector(".file-icon").textContent === "📁";

          if (aIsDir !== bIsDir) {
            return bIsDir ? 1 : -1;
          }

          return aVal.localeCompare(bVal);
        });

        rows.forEach((row) => tbody.appendChild(row));
      }

      document.addEventListener('DOMContentLoaded', function () {
        const table = document.getElementById('fileTable');
        const resizers = table.querySelectorAll('.resizer');
        let th = null;
        let startX, startWidth;

        resizers.forEach(resizer => {
          resizer.addEventListener('mousedown', function (e) {
            e.preventDefault();
            th = e.target.parentElement;
            startX = e.pageX;
            startWidth = th.offsetWidth;
            
            const headerCells = table.querySelectorAll('th');
            headerCells.forEach(cell => {
                cell.style.width = `${cell.offsetWidth}px`;
            });

            document.addEventListener('mousemove', mouseMove);
            document.addEventListener('mouseup', mouseUp);
          });
        });

        function mouseMove(e) {
          const width = startWidth + (e.pageX - startX);
          if (width > MIN_COLUMN_WIDTH) { // Minimum width
            th.style.width = width + 'px';
          }
        }

        function mouseUp() {
          document.removeEventListener('mousemove', mouseMove);
          document.removeEventListener('mouseup', mouseUp);
        }
      });
    </script>
  </body>
</html>
