---
import Layout from "../../layouts/Layout.astro";
import type { Locale } from "../../i18n/config";

const lang: Locale = "de";

// ─── Interne Bestellverwaltung — NUR für qciga/vanvan (siehe functions/_middleware.js, diese
// Seite bleibt immer hinter dem Zugangscode, auch wenn der Rest der Seite mal öffentlich wird,
// UND zusätzlich schützt dieselbe Middleware die dazugehörige API unter /api/verwaltung/*). ───
//
// Echtes Bestellsystem seit Phase 2 (Cloudflare D1, siehe functions/api/orders.js +
// functions/api/verwaltung/): Diese Seite selbst ist als statische Astro-Seite gebaut (wie die
// ganze restliche Seite), lädt die eigentlichen Bestelldaten aber zur LAUFZEIT per fetch() aus
// der Datenbank (siehe <script> unten) — es gibt hier also KEINE Beispieldaten mehr, sondern
// echte, live einlaufende Bestellungen aus dem Checkout.
//
// 03.08.2026, zweite Ausbaustufe: auf ausdrücklichen Wunsch ("perfektioniere diese Seite aufs
// Maximum") um alles erweitert, was ein echtes kleines Shop-Team im Alltag wirklich braucht und
// vorher fehlte — Suche, Zeitraum-Filter, Sortierung, CSV-Export für die Buchhaltung, direkt
// editierbare Tracking-Nummer, Ein-Klick-Kopieren von E-Mail/Adresse fürs Versandlabel, eine
// echte PDF-Rechnung pro Bestellung (nutzt dieselbe jsPDF-Funktion wie im Kundenkonto), Warnung
// bei offenen Bestellungen, die schon länger liegen, Stammkundinnen-Kennzeichnung, und ein
// dezenter Hinweis, wenn im Hintergrund neue Bestellungen eingetrudelt sind.
---
<Layout
  title="Bestellverwaltung"
  description="Interne Bestellübersicht — nur für qciga und VanVan sichtbar."
  lang={lang}
  path="/verwaltung/"
  noindex={true}
