{# templates/connections.html #}
{% extends 'base.html' %}

{% block title %}Recent Connections{% endblock %}

{% block head_extra %}
  <style>
    /* page-specific styles */
    .table-container { flex: 1; overflow-y: auto; }
    #connectionsTableBody {
      transition: transform 0.5s ease-out;
      transform: translateY(0);
    }
    @keyframes slideIn {
      0% { opacity: 0; transform: scale(0.8); }
      100% { opacity: 1; transform: scale(1); }
    }
    .slide-in { animation: slideIn 0.5s ease-out; }
    @keyframes slideOut {
      0% { opacity: 1; transform: scale(1); }
      100% { opacity: 0; transform: scale(0.1); }
    }
    .slide-out { animation: slideOut 0.5s ease-in forwards; }
  </style>
{% endblock %}

{% block content %}
  <div class="container-fluid">
    <h2>Übersicht deiner gültigen Links</h2>
    <span class="ms-3">
      Anzahl Verbindungen: <strong id="totalConnections">0</strong>
    </span>
    <div class="table-responsive table-container">
      <table class="table table-hover">
        <thead class="table-secondary">
          <tr>
            <th>Timestamp</th>
            <th>Location</th>
            <th>User Agent</th>
            <th>File Path</th>
            <th>File Size</th>
            <th>MIME-Typ</th>
            <th>Cached</th>
          </tr>
        </thead>
        <tbody id="connectionsTableBody">
          {# dynamically populated via Socket.IO #}
        </tbody>
      </table>
    </div>
  </div>
{% endblock %}

{% block scripts %}
  <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
  <script>
    const socket = io();
    socket.on("connect", () => socket.emit("request_initial_data"));

    function updateStats(data) {
      document.getElementById("totalConnections").textContent = data.length;
    }

    function createRow(record, animate=true) {
      const tr = document.createElement("tr");
      tr.dataset.timestamp = record.timestamp;
      if (animate) {
        tr.classList.add("slide-in");
        tr.addEventListener("animationend", () =>
          tr.classList.remove("slide-in"), { once: true });
      }
      tr.innerHTML = `
        <td>${record.timestamp}</td>
        <td>${record.location}</td>
        <td>${record.user_agent}</td>
        <td>${record.full_path}</td>
        <td>${record.filesize}</td>
        <td>${record.mime_typ}</td>
        <td>${record.cached}</td>
      `;
      return tr;
    }

    function updateTable(data) {
      const tbody = document.getElementById("connectionsTableBody");
      const existing = {};
      Array.from(tbody.children).forEach(r => existing[r.dataset.timestamp] = r);

      const frag = document.createDocumentFragment();
      data.forEach(rec => {
        let row = existing[rec.timestamp];
        if (row) {
          row.innerHTML = createRow(rec, false).innerHTML;
          row.classList.remove("slide-out");
        } else {
          row = createRow(rec, true);
        }
        frag.appendChild(row);
      });

      tbody.innerHTML = "";
      tbody.appendChild(frag);
    }

    function animateTableWithNewRow(data) {
      const tbody = document.getElementById("connectionsTableBody");
      const currentTs = new Set([...tbody.children].map(r => r.dataset.timestamp));
      const newRecs = data.filter(r => !currentTs.has(r.timestamp));

      if (newRecs.length) {
        const temp = createRow(newRecs[0], false);
        temp.style.visibility = "hidden";
        tbody.appendChild(temp);
        const h = temp.getBoundingClientRect().height;
        temp.remove();

        tbody.style.transform = `translateY(${h}px)`;
        setTimeout(() => {
          updateTable(data);
          tbody.style.transition = "none";
          tbody.style.transform = "translateY(0)";
          void tbody.offsetWidth;
          tbody.style.transition = "transform 0.5s ease-out";
        }, 500);
      } else {
        updateTable(data);
      }
    }

    socket.on("recent_connections", data => {
      updateStats(data);
      animateTableWithNewRow(data);
    });
  </script>
{% endblock %}
