<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Application Logs</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    :root {
      --brand: #0d9488;
      --brand-dark: #0f766e;
      --brand-light: #ccfbf1;
    }

    body {
      background: #f8fafc;
      font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
      color: #0f172a;
    }

    .page-wrap {
      max-width: 1000px;
      margin: 0 auto;
      padding: 2rem 1rem 3rem;
    }

    .page-header {
      margin-bottom: 1.5rem;
    }

    .page-title {
      font-size: 1.75rem;
      font-weight: 700;
      margin: 0;
    }

    .page-subtitle {
      color: #64748b;
      margin: 0.35rem 0 0;
    }

    .panel {
      background: #fff;
      border: 1px solid #e2e8f0;
      border-radius: 12px;
      box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
      overflow: hidden;
    }

    .filters {
      padding: 1.25rem;
      display: grid;
      grid-template-columns: 1fr auto;
      gap: 1rem;
      align-items: end;
      border-bottom: 1px solid #e2e8f0;
    }

    .form-label {
      font-size: 0.85rem;
      font-weight: 600;
      color: #334155;
    }

    .btn-brand {
      background: var(--brand);
      border-color: var(--brand);
      color: #fff;
      min-width: 110px;
    }

    .btn-brand:hover,
    .btn-brand:focus {
      background: var(--brand-dark);
      border-color: var(--brand-dark);
      color: #fff;
    }

    .table thead th {
      font-size: 0.75rem;
      letter-spacing: 0.04em;
      text-transform: uppercase;
      color: #64748b;
      border-bottom-color: #e2e8f0;
      background: #f8fafc;
    }

    .table tbody td {
      vertical-align: middle;
      border-bottom-color: #f1f5f9;
    }

    .empty-state {
      text-align: center;
      padding: 3rem 1rem;
      color: #64748b;
    }

    .footer-bar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0.9rem 1.25rem;
      border-top: 1px solid #e2e8f0;
      color: #64748b;
      font-size: 0.9rem;
      gap: 1rem;
      flex-wrap: wrap;
    }

    .alert-inline {
      margin: 1rem 1.25rem 0;
    }

    @media (max-width: 768px) {
      .filters {
        grid-template-columns: 1fr;
      }
    }
  </style>
