{% extends "base.html" %}
{% set active_page = "logs" %}
{% block page_title %}Auditlog{% endblock %}
{% block page_sub %}
<div class="topbar-sub" id="auditEntryCount">
  {% if has_more %}{{ entries|length }} von {{ total_count }} Einträgen geladen{% else %}{{ entries|length }} Eintrag{{ 'e' if entries|length != 1 else '' }}{% endif %}
</div>
{% endblock %}

{% block content %}
{% import "_audit_log_macros.html" as m %}

{% set ns = namespace(create=0, delete=0, edit=0) %}
{% for e in entries %}
  {% set cat = m.category_of(e['action'].split('.')[-1])|trim %}
  {% if cat == "create" %}{% set ns.create = ns.create + 1 %}
  {% elif cat == "delete" %}{% set ns.delete = ns.delete + 1 %}
  {% else %}{% set ns.edit = ns.edit + 1 %}{% endif %}
{% endfor %}

{% macro fmt_count(loaded, total) %}{% if loaded < total %}{{ loaded }} / {{ total }}{% else %}{{ loaded }}{% endif %}{% endmacro %}

<div class="stat-row" style="margin-bottom:18px;">
  <div class="stat-card" data-category-filter="">
    <div class="stat-label">Alle</div>
    <div class="stat-value" id="statAll">{{ fmt_count(entries|length, total_count) }}</div>
  </div>
  <div class="stat-card" data-category-filter="create">
    <div class="stat-label">Hinzufügen</div>
    <div class="stat-value" id="statCreate" style="color:var(--success);">{{ fmt_count(ns.create, total_create) }}</div>
  </div>
  <div class="stat-card" data-category-filter="edit">
    <div class="stat-label">Änderungen</div>
    <div class="stat-value" id="statEdit" style="color:var(--accent-strong);">{{ fmt_count(ns.edit, total_edit) }}</div>
  </div>
  <div class="stat-card" data-category-filter="delete">
    <div class="stat-label">Löschungen</div>
    <div class="stat-value" id="statDelete" style="color:var(--danger);">{{ fmt_count(ns.delete, total_delete) }}</div>
  </div>
</div>

<div class="table-wrap">
  <div class="table-toolbar">
    <div class="search-input">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
      <input type="text" id="auditSearch" placeholder="Benutzer, Aktion, Ziel oder Details durchsuchen...">
    </div>
  </div>
  <div style="overflow-x:auto;">
  <table class="data-table" id="auditTable" data-sortable>
    <thead><tr>
      <th data-sort-key="ts" style="width:1%; white-space:nowrap;">Zeitpunkt</th>
      <th data-sort-key="user" style="width:1%; white-space:nowrap;">Benutzer</th>
      <th data-sort-key="action" style="width:1%; white-space:nowrap;">Aktion</th>
      <th data-sort-key="target" style="width:1%; white-space:nowrap;">Ziel</th>
      <th>Details</th>
    </tr></thead>
    <tbody>
      {% for e in entries %}{{ m.audit_row(e) }}{% else %}
      <tr class="empty-row"><td colspan="5">Noch keine Änderungen protokolliert.</td></tr>
      {% endfor %}
    </tbody>
  </table>
  </div>
  <p id="auditNoResults" class="text-faint hidden" style="padding:16px; text-align:center; font-size:12.5px;">Keine Einträge für diese Auswahl.</p>
  <div id="auditLoadMoreWrap" class="{{ 'hidden' if not has_more }}" style="padding:16px; text-align:center; display:flex; gap:8px; justify-content:center;">
    <button type="button" id="auditLoadMoreBtn" class="btn btn-primary" data-oldest-id="{{ oldest_loaded_id or '' }}">
      Mehr laden (300)
    </button>
    <button type="button" id="auditLoadAllBtn" class="btn btn-secondary">
      Alle laden
    </button>
  </div>
  </div>

{% endblock %}

