<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Firmware Files - FWServe</title>
  <style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body {
      font-family: system-ui, -apple-system, sans-serif;
      background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
      min-height: 100vh; color: #e0e0e0; padding: 20px;
    }
    .container { max-width: 1000px; margin: 0 auto; }
    header { margin-bottom: 30px; }
    h1 { color: #00d4ff; margin-bottom: 5px; }
    .subtitle { color: #888; }
    .back-link { color: #00d4ff; text-decoration: none; }
    .back-link:hover { text-decoration: underline; }

    .panel {
      background: rgba(255,255,255,0.05);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 12px; padding: 25px; margin-bottom: 20px;
    }
    .panel h2 { color: #00d4ff; margin-bottom: 15px; font-size: 1.2rem; }

    .upload-form { display: flex; flex-direction: column; gap: 15px; }
    .form-row { display: flex; gap: 15px; flex-wrap: wrap; }
    .form-group { flex: 1; min-width: 200px; }
    .form-group label { display: block; margin-bottom: 5px; color: #aaa; }
    .form-group input {
      width: 100%; padding: 10px; border-radius: 6px;
      border: 1px solid rgba(255,255,255,0.2); background: rgba(0,0,0,0.3);
      color: #fff; font-size: 14px;
    }
    .form-group input[type="file"] { padding: 8px; }
    .form-group input::placeholder { color: #666; }

    .upload-btn {
      background: #00d4ff; color: #1a1a2e; padding: 12px 30px;
      border: none; border-radius: 6px; font-weight: 600;
      cursor: pointer; font-size: 16px; align-self: flex-start;
    }
    .upload-btn:hover { background: #00b8e6; }
    .upload-btn:disabled { background: #555; cursor: not-allowed; }

    .progress-container { display: none; margin-top: 15px; }
    .progress-bar {
      height: 24px; background: rgba(0,0,0,0.3); border-radius: 12px;
      overflow: hidden; position: relative;
    }
    .progress-fill {
      height: 100%; background: linear-gradient(90deg, #00d4ff, #00ff88);
      width: 0%; transition: width 0.2s;
    }
    .progress-text {
      position: absolute; top: 50%; left: 50%;
      transform: translate(-50%, -50%); font-size: 12px; font-weight: 600;
    }
    .upload-status { margin-top: 10px; font-size: 14px; }
    .status-success { color: #28a745; }
    .status-error { color: #dc3545; }

    .file-table { width: 100%; border-collapse: collapse; }
    .file-table th, .file-table td {
      text-align: left; padding: 12px;
      border-bottom: 1px solid rgba(255,255,255,0.1);
    }
    .file-table th { color: #00d4ff; font-weight: 600; }
    .file-table td { color: #ccc; }
    .file-table code {
      background: rgba(0,212,255,0.1); padding: 2px 6px;
      border-radius: 4px; font-family: monospace; font-size: 12px;
    }
    .file-table a { color: #00d4ff; text-decoration: none; }
    .file-table a:hover { text-decoration: underline; }
    .no-files { color: #888; font-style: italic; }

    .size { white-space: nowrap; }
    .md5 { font-family: monospace; font-size: 11px; color: #888; }
  </style>
</head>
<body>
  <div class="container">
    <header>
      <a href="/" class="back-link">&larr; Back to Home</a>
      <h1>Firmware Files</h1>
      <p class="subtitle">Upload and manage .bin firmware files</p>
    </header>

    <div class="panel">
      <h2>Upload New Firmware</h2>
      <form class="upload-form" id="uploadForm">
        <div class="form-row">
          <div class="form-group">
            <label for="file">Firmware File (.bin)</label>
            <input type="file" id="file" name="file" accept=".bin" required />
          </div>
          <div class="form-group">
            <label for="md5">MD5 Hash (optional)</label>
            <input type="text" id="md5" name="md5"
              placeholder="e.g. d41d8cd98f00b204e9800998ecf8427e"
              pattern="[a-fA-F0-9]{32}" maxlength="32" />
          </div>
        </div>
        <button type="submit" class="upload-btn" id="uploadBtn">Upload</button>
      </form>
      <div class="progress-container" id="progressContainer">
        <div class="progress-bar">
          <div class="progress-fill" id="progressFill"></div>
          <span class="progress-text" id="progressText">0%</span>
        </div>
        <div class="upload-status" id="uploadStatus"></div>
      </div>
    </div>

    <div class="panel">
      <h2>Available Files</h2>
      <div id="fileList"><p class="no-files">Loading...</p></div>
    </div>
  </div>

  <script>
    function formatSize(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];
    }

    async function loadFiles() {
      try {
        const resp = await fetch('/files');
        const data = await resp.json();
        const container = document.getElementById('fileList');

        if (!data.files || data.files.length === 0) {
          container.innerHTML = '<p class="no-files">No files uploaded yet</p>';
          return;
        }

        let html = '<table class="file-table"><tr>';
        html += '<th>Filename</th><th>Size</th><th>MD5 Hash</th></tr>';
        for (const f of data.files) {
          html += '<tr>';
          html += '<td><a href="/files/' + f.name + '">' + f.name + '</a></td>';
          html += '<td class="size">' + formatSize(f.size) + '</td>';
          html += '<td class="md5">' + (f.md5 || '<em>Not provided</em>') + '</td>';
          html += '</tr>';
        }
        html += '</table>';
        container.innerHTML = html;
      } catch (e) {
        document.getElementById('fileList').innerHTML =
          '<p class="no-files">Error loading files</p>';
      }
    }

    document.getElementById('uploadForm').addEventListener('submit', function(e) {
      e.preventDefault();

      const fileInput = document.getElementById('file');
      const md5Input = document.getElementById('md5');
      const btn = document.getElementById('uploadBtn');
      const progress = document.getElementById('progressContainer');
      const fill = document.getElementById('progressFill');
      const text = document.getElementById('progressText');
      const status = document.getElementById('uploadStatus');

      if (!fileInput.files.length) return;

      const formData = new FormData();
      formData.append('file', fileInput.files[0]);
      formData.append('md5', md5Input.value.trim());

      btn.disabled = true;
      progress.style.display = 'block';
      status.textContent = '';
      status.className = 'upload-status';
      fill.style.width = '0%';
      text.textContent = '0%';

      const xhr = new XMLHttpRequest();

      xhr.upload.addEventListener('progress', function(e) {
        if (e.lengthComputable) {
          const pct = Math.round((e.loaded / e.total) * 100);
          fill.style.width = pct + '%';
          text.textContent = pct + '% (' + formatSize(e.loaded) +
            ' / ' + formatSize(e.total) + ')';
        }
      });

      xhr.addEventListener('load', function() {
        btn.disabled = false;
        if (xhr.status === 200) {
          status.textContent = 'Upload complete!';
          status.className = 'upload-status status-success';
          fileInput.value = '';
          md5Input.value = '';
          loadFiles();
        } else {
          let msg = 'Upload failed';
          try {
            const err = JSON.parse(xhr.responseText);
            msg = err.detail || msg;
          } catch (e) {}
          status.textContent = msg;
          status.className = 'upload-status status-error';
        }
      });

      xhr.addEventListener('error', function() {
        btn.disabled = false;
        status.textContent = 'Network error';
        status.className = 'upload-status status-error';
      });

      xhr.open('POST', '/upload');
      xhr.send(formData);
    });

    loadFiles();
  </script>
</body>
</html>