</head>
<body>
  <div class="page-wrap">
    <div class="page-header">
      <h1 class="page-title">Application Logs</h1>
      <p class="page-subtitle">View or download daily log files. Results load 10 at a time.</p>
    </div>

    <div class="panel">
      <div id="alertBox"></div>

      <div class="filters">
        <div>
          <label for="searchInput" class="form-label">File name</label>
          <input id="searchInput" type="text" class="form-control" placeholder="Search file name...">
        </div>
        <div>
          <button id="searchBtn" class="btn btn-brand w-100">Search</button>
        </div>
      </div>

      <div class="table-responsive">
        <table class="table mb-0">
          <thead>
            <tr>
              <th>File name</th>
              <th>Size</th>
              <th>Last modified</th>
              <th>Action</th>
            </tr>
          </thead>
          <tbody id="logsBody">
            <tr>
              <td colspan="4" class="text-center py-4 text-muted">Loading logs...</td>
            </tr>
          </tbody>
        </table>
      </div>

      <div class="footer-bar">
        <div id="pageInfo">Page —</div>
        <div class="d-flex gap-2">
          <button id="prevBtn" class="btn btn-outline-secondary btn-sm" disabled>Previous</button>
          <button id="nextBtn" class="btn btn-brand btn-sm" disabled>Next</button>
        </div>
      </div>
    </div>
  </div>

  <script>
    const baseUrl = <?= json_encode(base_url()) ?>.replace(/\/$/, '');
    const apiBase = baseUrl + '/logs';

    const searchInput = document.getElementById('searchInput');
    const searchBtn = document.getElementById('searchBtn');
    const logsBody = document.getElementById('logsBody');
    const pageInfo = document.getElementById('pageInfo');
    const prevBtn = document.getElementById('prevBtn');
    const nextBtn = document.getElementById('nextBtn');
    const alertBox = document.getElementById('alertBox');

    let currentSearch = '';
    let pageNumber = 1;
    let totalPages = 0;
    let totalFiles = 0;

    function showAlert(message, type = 'danger') {
      alertBox.innerHTML = `<div class="alert alert-${type} alert-inline mb-0">${escapeHtml(message)}</div>`;
    }

    function clearAlert() {
      alertBox.innerHTML = '';
    }

    function escapeHtml(value) {
      return String(value)
        .replaceAll('&', '&amp;')
        .replaceAll('<', '&lt;')
        .replaceAll('>', '&gt;')
        .replaceAll('"', '&quot;')
        .replaceAll("'", '&#39;');
    }

    function renderEmpty(message) {
      logsBody.innerHTML = `
        <tr>
          <td colspan="4">
            <div class="empty-state">${escapeHtml(message)}</div>
          </td>
        </tr>`;
    }

    function renderLoading() {
      logsBody.innerHTML = `
        <tr>
          <td colspan="4" class="text-center py-4 text-muted">Loading logs...</td>
        </tr>`;
    }

    function renderFiles(files) {
      if (!files.length) {
        renderEmpty('No log files found');
        return;
      }

      logsBody.innerHTML = files.map((file) => {
        const viewUrl = `${apiBase}/view?file=${encodeURIComponent(file.name)}`;
        const downloadUrl = `${apiBase}/download?file=${encodeURIComponent(file.name)}`;

        return `
          <tr>
            <td><code>${escapeHtml(file.name)}</code></td>
            <td>${escapeHtml(file.size_human)}</td>
            <td>${escapeHtml(file.modified || '—')}</td>
            <td>
              <a class="btn btn-sm btn-outline-primary me-1" href="${viewUrl}" target="_blank" rel="noopener">View</a>
              <a class="btn btn-sm btn-brand" href="${downloadUrl}">Download</a>
            </td>
          </tr>`;
      }).join('');
    }

    function updatePagination() {
      if (totalFiles === 0) {
        pageInfo.textContent = 'No results';
      } else {
        pageInfo.textContent = `Page ${pageNumber} of ${totalPages} · ${totalFiles} file${totalFiles === 1 ? '' : 's'}`;
      }

      prevBtn.disabled = pageNumber <= 1;
      nextBtn.disabled = pageNumber >= totalPages || totalPages === 0;
    }

    async function loadLogs(resetPage = true) {
      clearAlert();

      if (resetPage) {
        pageNumber = 1;
      }

      renderLoading();

      const params = new URLSearchParams({
        page: String(pageNumber),
        limit: '10',
      });

      if (currentSearch) {
        params.set('q', currentSearch);
      }

      try {
        const response = await fetch(`${apiBase}/list?${params.toString()}`);
        const data = await response.json();

        if (data.status !== 'success') {
          showAlert(data.message || 'Unable to load logs');
          renderEmpty('Unable to load logs');
          totalPages = 0;
          totalFiles = 0;
          updatePagination();
          return;
        }

        totalPages = data.total_pages || 0;
        totalFiles = data.total || 0;
        pageNumber = data.page || pageNumber;

        renderFiles(data.files || []);
        updatePagination();
      } catch (error) {
        showAlert('Network error while loading logs');
        renderEmpty('Unable to load logs');
        totalPages = 0;
        totalFiles = 0;
        updatePagination();
      }
    }

    function runSearch() {
      currentSearch = searchInput.value.trim();
      loadLogs(true);
    }

    searchBtn.addEventListener('click', runSearch);
    searchInput.addEventListener('keydown', (event) => {
      if (event.key === 'Enter') {
        runSearch();
      }
    });

    prevBtn.addEventListener('click', () => {
      if (pageNumber <= 1) {
        return;
      }
      pageNumber -= 1;
      loadLogs(false);
    });

    nextBtn.addEventListener('click', () => {
      if (pageNumber >= totalPages) {
        return;
      }
      pageNumber += 1;
      loadLogs(false);
    });

    loadLogs(true);
  </script>
</body>
</html>