{% block scripts %}
<script>
document.addEventListener("DOMContentLoaded", function () {
    const searchInput = document.getElementById("auditSearch");
    const noResults = document.getElementById("auditNoResults");
    let activeCategory = null;

    function applyFilters() {
        const q = (searchInput ? searchInput.value : "").trim().toLowerCase();
        const rows = Array.from(document.querySelectorAll("#auditTable tbody tr"));
        let anyVisible = false;
        rows.forEach(function (row) {
            if (row.classList.contains("empty-row")) return;
            const categoryMatches = !activeCategory || row.dataset.category === activeCategory;
            const textMatches = !q || row.innerText.toLowerCase().includes(q);
            const match = categoryMatches && textMatches;
            row.style.display = match ? "" : "none";
            if (match) anyVisible = true;
        });
        if (noResults) noResults.classList.toggle("hidden", anyVisible);
        document.querySelectorAll(".stat-card[data-category-filter]").forEach(function (card) {
            const isTotal = card.dataset.categoryFilter === "";
            const active = activeCategory === null ? isTotal : card.dataset.categoryFilter === activeCategory;
            card.classList.toggle("active", active);
        });
    }

    if (searchInput) searchInput.addEventListener("input", applyFilters);

    document.querySelectorAll(".stat-card[data-category-filter]").forEach(function (card) {
        card.addEventListener("click", function () {
            const key = this.dataset.categoryFilter;
            activeCategory = (!key || activeCategory === key) ? null : key;
            applyFilters();
        });
    });

    /* ---- Nachladen älterer Einträge (Mehr laden / Alle laden) ---- */
    const totalCount = {{ total_count }};
    const totalCreate = {{ total_create }};
    const totalEdit = {{ total_edit }};
    const totalDelete = {{ total_delete }};
    const entryCountLabel = document.getElementById("auditEntryCount");

    function fmtCount(loaded, total) {
        return loaded < total ? loaded + " / " + total : String(loaded);
    }

    function recomputeStats() {
        const rows = Array.from(document.querySelectorAll("#auditTable tbody tr[data-category]"));
        const counts = { create: 0, edit: 0, delete: 0 };
        rows.forEach(function (r) { counts[r.dataset.category] = (counts[r.dataset.category] || 0) + 1; });
        document.getElementById("statAll").textContent = fmtCount(rows.length, totalCount);
        document.getElementById("statCreate").textContent = fmtCount(counts.create, totalCreate);
        document.getElementById("statEdit").textContent = fmtCount(counts.edit, totalEdit);
        document.getElementById("statDelete").textContent = fmtCount(counts.delete, totalDelete);
        if (entryCountLabel) {
            entryCountLabel.textContent = rows.length < totalCount
                ? rows.length + " von " + totalCount + " Einträgen geladen"
                : rows.length + " Eintrag" + (rows.length === 1 ? "" : "e");
        }
        return rows.length;
    }

    const loadMoreBtn = document.getElementById("auditLoadMoreBtn");
    const loadAllBtn = document.getElementById("auditLoadAllBtn");
    const loadMoreWrap = document.getElementById("auditLoadMoreWrap");
    const tbody = document.querySelector("#auditTable tbody");
    const MORE_URL = "{{ url_for('activity_log_more') }}";

    // Laedt genau einen weiteren 300er-Block nach und haengt ihn an -- von
    // beiden Buttons genutzt: "Mehr laden" ruft das einmal auf, "Alle laden"
    // ruft es wiederholt auf, bis der Server "keine weiteren mehr" meldet.
    function loadMoreOnce() {
        const oldestId = loadMoreBtn.dataset.oldestId;
        if (!oldestId) return Promise.resolve({ hasMore: false });
        return fetch(MORE_URL + "?before_id=" + encodeURIComponent(oldestId))
            .then(function (r) {
                const hasMore = r.headers.get("X-Has-More") === "1";
                const newOldestId = r.headers.get("X-Oldest-Id");
                return r.text().then(function (html) {
                    return { html: html, hasMore: hasMore, newOldestId: newOldestId };
                });
            })
            .then(function (result) {
                const emptyRow = tbody.querySelector(".empty-row");
                if (emptyRow) emptyRow.remove();
                tbody.insertAdjacentHTML("beforeend", result.html);
                if (result.newOldestId) loadMoreBtn.dataset.oldestId = result.newOldestId;
                return result;
            });
    }

    if (loadMoreBtn) {
        loadMoreBtn.addEventListener("click", function () {
            loadMoreBtn.disabled = true;
            if (loadAllBtn) loadAllBtn.disabled = true;
            const originalText = loadMoreBtn.textContent;
            loadMoreBtn.textContent = "Lädt …";
            loadMoreOnce()
                .then(function (result) {
                    if (!result.hasMore) loadMoreWrap.classList.add("hidden");
                    recomputeStats();
                    applyFilters();
                })
                .catch(function () { /* Button unten wird trotzdem wieder aktiviert */ })
                .then(function () {
                    loadMoreBtn.disabled = false;
                    if (loadAllBtn) loadAllBtn.disabled = false;
                    loadMoreBtn.textContent = originalText;
                });
        });
    }

    if (loadAllBtn) {
        loadAllBtn.addEventListener("click", function () {
            loadMoreBtn.disabled = true;
            loadAllBtn.disabled = true;
            const originalText = loadAllBtn.textContent;

            function step() {
                loadAllBtn.textContent = "Lädt … (" + recomputeStats() + " von " + totalCount + ")";
                return loadMoreOnce().then(function (result) {
                    return result.hasMore ? step() : null;
                });
            }

            step()
                .then(function () {
                    loadMoreWrap.classList.add("hidden");
                })
                .catch(function () { /* teilweise geladene Eintraege bleiben stehen */ })
                .then(function () {
                    recomputeStats();
                    applyFilters();
                    loadMoreBtn.disabled = false;
                    loadAllBtn.disabled = false;
                    loadAllBtn.textContent = originalText;
                });
        });
    }

    applyFilters();
    recomputeStats();
});
</script>
{% endblock %}