>
  <section class="section-tight">
    <div class="container">
      <p class="todo-note">
        🔒 Interner Bereich, nur für dich und VanVan sichtbar (siehe Zugangscode-Gate) — bleibt
        so, auch wenn der Rest der Seite mal öffentlich wird. Alles unten sind ECHTE
        Bestellungen aus der Datenbank, live vom Checkout befüllt.
      </p>
      <div class="verwaltung-hero">
        <span class="verwaltung-hero-sparkle verwaltung-hero-sparkle-1" aria-hidden="true">✨</span>
        <span class="verwaltung-hero-sparkle verwaltung-hero-sparkle-2" aria-hidden="true">✨</span>
        <span class="eyebrow">Verwaltung</span>
        <h1>📊 Bestellverwaltung</h1>
        <p class="lead">Behalte jederzeit den Überblick: wie viele Bestellungen offen, in Bearbeitung, versendet oder abgeschlossen sind — plus eine Auswertung, was sich am besten verkauft und woher eure Kundschaft kommt.</p>
      </div>
    </div>
  </section>

  <section class="section-tight" id="verwaltung-loading">
    <div class="container">
      <p class="small">⏳ Bestellungen werden geladen …</p>
    </div>
  </section>

  <section class="section-tight" id="verwaltung-error" style="display:none;">
    <div class="container">
      <p class="todo-note" style="border-color: var(--c-sale); color: var(--c-sale);" id="verwaltung-error-text"></p>
      <button type="button" class="btn btn-outline btn-sm" id="verwaltung-retry-btn">🔄 Erneut versuchen</button>
    </div>
  </section>

  <div id="verwaltung-content" style="display:none;">
    <section class="section-tight">
      <div class="container">
        {/* Jede zusammengehörige Gruppe bekommt jetzt ihre eigene, farblich eigenständige "Kiste"
            (siehe .verwaltung-box in global.css) — statt loser Kacheln/Absätze auf der Seite. */}
        <div class="verwaltung-box" style="--box-color: var(--c-accent);">
          <div class="verwaltung-box-head">
            <span class="verwaltung-box-icon" aria-hidden="true">📊</span>
            <h2>Bestellstatus</h2>
          </div>
          <div class="verwaltung-box-body">
            <div class="verwaltung-stat-grid">
              <button type="button" class="card verwaltung-stat-tile" data-filter="offen">
                <span class="verwaltung-stat-icon" aria-hidden="true">🆕</span>
                <span class="verwaltung-stat-value" id="stat-offen">0</span>
                <span class="verwaltung-stat-label">Offen</span>
              </button>
              <button type="button" class="card verwaltung-stat-tile" data-filter="inBearbeitung">
                <span class="verwaltung-stat-icon" aria-hidden="true">⚙️</span>
                <span class="verwaltung-stat-value" id="stat-inBearbeitung">0</span>
                <span class="verwaltung-stat-label">In Bearbeitung</span>
              </button>
              <button type="button" class="card verwaltung-stat-tile" data-filter="versendet">
                <span class="verwaltung-stat-icon" aria-hidden="true">🚚</span>
                <span class="verwaltung-stat-value" id="stat-versendet">0</span>
                <span class="verwaltung-stat-label">Versendet</span>
              </button>
              <button type="button" class="card verwaltung-stat-tile" data-filter="abgeschlossen">
                <span class="verwaltung-stat-icon" aria-hidden="true">✅</span>
                <span class="verwaltung-stat-value" id="stat-abgeschlossen">0</span>
                <span class="verwaltung-stat-label">Abgeschlossen</span>
              </button>
              <div class="card verwaltung-stat-tile verwaltung-stat-tile-highlight">
                <span class="verwaltung-stat-icon" aria-hidden="true">💶</span>
                <span class="verwaltung-stat-value" id="stat-umsatz">–</span>
                <span class="verwaltung-stat-label" id="stat-umsatz-label">Gesamtumsatz</span>
              </div>
            </div>
          </div>
        </div>

        {/* Zweite Kennzahlen-Kiste — Dinge, die im ersten Entwurf fehlten, aber im Alltag sehr
            wichtig sind: wie viel kommt gerade neu rein, und wie hoch ist der durchschnittliche
            Bestellwert (wichtig für Preis-/Werbeentscheidungen). "Heute"/"7 Tage" sind zusätzlich
            anklickbar und setzen direkt den Zeitraum-Filter unten. */}
        <div class="verwaltung-box" style="--box-color: #9b7fd6;">
          <div class="verwaltung-box-head">
            <span class="verwaltung-box-icon" aria-hidden="true">📈</span>
            <h2>Kennzahlen</h2>
          </div>
          <div class="verwaltung-box-body">
            <div class="verwaltung-stat-grid verwaltung-stat-grid-secondary">
              <button type="button" class="card verwaltung-stat-tile verwaltung-stat-tile-mini" data-zeitraum="heute">
                <span class="verwaltung-stat-icon" aria-hidden="true">📅</span>
                <span class="verwaltung-stat-value" id="stat-heute">0</span>
                <span class="verwaltung-stat-label">Bestellungen heute</span>
              </button>
              <button type="button" class="card verwaltung-stat-tile verwaltung-stat-tile-mini" data-zeitraum="7tage">
                <span class="verwaltung-stat-icon" aria-hidden="true">🗓️</span>
                <span class="verwaltung-stat-value" id="stat-7tage">0</span>
                <span class="verwaltung-stat-label">Letzte 7 Tage</span>
              </button>
              <div class="card verwaltung-stat-tile verwaltung-stat-tile-mini">
                <span class="verwaltung-stat-icon" aria-hidden="true">📈</span>
                <span class="verwaltung-stat-value" id="stat-avg">–</span>
                <span class="verwaltung-stat-label">Ø Bestellwert</span>
              </div>
              <div class="card verwaltung-stat-tile verwaltung-stat-tile-mini" id="stat-attention-tile" style="display:none;">
                <span class="verwaltung-stat-icon" aria-hidden="true">⚠️</span>
                <span class="verwaltung-stat-value" id="stat-attention">0</span>
                <span class="verwaltung-stat-label">Brauchen Aufmerksamkeit</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <section class="section-tight">
      <div class="container">
        <div class="verwaltung-box" style="--box-color: var(--c-accent);">
          <div class="verwaltung-box-head">
            <span class="verwaltung-box-icon" aria-hidden="true">📦</span>
            <h2>Alle Bestellungen</h2>
          </div>
          <div class="verwaltung-box-body">
            <div class="verwaltung-new-banner" id="verwaltung-new-banner" style="display:none;">
              <span>🔔 <strong id="verwaltung-new-count"></strong> neue Bestellung(en) seit dem letzten Laden</span>
              <button type="button" class="btn btn-primary btn-sm" id="verwaltung-new-refresh-btn">Jetzt aktualisieren</button>
            </div>

            <div class="verwaltung-toolbar">
              <input type="search" id="verwaltung-search" class="verwaltung-input" placeholder="🔍 Suche nach Bestellnummer, Name oder E-Mail …" />
              <select id="verwaltung-zeitraum" class="verwaltung-input verwaltung-select">
                <option value="alle">Alle Zeiträume</option>
                <option value="heute">Heute</option>
                <option value="7tage">Letzte 7 Tage</option>
                <option value="30tage">Letzte 30 Tage</option>
              </select>
              <select id="verwaltung-sort" class="verwaltung-input verwaltung-select">
                <option value="neu">Neueste zuerst</option>
                <option value="alt">Älteste zuerst</option>
                <option value="wert-ab">Höchster Wert zuerst</option>
                <option value="wert-auf">Niedrigster Wert zuerst</option>
              </select>
              <button type="button" class="btn btn-outline btn-sm" id="verwaltung-csv-btn">📄 CSV-Export</button>
            </div>

            <nav class="verwaltung-filter" aria-label="Nach Status filtern">
              <button type="button" class="verwaltung-filter-btn is-active" data-filter="alle">Alle (<span id="filter-count-alle">0</span>)</button>
              <button type="button" class="verwaltung-filter-btn" data-filter="offen">Offen (<span id="filter-count-offen">0</span>)</button>
              <button type="button" class="verwaltung-filter-btn" data-filter="inBearbeitung">In Bearbeitung (<span id="filter-count-inBearbeitung">0</span>)</button>
              <button type="button" class="verwaltung-filter-btn" data-filter="versendet">Versendet (<span id="filter-count-versendet">0</span>)</button>
              <button type="button" class="verwaltung-filter-btn" data-filter="abgeschlossen">Abgeschlossen (<span id="filter-count-abgeschlossen">0</span>)</button>
              <button type="button" class="verwaltung-filter-btn" data-filter="storniert">Storniert (<span id="filter-count-storniert">0</span>)</button>
            </nav>

            <div class="verwaltung-box-empty" id="verwaltung-empty" style="display:none;">
              <span class="verwaltung-box-empty-icon" aria-hidden="true">📭</span>
              <p>Noch keine Bestellungen eingegangen.</p>
              <p class="small">Sobald die erste Bestellung im Checkout abgeschickt wird, erscheint sie sofort hier.</p>
            </div>
            <p class="small" id="verwaltung-no-match" style="display:none;">Keine Bestellung passt zur aktuellen Suche/Filterung.</p>
            <div class="order-list" id="verwaltung-order-list"></div>
          </div>
        </div>
      </div>
    </section>

    <section class="section-tight" id="verwaltung-auswertung-section">
      <div class="container">
        <div class="verwaltung-box" style="--box-color: #e3b23c;">
          <div class="verwaltung-box-head">
            <span class="verwaltung-box-icon" aria-hidden="true">🏆</span>
            <h2>Bestseller je Kategorie</h2>
          </div>
          <div class="verwaltung-box-body">
            <div class="verwaltung-box-empty" id="verwaltung-kat-empty" style="display:none;">
              <span class="verwaltung-box-empty-icon" aria-hidden="true">🧶</span>
              <p>Noch keine ausgewerteten Verkäufe.</p>
              <p class="small">Hier siehst du bald, welche Produkte je Kategorie am besten laufen (stornierte Bestellungen zählen nicht mit).</p>
            </div>
            <div class="verwaltung-auswertung-grid" id="verwaltung-kat-grid"></div>
          </div>
        </div>
      </div>
    </section>

    <section class="section-tight">
      <div class="container">
        <div class="verwaltung-box" style="--box-color: #6ecb8f;">
          <div class="verwaltung-box-head">
            <span class="verwaltung-box-icon" aria-hidden="true">🌍</span>
            <h2>Herkunft der Bestellungen</h2>
          </div>
          <div class="verwaltung-box-body">
            <div class="verwaltung-box-empty" id="verwaltung-land-empty" style="display:none;">
              <span class="verwaltung-box-empty-icon" aria-hidden="true">🗺️</span>
              <p>Noch keine Bestellungen.</p>
              <p class="small">Sobald Bestellungen eingehen, siehst du hier den Anteil je Land (DE/AT/CH/LU).</p>
            </div>
            <div class="verwaltung-bar-list" id="verwaltung-land-list"></div>
          </div>
        </div>
      </div>
    </section>

    <section class="section-tight">
      <div class="container">
        <div class="verwaltung-box" style="--box-color: var(--c-sale);">
          <div class="verwaltung-box-head">
            <span class="verwaltung-box-icon" aria-hidden="true">👑</span>
            <h2>Stammkundschaft</h2>
          </div>
          <div class="verwaltung-box-body">
            <div class="verwaltung-box-empty" id="verwaltung-kunden-empty" style="display:none;">
              <span class="verwaltung-box-empty-icon" aria-hidden="true">💌</span>
              <p>Noch keine wiederkehrende Kundschaft.</p>
              <p class="small">Sobald jemand zum zweiten Mal bestellt, erscheint sie hier — sortiert nach bisherigem Umsatz.</p>
            </div>
            <div class="verwaltung-bar-list" id="verwaltung-kunden-list"></div>
          </div>
        </div>
      </div>
    </section>
  </div>
</Layout>

<script type="module">
  import { getCategory } from "../../data/categories";
  import { formatPrice } from "../../i18n/format";
  import { rechnungAlsPdfHerunterladen } from "../../scripts/invoice-pdf";

  const lang = "de";
  const STATUS_LABEL = {
    bezahlt: "Bezahlt",
    bearbeitung: "In Bearbeitung",
    versandVorbereitet: "Versand wird vorbereitet",
    versendet: "Versendet",
    abgeschlossen: "Abgeschlossen",
    storniert: "Storniert",
  };
  const LAND_NAME = { de: "Deutschland", at: "Österreich", ch: "Schweiz", lu: "Luxemburg" };
  const LAND_FLAGGE = { de: "🇩🇪", at: "🇦🇹", ch: "🇨🇭", lu: "🇱🇺" };
  const ZAHLUNGSART_LABEL = { paypal: "💙 PayPal", klarna: "🩷 Klarna", kreditkarte: "💳 Kreditkarte", ueberweisung: "🏦 Überweisung" };
  const INVOICE_LABELS = {
    title: "Rechnung", numberLabel: "Rechnungsnummer", dateLabel: "Rechnungsdatum",
    sellerLabel: "Verkäufer", billToLabel: "Rechnungsempfänger",
    itemLabel: "Artikel", qtyLabel: "Menge", unitPriceLabel: "Einzelpreis", sumLabel: "Gesamtbetrag",
    totalLabel: "Gesamt", vatNote: "Gemäß §19 UStG wird keine Umsatzsteuer berechnet und ausgewiesen.",
  };
  // Ab wie vielen Tagen eine noch offene ("bezahlt") Bestellung als "braucht Aufmerksamkeit"
  // markiert wird — soll verhindern, dass mal eine Bestellung vergessen wird.
  const ALTER_SCHWELLE_TAGE = 3;
  const MS_PRO_TAG = 24 * 60 * 60 * 1000;

  function bucket(status) {
    if (status === "storniert") return "storniert";
    if (status === "bezahlt") return "offen";
    if (status === "bearbeitung" || status === "versandVorbereitet") return "inBearbeitung";
    if (status === "versendet") return "versendet";
    return "abgeschlossen";
  }

  const loadingEl = document.getElementById("verwaltung-loading");
  const errorEl = document.getElementById("verwaltung-error");
  const errorTextEl = document.getElementById("verwaltung-error-text");
  const contentEl = document.getElementById("verwaltung-content");
  const searchInput = document.getElementById("verwaltung-search");
  const zeitraumSelect = document.getElementById("verwaltung-zeitraum");
  const sortSelect = document.getElementById("verwaltung-sort");

  let alleBestellungen = [];
  let bekannteIds = new Set();
  let erstesLaden = true;

  async function ladeUndRendere() {
    loadingEl.style.display = "";
    errorEl.style.display = "none";
    document.getElementById("verwaltung-new-banner").style.display = "none";
    try {
      const res = await fetch("/api/verwaltung/orders");
      const data = await res.json().catch(() => null);
      if (!res.ok || !data?.ok) {
        throw new Error(data?.error || `Server antwortete mit Status ${res.status}.`);
      }
      alleBestellungen = data.orders;
      bekannteIds = new Set(alleBestellungen.map((b) => b.id));
      erstesLaden = false;
      render();
      loadingEl.style.display = "none";
      contentEl.style.display = "";
    } catch (err) {
      loadingEl.style.display = "none";
      errorEl.style.display = "";
      errorTextEl.textContent = "⚠️ Bestellungen konnten nicht geladen werden: " + (err instanceof Error ? err.message : String(err));
    }
  }

  // Leiser Hintergrund-Check alle 45s: lädt neu, vergleicht nur die IDs, ERSETZT aber nicht
  // sofort die Ansicht (damit man beim Durchsehen/Filtern nicht unterbrochen wird) — stattdessen
  // erscheint nur ein dezenter Hinweis-Banner mit "Jetzt aktualisieren"-Knopf.
  async function pruefeNeueBestellungenImHintergrund() {
    if (erstesLaden || document.hidden) return;
    try {
      const res = await fetch("/api/verwaltung/orders");
      const data = await res.json().catch(() => null);
      if (!res.ok || !data?.ok) return;
      const neue = data.orders.filter((b) => !bekannteIds.has(b.id));
      if (neue.length > 0) {
        const banner = document.getElementById("verwaltung-new-banner");
        document.getElementById("verwaltung-new-count").textContent = String(neue.length);
        banner.style.display = "flex";
      }
    } catch {
      // Stiller Fehlschlag — der nächste reguläre Refresh/Retry fängt es wieder ein, kein Grund
      // die Ansicht deswegen zu stören.
    }
  }
  setInterval(pruefeNeueBestellungenImHintergrund, 45000);

  function setText(id, text) {
    const el = document.getElementById(id);
    if (el) el.textContent = text;
  }

  function sortiere(liste, modus) {
    const kopie = [...liste];
    switch (modus) {
      case "alt": return kopie.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
      case "wert-ab": return kopie.sort((a, b) => Number(b.summe) - Number(a.summe));
      case "wert-auf": return kopie.sort((a, b) => Number(a.summe) - Number(b.summe));
      default: return kopie.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
    }
  }

  function render() {
    const aktive = alleBestellungen.filter((b) => b.status !== "storniert");

    // ── Buckets für die Stat-Kacheln + Filterleiste ──
    const buckets = { offen: 0, inBearbeitung: 0, versendet: 0, abgeschlossen: 0, storniert: 0 };
    alleBestellungen.forEach((b) => { buckets[bucket(b.status)]++; });
    setText("stat-offen", String(buckets.offen));
    setText("stat-inBearbeitung", String(buckets.inBearbeitung));
    setText("stat-versendet", String(buckets.versendet));
    setText("stat-abgeschlossen", String(buckets.abgeschlossen));
    setText("filter-count-alle", String(alleBestellungen.length));
    setText("filter-count-offen", String(buckets.offen));
    setText("filter-count-inBearbeitung", String(buckets.inBearbeitung));
    setText("filter-count-versendet", String(buckets.versendet));
    setText("filter-count-abgeschlossen", String(buckets.abgeschlossen));
    setText("filter-count-storniert", String(buckets.storniert));

    // ── Umsatz + Ø Bestellwert: stornierte Bestellungen zählen bewusst NICHT mit. ──
    const gesamtumsatz = aktive.reduce((s, b) => s + Number(b.summe), 0);
    setText("stat-umsatz", formatPrice(gesamtumsatz, lang));
    setText("stat-umsatz-label", `Gesamtumsatz (${aktive.length} Bestellung${aktive.length === 1 ? "" : "en"})`);
    setText("stat-avg", aktive.length > 0 ? formatPrice(gesamtumsatz / aktive.length, lang) : "–");

    // ── Heute / letzte 7 Tage + "braucht Aufmerksamkeit" ──
    const jetzt = Date.now();
    const heuteStr = new Date().toLocaleDateString("de-DE");
    const heuteCount = aktive.filter((b) => new Date(b.created_at).toLocaleDateString("de-DE") === heuteStr).length;
    const siebenTageCount = aktive.filter((b) => jetzt - new Date(b.created_at).getTime() <= 7 * MS_PRO_TAG).length;
    setText("stat-heute", String(heuteCount));
    setText("stat-7tage", String(siebenTageCount));

    const attentionIds = new Set(
      aktive.filter((b) => b.status === "bezahlt" && jetzt - new Date(b.created_at).getTime() > ALTER_SCHWELLE_TAGE * MS_PRO_TAG).map((b) => b.id)
    );
    const attentionTile = document.getElementById("stat-attention-tile");
    if (attentionIds.size > 0) {
      setText("stat-attention", String(attentionIds.size));
      attentionTile.style.display = "";
    } else {
      attentionTile.style.display = "none";
    }

    // ── Stammkundinnen: E-Mail kommt in mehr als einer Bestellung vor. ──
    const emailCounts = new Map();
    alleBestellungen.forEach((b) => emailCounts.set(b.kunde_email, (emailCounts.get(b.kunde_email) ?? 0) + 1));

    // ── Bestellliste (sortiert nach aktuell gewähltem Modus) ──
    const listEl = document.getElementById("verwaltung-order-list");
    const emptyEl = document.getElementById("verwaltung-empty");
    if (alleBestellungen.length === 0) {
      listEl.innerHTML = "";
      emptyEl.style.display = "";
    } else {
      emptyEl.style.display = "none";
      const sortiert = sortiere(alleBestellungen, sortSelect.value);
      listEl.innerHTML = sortiert.map((b) => {
        const land = b.land;
        const artikelHtml = b.artikel.map((a) =>
          `<li><span>${a.menge}× ${escapeHtml(a.name)}${a.gratis ? " <span class=\"small\">(gratis)</span>" : ""}</span><span class="order-item-price">${formatPrice(a.preis * a.menge, lang)}</span></li>`
        ).join("");
        const datum = new Date(b.created_at).toLocaleDateString("de-DE", { year: "numeric", month: "2-digit", day: "2-digit" });
        const istNeu = jetzt - new Date(b.created_at).getTime() < MS_PRO_TAG;
        const brauchtAufmerksamkeit = attentionIds.has(b.id);
        const istStammkundin = (emailCounts.get(b.kunde_email) ?? 0) > 1;
        const adresse = [b.strasse, `${b.plz} ${b.ort}`.trim(), LAND_NAME[land] || land].filter(Boolean).join(", ");
        const suchtext = `${b.bestellnummer ?? ""} ${b.kunde_name} ${b.kunde_email}`.toLowerCase();

        return `
          <div class="card order-card order-card-${b.status}${brauchtAufmerksamkeit ? " order-card-attention" : ""}" data-bucket="${bucket(b.status)}" data-order-id="${b.id}" data-created="${b.created_at}" data-search="${escapeHtml(suchtext)}">
            <div class="order-card-head">
              <div>
                <span class="order-no">${LAND_FLAGGE[land] || ""} ${escapeHtml(b.bestellnummer || `#${b.id}`)}</span>
                ${istNeu ? `<span class="verwaltung-chip verwaltung-chip-new">🆕 Neu</span>` : ""}
                ${istStammkundin ? `<span class="verwaltung-chip verwaltung-chip-stamm">🔁 Stammkundin</span>` : ""}
                ${brauchtAufmerksamkeit ? `<span class="verwaltung-chip verwaltung-chip-attention">⚠️ Braucht Aufmerksamkeit</span>` : ""}
                <br />
                <span class="small order-meta">${datum} · ${LAND_NAME[land] || land} · ${escapeHtml(b.kunde_name)} · ${escapeHtml(b.kunde_email)}${b.zahlungsart ? ` · ${ZAHLUNGSART_LABEL[b.zahlungsart] || escapeHtml(b.zahlungsart)}` : ""}</span>
              </div>
              <span class="badge order-status order-status-${b.status}">${STATUS_LABEL[b.status] || b.status}</span>
            </div>
            <ul class="order-items">${artikelHtml}</ul>
            <div class="verwaltung-copy-row">
              <button type="button" class="btn btn-outline btn-xs verwaltung-copy-btn" data-copy="${escapeHtml(b.kunde_email)}">📧 E-Mail kopieren</button>
              <button type="button" class="btn btn-outline btn-xs verwaltung-copy-btn" data-copy="${escapeHtml(`${b.kunde_name}\n${adresse}`)}">📍 Adresse kopieren</button>
              <button type="button" class="btn btn-outline btn-xs verwaltung-pdf-btn" data-order-id="${b.id}">🧾 Rechnung als PDF</button>
              <span class="small verwaltung-copy-hint" data-hint-for="${b.id}" style="display:none;">✅ kopiert</span>
            </div>
            <div class="order-card-foot verwaltung-order-foot">
              <span class="order-total">Summe: <strong>${formatPrice(Number(b.summe), lang)}</strong></span>
              <div class="verwaltung-tracking-edit">
                <input type="text" class="verwaltung-input verwaltung-tracking-input" data-order-id="${b.id}" placeholder="Tracking-Nummer" value="${escapeHtml(b.tracking || "")}" />
                <button type="button" class="btn btn-outline btn-xs verwaltung-tracking-save" data-order-id="${b.id}">💾</button>
              </div>
              <div class="verwaltung-status-edit">
                <select class="verwaltung-status-select" data-order-id="${b.id}">
                  ${Object.entries(STATUS_LABEL).map(([val, label]) => `<option value="${val}" ${val === b.status ? "selected" : ""}>${label}</option>`).join("")}
                </select>
                <span class="small verwaltung-status-saved" data-order-id="${b.id}" style="display:none;">✅ gespeichert</span>
              </div>
            </div>
          </div>
        `;
      }).join("");

      listEl.querySelectorAll(".verwaltung-status-select").forEach((select) => {
        select.addEventListener("change", () => statusAendern(select));
      });
      listEl.querySelectorAll(".verwaltung-copy-btn").forEach((btn) => {
        btn.addEventListener("click", () => kopieren(btn));
      });
      listEl.querySelectorAll(".verwaltung-pdf-btn").forEach((btn) => {
        btn.addEventListener("click", () => rechnungDrucken(btn.dataset.orderId));
      });
      listEl.querySelectorAll(".verwaltung-tracking-save").forEach((btn) => {
        btn.addEventListener("click", () => trackingSpeichern(btn.dataset.orderId));
      });
      listEl.querySelectorAll(".verwaltung-tracking-input").forEach((input) => {
        input.addEventListener("keydown", (e) => { if (e.key === "Enter") trackingSpeichern(input.dataset.orderId); });
      });
    }

    // ── Auswertung: meistverkaufte Produkte je Kategorie (stornierte Bestellungen ausgeschlossen) ──
    const mengeProSlug = new Map(); // slug -> { name, kategorie, menge }
    aktive.forEach((b) => b.artikel.forEach((a) => {
      const eintrag = mengeProSlug.get(a.produkt_slug) ?? { name: a.name, kategorie: a.kategorie_slug, menge: 0 };
      eintrag.menge += a.menge;
      mengeProSlug.set(a.produkt_slug, eintrag);
    }));
    const kategorienMitProdukten = new Map();
    mengeProSlug.forEach((eintrag, slug) => {
      if (!eintrag.kategorie) return;
      const liste = kategorienMitProdukten.get(eintrag.kategorie) ?? [];
      liste.push({ slug, name: eintrag.name, menge: eintrag.menge });
      kategorienMitProdukten.set(eintrag.kategorie, liste);
    });
    const auswertungKategorien = Array.from(kategorienMitProdukten.entries())
      .map(([kategorieSlug, produkte]) => {
        const kat = getCategory(kategorieSlug);
        const sortiert = produkte.sort((a, b) => b.menge - a.menge);
        const maxMenge = sortiert[0]?.menge ?? 1;
        return {
          slug: kategorieSlug,
          name: kat?.name?.[lang] ?? kategorieSlug,
          icon: kat?.icon ?? "📦",
          gesamtMenge: sortiert.reduce((s, p) => s + p.menge, 0),
          produkte: sortiert.slice(0, 4).map((p) => ({ ...p, prozent: Math.round((p.menge / maxMenge) * 100) })),
        };
      })
      .sort((a, b) => b.gesamtMenge - a.gesamtMenge);

    const katGrid = document.getElementById("verwaltung-kat-grid");
    const katEmpty = document.getElementById("verwaltung-kat-empty");
    if (auswertungKategorien.length === 0) {
      katGrid.innerHTML = "";
      katEmpty.style.display = "";
    } else {
      katEmpty.style.display = "none";
      katGrid.innerHTML = auswertungKategorien.map((k) => `
        <div class="card verwaltung-kat-card">
          <h3>${k.icon} ${escapeHtml(k.name)}</h3>
          <div class="verwaltung-bar-list">
            ${k.produkte.map((p) => `
              <div class="verwaltung-bar-row">
                <div class="verwaltung-bar-head"><span>${escapeHtml(p.name)}</span><span class="small">${p.menge}× verkauft</span></div>
                <div class="verwaltung-bar-track"><div class="verwaltung-bar-fill" style="width:${p.prozent}%"></div></div>
              </div>
            `).join("")}
          </div>
        </div>
      `).join("");
    }

    // ── Auswertung: Bestellungen nach Land (stornierte ausgeschlossen) ──
    const landCounts = new Map();
    aktive.forEach((b) => landCounts.set(b.land, (landCounts.get(b.land) ?? 0) + 1));
    const maxLandCount = Math.max(1, ...Array.from(landCounts.values()));
    const auswertungLaender = Array.from(landCounts.entries())
      .sort((a, b) => b[1] - a[1])
      .map(([land, count]) => ({
        land, name: LAND_NAME[land] || land, flagge: LAND_FLAGGE[land] || "",
        count, prozent: aktive.length > 0 ? Math.round((count / aktive.length) * 100) : 0,
        balken: Math.round((count / maxLandCount) * 100),
      }));

    const landList = document.getElementById("verwaltung-land-list");
    const landEmpty = document.getElementById("verwaltung-land-empty");
    if (auswertungLaender.length === 0) {
      landList.innerHTML = "";
      landEmpty.style.display = "";
    } else {
      landEmpty.style.display = "none";
      landList.innerHTML = auswertungLaender.map((l) => `
          <div class="verwaltung-bar-row">
            <div class="verwaltung-bar-head"><span>${l.flagge} ${escapeHtml(l.name)}</span><span class="small">${l.count} Bestellungen · ${l.prozent}%</span></div>
            <div class="verwaltung-bar-track"><div class="verwaltung-bar-fill verwaltung-bar-fill-land" style="width:${l.balken}%"></div></div>
          </div>
        `).join("");
    }

    // ── NEU: Beste Kundinnen (Umsatz pro E-Mail, nur wer mehr als 1× bestellt hat) ──
    const umsatzProKundin = new Map(); // email -> { name, summe, anzahl }
    aktive.forEach((b) => {
      const eintrag = umsatzProKundin.get(b.kunde_email) ?? { name: b.kunde_name, summe: 0, anzahl: 0 };
      eintrag.summe += Number(b.summe);
      eintrag.anzahl += 1;
      umsatzProKundin.set(b.kunde_email, eintrag);
    });
    const besteKunden = Array.from(umsatzProKundin.entries())
      .filter(([, v]) => v.anzahl > 1)
      .map(([email, v]) => ({ email, ...v }))
      .sort((a, b) => b.summe - a.summe)
      .slice(0, 8);
    const maxKundenUmsatz = Math.max(1, ...besteKunden.map((k) => k.summe));
    const kundenEmpty = document.getElementById("verwaltung-kunden-empty");
    const kundenList = document.getElementById("verwaltung-kunden-list");
    if (besteKunden.length === 0) {
      kundenList.innerHTML = "";
      kundenEmpty.style.display = "";
    } else {
      kundenEmpty.style.display = "none";
      kundenList.innerHTML = besteKunden.map((k) => `
        <div class="verwaltung-bar-row">
          <div class="verwaltung-bar-head"><span>👑 ${escapeHtml(k.name)} <span class="small">(${escapeHtml(k.email)})</span></span><span class="small">${formatPrice(k.summe, lang)} · ${k.anzahl}× bestellt</span></div>
          <div class="verwaltung-bar-track"><div class="verwaltung-bar-fill verwaltung-bar-fill-kunden" style="width:${Math.round((k.summe / maxKundenUmsatz) * 100)}%"></div></div>
        </div>
      `).join("");
    }

    wendeFilterAn();
  }

  function escapeHtml(str) {
    return String(str ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c]));
  }

  async function statusAendern(select) {
    const orderId = select.dataset.orderId;
    const neuerStatus = select.value;
    select.disabled = true;
    try {
      const res = await fetch(`/api/verwaltung/orders/${orderId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ status: neuerStatus }),
      });
      const data = await res.json().catch(() => null);
      if (!res.ok || !data?.ok) throw new Error(data?.error || "Speichern fehlgeschlagen.");

      const b = alleBestellungen.find((o) => String(o.id) === String(orderId));
      if (b) b.status = neuerStatus;
      render();

      const savedHint = document.querySelector(`.verwaltung-status-saved[data-order-id="${orderId}"]`);
      if (savedHint) {
        savedHint.style.display = "inline";
        setTimeout(() => { savedHint.style.display = "none"; }, 2000);
      }
    } catch (err) {
      alert("⚠️ Status konnte nicht gespeichert werden: " + (err instanceof Error ? err.message : String(err)));
      select.disabled = false;
    }
  }

  async function trackingSpeichern(orderId) {
    const input = document.querySelector(`.verwaltung-tracking-input[data-order-id="${orderId}"]`);
    const saveBtn = document.querySelector(`.verwaltung-tracking-save[data-order-id="${orderId}"]`);
    if (!input) return;
    saveBtn.disabled = true;
    try {
      const res = await fetch(`/api/verwaltung/orders/${orderId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ tracking: input.value.trim() }),
      });
      const data = await res.json().catch(() => null);
      if (!res.ok || !data?.ok) throw new Error(data?.error || "Speichern fehlgeschlagen.");
      const b = alleBestellungen.find((o) => String(o.id) === String(orderId));
      if (b) b.tracking = input.value.trim();
      saveBtn.textContent = "✅";
      setTimeout(() => { saveBtn.textContent = "💾"; }, 1500);
    } catch (err) {
      alert("⚠️ Tracking-Nummer konnte nicht gespeichert werden: " + (err instanceof Error ? err.message : String(err)));
    } finally {
      saveBtn.disabled = false;
    }
  }

  async function kopieren(btn) {
    const text = btn.dataset.copy;
    try {
      await navigator.clipboard.writeText(text);
      const card = btn.closest(".order-card");
      const hint = card?.querySelector(".verwaltung-copy-hint");
      if (hint) {
        hint.style.display = "inline";
        setTimeout(() => { hint.style.display = "none"; }, 1600);
      }
    } catch {
      alert("Kopieren nicht möglich — bitte manuell markieren:\n\n" + text);
    }
  }

  function rechnungDrucken(orderId) {
    const b = alleBestellungen.find((o) => String(o.id) === String(orderId));
    if (!b) return;
    rechnungAlsPdfHerunterladen({
      nummer: b.bestellnummer || `#${b.id}`,
      datum: new Date(b.created_at).toLocaleDateString("de-DE"),
      artikel: b.artikel.map((a) => ({ name: a.name, menge: a.menge, preis: a.preis })),
      summe: Number(b.summe),
      empfaenger: b.kunde_name,
      lang: "de",
      labels: INVOICE_LABELS,
    });
  }

  // ── Kombinierter Filter: Status-Kachel/Filterleiste + Suche + Zeitraum wirken alle
  //    gleichzeitig (UND-Verknüpft), rein clientseitig über die schon gerenderten Karten. ──
  let aktuellerStatusFilter = "alle";

  function wendeFilterAn() {
    const suchtext = searchInput.value.trim().toLowerCase();
    const zeitraum = zeitraumSelect.value;
    const jetzt = Date.now();
    const zeitraumMs = zeitraum === "heute" ? MS_PRO_TAG : zeitraum === "7tage" ? 7 * MS_PRO_TAG : zeitraum === "30tage" ? 30 * MS_PRO_TAG : null;

    let sichtbar = 0;
    document.querySelectorAll("#verwaltung-order-list .order-card").forEach((card) => {
      const matchStatus = aktuellerStatusFilter === "alle" || card.dataset.bucket === aktuellerStatusFilter;
      const matchSuche = !suchtext || card.dataset.search.includes(suchtext);
      const matchZeitraum = !zeitraumMs || jetzt - new Date(card.dataset.created).getTime() <= zeitraumMs;
      const zeigen = matchStatus && matchSuche && matchZeitraum;
      card.style.display = zeigen ? "" : "none";
      if (zeigen) sichtbar++;
    });

    const hatBestellungen = alleBestellungen.length > 0;
    document.getElementById("verwaltung-no-match").style.display = hatBestellungen && sichtbar === 0 ? "" : "none";
  }

  document.addEventListener("click", (e) => {
    const filterBtn = e.target.closest("[data-filter]");
    if (filterBtn) {
      const f = filterBtn.dataset.filter;
      if (f) {
        aktuellerStatusFilter = f;
        document.querySelectorAll(".verwaltung-filter-btn").forEach((b) => b.classList.toggle("is-active", b.dataset.filter === f));
        wendeFilterAn();
        if (filterBtn.classList.contains("verwaltung-stat-tile")) {
          document.getElementById("verwaltung-order-list")?.scrollIntoView({ behavior: "smooth", block: "start" });
        }
      }
      return;
    }
    const zeitraumBtn = e.target.closest("[data-zeitraum]");
    if (zeitraumBtn) {
      zeitraumSelect.value = zeitraumBtn.dataset.zeitraum;
      wendeFilterAn();
      document.getElementById("verwaltung-order-list")?.scrollIntoView({ behavior: "smooth", block: "start" });
    }
  });

  searchInput.addEventListener("input", wendeFilterAn);
  zeitraumSelect.addEventListener("change", wendeFilterAn);
  sortSelect.addEventListener("change", render);

  document.getElementById("verwaltung-new-refresh-btn")?.addEventListener("click", ladeUndRendere);
  document.getElementById("verwaltung-retry-btn")?.addEventListener("click", ladeUndRendere);

  // ── CSV-Export: exportiert genau die aktuell sichtbare (gefilterte) Liste — für die
  //    Buchhaltung/Steuer, komplett clientseitig, keine Serverkosten. ──
  document.getElementById("verwaltung-csv-btn").addEventListener("click", () => {
    const sichtbareIds = Array.from(document.querySelectorAll("#verwaltung-order-list .order-card"))
      .filter((c) => c.style.display !== "none")
      .map((c) => c.dataset.orderId);
    const bestellungen = alleBestellungen.filter((b) => sichtbareIds.includes(String(b.id)));
    if (bestellungen.length === 0) {
      alert("Keine Bestellungen zum Exportieren (aktuelle Filterung ergibt 0 Treffer).");
      return;
    }
    const kopf = ["Bestellnummer", "Datum", "Status", "Kunde", "E-Mail", "Land", "PLZ", "Ort", "Straße", "Artikel", "Zwischensumme", "Versand", "Rabatt", "Summe", "Zahlungsart", "Tracking"];
    const csvZeile = (werte) => werte.map((w) => `"${String(w ?? "").replace(/"/g, '""')}"`).join(";");
    const zeilen = [csvZeile(kopf)];
    bestellungen.forEach((b) => {
      zeilen.push(csvZeile([
        b.bestellnummer || `#${b.id}`,
        new Date(b.created_at).toLocaleDateString("de-DE"),
        STATUS_LABEL[b.status] || b.status,
        b.kunde_name,
        b.kunde_email,
        LAND_NAME[b.land] || b.land,
        b.plz,
        b.ort,
        b.strasse,
        b.artikel.map((a) => `${a.menge}x ${a.name}`).join(" | "),
        b.zwischensumme,
        b.versandkosten,
        b.rabatt_gesamt,
        b.summe,
        b.zahlungsart,
        b.tracking || "",
      ]));
    });
    const csv = "﻿" + zeilen.join("\r\n"); // BOM voran, damit Excel Umlaute korrekt zeigt
    const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `bestellungen-${new Date().toISOString().slice(0, 10)}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  });

  ladeUndRendere();
</script>
