import { Router } from 'express';

const router = Router();

router.get('/', (req, res) => {
  if (!req.session?.user) {
    const baseRoot = process.env.WEB_BASE_PATH || '/ucp';
    return res.redirect(`${baseRoot}/auth/discord`);
  }

  const guildId = typeof req.query.guildId === 'string' ? req.query.guildId : '';
  const baseRoot = process.env.WEB_BASE_PATH || '/ucp';
  const baseDashboard = `${baseRoot}/dashboard`;
  const baseAuth = `${baseRoot}/auth`;
  const baseApi = `${baseRoot}/api`;
  const baseScript = `
      const BASE_ROOT = '${baseRoot}';
      const BASE_DASH = '${baseDashboard}';
      const BASE_API = '${baseApi}';
      const BASE_AUTH = '${baseAuth}';
      const prependBase = (url) => {
        if (typeof url !== 'string') return url;
        if (BASE_ROOT && url.startsWith(BASE_ROOT + '/')) return url;
        if (url.startsWith('/')) return (BASE_ROOT || '') + url;
        return url;
      };
      const _fetch = window.fetch.bind(window);
      window.fetch = (u, o) => _fetch(prependBase(u), o);
      const gotoDashboard = (guildId) => {
        const qs = guildId ? ('?guildId=' + encodeURIComponent(guildId)) : '';
        window.location.href = (BASE_DASH || '/dashboard') + qs;
      };
  `;

  // TODO: TICKETS: Dashboard-Layout neu aufsetzen.
  //  - Filter/Status/Live-Ansicht statt statischem Inline-HTML.
  //  - Ticketdaten per API/WebSocket laden und live aktualisieren.
  // TODO: MODULE: Musik-Modul als toggelbares Modul mit Status- und Queue-Ansicht einbinden.
  //  - Play/Pause/Skip/Loop als UI-Controls anbieten und Bot-Status spiegeln.
  // TODO: AUTOMOD: Konfiguration (Schwellenwerte, Filter, Logging) im Dashboard editierbar machen.
  //  - Grenzwerte, Whitelist/Badwords und Log-Ziel in ein Formular ueberfuehren.
  const sidebar = `
    <aside class="sidebar">
      <div class="brand">Papo Control</div>
      <div class="nav">
        <a class="active" href="#overview" data-target="overview"><span class="icon">🏠</span> Uebersicht</a>
        <a href="#tickets" data-target="tickets"><span class="icon">🎫</span> Ticketsystem</a>
        <a href="#automod" data-target="automod" class="automod-link"><span class="icon">🛡️</span> Automod</a>
        <a href="#welcome" data-target="welcome" class="welcome-link"><span class="icon">👋</span> Willkommen</a>
        <a href="#dynamicvoice" data-target="dynamicvoice" class="dynamicvoice-link"><span class="icon">🎙️</span> Dynamic Voice</a>
        <a href="#birthday" data-target="birthday" class="birthday-link"><span class="icon">🎂</span> Birthday</a>
        <a href="#reactionroles" data-target="reactionroles" class="reactionroles-link"><span class="icon">🎭</span> Reaction Roles</a>
        <a href="#statuspage" data-target="statuspage" class="statuspage-link"><span class="icon">📡</span> Statuspage</a>
        <a href="#serverstats" data-target="serverstats" class="serverstats-link"><span class="icon">📈</span> Server Stats</a>
        <a href="#settings" data-target="settings"><span class="icon">⚙️</span> Einstellungen</a>
        <a href="#modules" data-target="modules"><span class="icon">🧩</span> Module</a>
        <a href="#events" data-target="events" class="events-link"><span class="icon">📅</span> Events</a>
        <a href="#admin" data-target="admin" class="admin-link hidden"><span class="icon">🛠️</span> Admin</a>
      </div>
<div class="muted">Angemeldet als <span id="userInfo"></span></div>
      <button id="logoutBtn" class="logout">Logout</button>
    </aside>
  `;

  if (!guildId) {
    res.send(`
    <!doctype html>
    <html lang="de">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Papo Dashboard - Auswahl</title>
      <style>
        :root { --bg:#080c15; --card:rgba(18,20,28,0.65); --text:#f8fafc; --accent:#f97316; --accent-strong:#ff9b3d; --muted:#aab4c5; --border:rgba(255,255,255,0.08); }
        body { margin:0; font-family: 'Inter', system-ui, -apple-system, sans-serif; background:radial-gradient(circle at 14% 18%, rgba(249,115,22,0.12), transparent 32%), radial-gradient(circle at 80% -6%, rgba(255,153,73,0.12), transparent 30%), linear-gradient(135deg, #070a11 0%, #0b0f18 50%, #080c15 100%); color:var(--text); min-height:100vh; }
        .layout { display:flex; width:100%; min-height:100vh; background:radial-gradient(circle at 50% 24%, rgba(255,153,73,0.06), transparent 30%); }
        .sidebar { width:240px; background:linear-gradient(180deg, rgba(12,14,22,0.85), rgba(10,12,18,0.78)); border-right:1px solid var(--border); padding:24px 20px; box-sizing:border-box; display:flex; flex-direction:column; gap:18px; backdrop-filter:blur(14px); box-shadow:8px 0 32px rgba(0,0,0,0.45); }
        .brand { font-size:20px; font-weight:800; letter-spacing:0.6px; }
        .nav { display:flex; flex-direction:column; gap:8px; }
        .nav a { display:flex; align-items:center; gap:10px; padding:11px 13px; border-radius:14px; color:var(--muted); text-decoration:none; font-weight:700; transition:background 140ms ease, color 140ms ease, box-shadow 140ms ease, border 140ms ease; border:1px solid transparent; background:rgba(255,255,255,0.02); }
        .nav a .icon { opacity:0.85; width:18px; display:inline-flex; justify-content:center; }
        .nav a.active { background:rgba(249,115,22,0.18); color:var(--accent-strong); border-color:rgba(249,115,22,0.45); box-shadow:0 10px 30px rgba(249,115,22,0.28); }
        .nav a:hover { background:rgba(255,255,255,0.06); color:var(--text); border-color:rgba(255,255,255,0.08); box-shadow:0 8px 22px rgba(0,0,0,0.28); }
        .content { flex:1; padding:24px 32px 48px; box-sizing:border-box; }
        h1 { margin:0; font-size:24px; letter-spacing:0.5px; font-weight:800; }
        .muted { color:var(--muted); font-size:13px; }
        main { display:grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap:16px; margin-top:18px; }
        .card { background:var(--card); border:1px solid var(--border); border-radius:18px; padding:16px 18px; box-shadow:0 18px 36px rgba(0,0,0,0.35); backdrop-filter:blur(12px); cursor:pointer; transition:transform 150ms ease, border-color 150ms ease, box-shadow 150ms ease, background 150ms ease; }
        .card:hover { transform:translateY(-2px); border-color: rgba(249,115,22,0.35); box-shadow:0 22px 40px rgba(0,0,0,0.4); background:rgba(255,255,255,0.05); }
        .row { display:flex; gap:12px; align-items:center; }
        .pill { display:inline-block; padding:6px 10px; border-radius:999px; font-size:12px; background:rgba(249,115,22,0.16); color:var(--text); border:1px solid rgba(249,115,22,0.3); box-shadow:0 8px 18px rgba(249,115,22,0.18); }
        img { width:42px; height:42px; border-radius:12px; object-fit:cover; }
        .logout { margin-top:auto; border:none; color:white; padding:10px 12px; border-radius:12px; cursor:pointer; background:linear-gradient(135deg, #ef4444, #b91c1c); box-shadow:0 12px 28px rgba(239,68,68,0.32); width:100%; transition:transform 120ms ease, box-shadow 120ms ease; }
        .logout:hover { transform:translateY(-1px); box-shadow:0 14px 32px rgba(239,68,68,0.36); }
      </style>
    </head>
    <body>
      <div class="layout">
        ${sidebar}
        <div class="content">
          <h1>Waehle eine Guild aus</h1>
          <div class="muted">Nur Guilds, auf denen der Bot ist.</div>
          <main id="guildGrid"></main>
        </div>
      </div>
      <script>
        ${baseScript}
        async function ensureAuth() {
          const res = await fetch('/api/me');
          if (res.status === 401) { window.location.href = BASE_AUTH + '/discord'; return null; }
          const data = await res.json();
          const userInfo = document.getElementById('userInfo');
          if (userInfo) userInfo.textContent = data.user ? data.user.username + '#' + data.user.discriminator : '';
          if (data.user?.isAdmin) document.querySelector('.nav .admin-link')?.classList.remove('hidden');
          return data;
        }
        async function loadGuilds() {
          const res = await fetch('/api/guilds');
          if (res.status === 401) { window.location.href = BASE_AUTH + '/discord'; return; }
          const data = await res.json();
          const grid = document.getElementById('guildGrid');
          grid.innerHTML = '';
          (data.guilds || []).forEach(g => {
            const card = document.createElement('div'); card.className = 'card';
            card.innerHTML =
              '<div class="row">' +
              '<img src="' + (g.icon ? 'https://cdn.discordapp.com/icons/' + g.id + '/' + g.icon + '.png' : 'https://cdn.discordapp.com/embed/avatars/0.png') + '" alt="icon"/>' +
              '<div><div style="font-weight:700;">' + g.name + '</div><div class="muted">ID: ' + g.id + '</div></div>' +
              '</div>' +
              '<div style="margin-top:10px;" class="pill">Zum Dashboard</div>';
            card.addEventListener('click', () => gotoDashboard(g.id));
            grid.appendChild(card);
          });
          if (!data.guilds?.length) {
            grid.innerHTML = '<div class="muted">Bot ist in keiner Guild. Bitte Bot zu einer Guild einladen.</div>';
          }
        }
        document.getElementById('logoutBtn').addEventListener('click', () => window.location.href = BASE_AUTH + '/logout');
        ensureAuth().then(loadGuilds);
      </script>
    </body>
    </html>
    `);
    return;
  }

  res.send(`
  <!doctype html>
  <html lang="de">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Papo Dashboard</title>
    <style>
      :root { --bg:#080c15; --card:rgba(16,19,28,0.65); --text:#f7fafc; --accent:#f97316; --accent-strong:#ff9b3d; --muted:#a8b2c5; --border:rgba(255,255,255,0.08); --surface:rgba(12,15,22,0.75); }
      body { margin:0; font-family: 'Inter', system-ui, -apple-system, sans-serif; background:radial-gradient(circle at 12% 18%, rgba(249,115,22,0.12), transparent 32%), radial-gradient(circle at 78% -6%, rgba(255,153,73,0.12), transparent 32%), linear-gradient(135deg, #070a11 0%, #0b0f18 50%, #080c15 100%); color:var(--text); min-height:100vh; }
      .layout { display:flex; width:100%; min-height:100vh; background:radial-gradient(circle at 50% 20%, rgba(255,153,73,0.08), transparent 30%); }
      .sidebar { width:240px; background:linear-gradient(180deg, rgba(12,14,22,0.85), rgba(10,12,18,0.78)); border-right:1px solid rgba(255,255,255,0.06); padding:24px 20px; box-sizing:border-box; display:flex; flex-direction:column; gap:18px; backdrop-filter:blur(14px); box-shadow:8px 0 32px rgba(0,0,0,0.45); }
      .brand { font-size:20px; font-weight:800; letter-spacing:0.6px; color:var(--text); }
      .nav { display:flex; flex-direction:column; gap:8px; }
      .nav a { display:flex; align-items:center; gap:10px; padding:11px 13px; border-radius:14px; color:var(--muted); text-decoration:none; font-weight:700; transition:background 140ms ease, color 140ms ease, box-shadow 140ms ease, border 140ms ease; border:1px solid transparent; background:rgba(255,255,255,0.02); }
      .nav a .icon { opacity:0.85; width:18px; display:inline-flex; justify-content:center; }
      .nav a.active { background:rgba(249,115,22,0.18); color:var(--accent-strong); border-color:rgba(249,115,22,0.45); box-shadow:0 10px 30px rgba(249,115,22,0.28); }
      .nav a:hover { background:rgba(255,255,255,0.06); color:var(--text); border-color:rgba(255,255,255,0.08); box-shadow:0 8px 22px rgba(0,0,0,0.28); }
      .content { flex:1; padding:28px 34px 56px; box-sizing:border-box; background:linear-gradient(145deg, rgba(255,153,73,0.05) 0%, rgba(255,255,255,0) 32%); }
      h1 { margin:0; font-size:26px; letter-spacing:0.6px; font-weight:800; }
      .muted { color:var(--muted); font-size:13px; }
      main { padding-top:18px; display:flex; flex-direction:column; gap:18px; }
      .section { display:none; }
      .section.active { display:block; }
      .section.hidden { display:none !important; }
      .grid { display:grid; gap:14px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
      .card { background:var(--card); border:1px solid var(--border); border-radius:18px; padding:18px 20px; box-shadow:0 18px 45px rgba(0,0,0,0.35); backdrop-filter:blur(14px); }
      .stat { font-size:34px; font-weight:800; margin:0; color:var(--text); }
      .label { color:var(--muted); margin:4px 0 0 0; letter-spacing:0.2px; }
      .tickets-grid { display:grid; grid-template-columns: repeat(3, minmax(260px, 1fr)); gap:18px; align-items:start; }
      .ticket-list-pane { display:flex; flex-direction:column; gap:10px; max-height:520px; overflow-y:auto; padding:6px; margin-top:12px; }
      .ticket-list-pane::-webkit-scrollbar { width:6px; }
      .ticket-list-pane::-webkit-scrollbar-thumb { background:rgba(255,255,255,0.18); border-radius:10px; }
      .ticket-list-item { border:1px solid var(--border); background:rgba(255,255,255,0.04); border-radius:14px; padding:13px 15px; display:flex; flex-direction:column; gap:6px; cursor:pointer; transition:transform 140ms ease, border-color 140ms ease, box-shadow 140ms ease, background 140ms ease; box-shadow:0 14px 32px rgba(0,0,0,0.3); }
      .ticket-list-item:hover { transform:translateY(-2px); border-color:rgba(249,115,22,0.35); background:rgba(255,255,255,0.06); box-shadow:0 16px 38px rgba(0,0,0,0.36); }
      .ticket-item-top { display:flex; justify-content:space-between; gap:10px; align-items:center; }
      .ticket-title { font-weight:750; font-size:15px; }
      .ticket-meta { display:flex; flex-wrap:wrap; gap:8px; color:var(--muted); font-size:12px; }
      .ticket-status-badge { padding:5px 11px; border-radius:999px; font-weight:700; font-size:12px; text-transform:capitalize; border:1px solid rgba(255,255,255,0.1); background:rgba(255,255,255,0.05); color:var(--text); box-shadow:0 10px 22px rgba(0,0,0,0.24); }
      .status-open { background:rgba(249,115,22,0.18); color:var(--accent-strong); border-color:rgba(249,115,22,0.45); }
      .status-in-progress { background:rgba(255,184,70,0.16); color:#fbbf24; border-color:rgba(255,184,70,0.42); }
      .status-closed { background:rgba(239,68,68,0.16); color:#f87171; border-color:rgba(239,68,68,0.42); }
      .ticket-empty { padding:20px; text-align:center; color:var(--muted); border:1px dashed rgba(255,255,255,0.16); border-radius:14px; background:rgba(255,255,255,0.03); }
      .ticket-tab { display:none; }
      .ticket-tab.active { display:block; }
      .ticket-tab-btn.active { background:rgba(249,115,22,0.18); border-color:rgba(249,115,22,0.45); color:var(--accent-strong); }
      form { display:flex; flex-direction:column; gap:10px; margin-top:4px; }
      .form-field { display:flex; flex-direction:column; gap:6px; }
      .form-label { font-size:13px; color:var(--muted); letter-spacing:0.2px; font-weight:600; }
      input, select, textarea { padding:12px 12px; border-radius:14px; border:1px solid rgba(255,255,255,0.12); background:rgba(255,255,255,0.06); color:var(--text); backdrop-filter:blur(8px); }
      input::placeholder, textarea::placeholder { color:rgba(229,231,235,0.65); }
      button { padding:12px 14px; border-radius:14px; border:1px solid rgba(249,115,22,0.4); background:linear-gradient(130deg, #ff9b3d, #f97316); color:white; font-weight:800; cursor:pointer; box-shadow:0 14px 30px rgba(249,115,22,0.35); transition:transform 140ms ease, box-shadow 140ms ease, filter 140ms ease; }
      button:hover { transform:translateY(-1px); filter:brightness(1.05); box-shadow:0 18px 40px rgba(249,115,22,0.4); }
      .secondary-btn { background:rgba(255,255,255,0.08); border:1px solid rgba(255,255,255,0.14); box-shadow:0 10px 22px rgba(0,0,0,0.24); color:var(--text); }
      .danger-btn { background:linear-gradient(135deg, #ef4444, #dc2626); box-shadow:0 12px 30px rgba(239,68,68,0.35); border-color:rgba(239,68,68,0.5); }
      .row { display:flex; gap:12px; align-items:center; }
      select { min-height:44px; }
      .icon-button { width:40px; height:40px; border-radius:12px; border:1px solid rgba(249,115,22,0.3); background:rgba(249,115,22,0.16); color:var(--text); font-size:18px; display:inline-flex; align-items:center; justify-content:center; cursor:pointer; transition:transform 140ms ease, border-color 140ms ease, background 140ms ease, box-shadow 140ms ease; box-shadow:0 12px 28px rgba(0,0,0,0.28); }
      .icon-button:hover { transform:translateY(-1px); border-color:rgba(249,115,22,0.6); background:rgba(249,115,22,0.22); box-shadow:0 14px 34px rgba(0,0,0,0.32); }
      #status { margin-top:6px; color:#fbbf77; }
      .logout { margin-top:auto; border:none; color:white; padding:10px 12px; border-radius:12px; cursor:pointer; background:linear-gradient(135deg, #ef4444, #b91c1c); width:100%; box-shadow:0 12px 28px rgba(239,68,68,0.32); }
      .nav a.hidden { display:none; }
      .module-list { display:flex; flex-direction:column; gap:10px; }
      .module-item { display:flex; align-items:center; justify-content:space-between; padding:12px 14px; border-radius:14px; border:1px solid rgba(255,255,255,0.07); background:rgba(255,255,255,0.03); box-shadow:0 12px 26px rgba(0,0,0,0.25); }
      .toggle { position:relative; width:48px; height:26px; background:rgba(255,255,255,0.14); border-radius:999px; cursor:pointer; transition:background 140ms ease, border 140ms ease, box-shadow 140ms ease; border:1px solid rgba(255,255,255,0.1); box-shadow:inset 0 2px 8px rgba(0,0,0,0.2); }
      .toggle::after { content:''; position:absolute; top:3px; left:3px; width:20px; height:20px; border-radius:50%; background:#9ca3af; transition:transform 160ms ease, background 160ms ease, box-shadow 160ms ease; box-shadow:0 4px 10px rgba(0,0,0,0.3); }
      .toggle.active { background:rgba(249,115,22,0.3); border-color:rgba(249,115,22,0.6); box-shadow:0 8px 20px rgba(249,115,22,0.24); }
      .toggle.active::after { transform:translateX(22px); background:#ffd9b3; box-shadow:0 6px 14px rgba(249,115,22,0.35); }
      .module-meta { display:flex; flex-direction:column; gap:4px; }
      .module-title { font-weight:700; color:var(--text); }
      .module-desc { color:var(--muted); font-size:13px; }
      .toast { position:fixed; top:20px; right:24px; padding:12px 14px; border-radius:12px; background:rgba(249,115,22,0.18); border:1px solid rgba(249,115,22,0.45); color:#ffe6d0; font-weight:700; box-shadow:0 12px 32px rgba(0,0,0,0.34); opacity:0; transform:translateY(-10px); transition:opacity 150ms ease, transform 150ms ease; z-index:1100; backdrop-filter:blur(10px); }
      .toast.error { background:rgba(239,68,68,0.18); border-color:rgba(239,68,68,0.4); color:#ffe4e6; }
      .toast.show { opacity:1; transform:translateY(0); }
      .option-grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap:12px; margin-top:10px; }
      .option-card { border:1px solid rgba(255,255,255,0.08); border-radius:14px; padding:13px; background:rgba(255,255,255,0.04); display:flex; align-items:center; justify-content:space-between; gap:10px; box-shadow:0 12px 26px rgba(0,0,0,0.25); }
      .option-card label { font-weight:700; color:var(--text); }
      .switch { position:relative; width:52px; height:28px; border-radius:28px; background:rgba(255,255,255,0.14); border:1px solid rgba(255,255,255,0.1); cursor:pointer; transition:background 140ms ease, border 140ms ease, box-shadow 140ms ease; box-shadow:inset 0 2px 8px rgba(0,0,0,0.2); }
      .switch::after { content:''; position:absolute; top:3px; left:3px; width:22px; height:22px; border-radius:50%; background:#9ca3af; transition:transform 160ms ease, background 160ms ease, box-shadow 160ms ease; box-shadow:0 4px 10px rgba(0,0,0,0.3); }
      .switch.on { background:rgba(249,115,22,0.32); border-color:rgba(249,115,22,0.6); box-shadow:0 8px 20px rgba(249,115,22,0.22); }
      .switch.on::after { transform:translateX(22px); background:#ffd9b3; box-shadow:0 6px 14px rgba(249,115,22,0.35); }
      .admin-grid { display:grid; gap:14px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
      .activity-bars { display:flex; gap:8px; align-items:flex-end; min-height:140px; padding:10px; border-radius:14px; background:rgba(255,255,255,0.02); border:1px solid rgba(255,255,255,0.06); overflow:hidden; }
      .activity-bar { flex:1; background:linear-gradient(130deg, rgba(249,115,22,0.4), rgba(249,115,22,0.24)); border-radius:10px 10px 4px 4px; position:relative; min-height:6px; box-shadow:0 10px 22px rgba(0,0,0,0.26); }
      .activity-bar span { position:absolute; bottom:100%; left:50%; transform:translate(-50%, -4px); font-size:11px; color:var(--muted); white-space:nowrap; }
      .log-list { margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:8px; max-height:280px; overflow:auto; }
      .log-item { padding:10px 12px; border-radius:12px; border:1px solid rgba(255,255,255,0.08); background:rgba(255,255,255,0.03); display:flex; gap:10px; align-items:flex-start; }
      .log-level { padding:4px 8px; border-radius:999px; font-weight:800; font-size:12px; }
      .log-level.info { background:rgba(59,130,246,0.16); border:1px solid rgba(59,130,246,0.35); color:#bfdbfe; }
      .log-level.warn { background:rgba(251,191,36,0.18); border:1px solid rgba(251,191,36,0.35); color:#fef08a; }
      .log-level.error { background:rgba(239,68,68,0.18); border:1px solid rgba(239,68,68,0.4); color:#fecaca; }
      .status-card { display:flex; flex-direction:column; gap:6px; border:1px solid rgba(255,255,255,0.08); border-radius:14px; padding:12px; background:rgba(255,255,255,0.03); box-shadow:0 12px 28px rgba(0,0,0,0.24); }
      .status-top { display:flex; justify-content:space-between; gap:8px; align-items:center; }
      .status-meta { display:flex; gap:8px; flex-wrap:wrap; color:var(--muted); font-size:12px; }
      .status-badge { padding:4px 10px; border-radius:999px; font-weight:800; font-size:12px; }
      .status-up { background:rgba(34,197,94,0.18); border:1px solid rgba(34,197,94,0.4); color:#bbf7d0; }
      .status-down { background:rgba(239,68,68,0.18); border:1px solid rgba(239,68,68,0.4); color:#fecaca; }
      .status-unknown { background:rgba(148,163,184,0.18); border:1px solid rgba(148,163,184,0.4); color:#e2e8f0; }
      .module-badges { display:flex; gap:8px; flex-wrap:wrap; }
      .badge { padding:6px 10px; border-radius:12px; font-weight:700; font-size:12px; border:1px solid rgba(255,255,255,0.12); background:rgba(255,255,255,0.06); }
      .badge.active { border-color:rgba(249,115,22,0.4); color:#f97316; box-shadow:0 6px 18px rgba(249,115,22,0.25); }
      .inline { display:flex; align-items:center; gap:8px; }
      .form-row { display:flex; gap:12px; flex-wrap:wrap; }
      .form-row .form-field { flex:1; min-width:220px; }
      .embed-preview { margin-top:10px; border:1px solid rgba(255,255,255,0.1); background:rgba(255,255,255,0.04); border-radius:14px; padding:14px; display:flex; gap:12px; box-shadow:0 12px 28px rgba(0,0,0,0.26); }
      .embed-color { width:6px; border-radius:6px; background:var(--accent); }
      .embed-body { flex:1; display:flex; flex-direction:column; gap:6px; }
      .embed-title { font-weight:750; }
      .embed-desc { white-space:pre-wrap; color:#d7dce6; }
      .embed-footer { color:#9ca3af; font-size:12px; }
      .embed-image { margin-top:8px; max-width:240px; border-radius:10px; display:block; }
      .modal-backdrop { position:fixed; inset:0; background:rgba(4,5,8,0.7); opacity:0; pointer-events:none; transition:opacity 160ms ease; z-index:900; backdrop-filter:blur(4px); }
      .modal-backdrop.show { opacity:1; pointer-events:auto; }
      .modal { position:fixed; top:50%; left:50%; transform:translate(-50%, -50%) scale(0.98); width:min(540px, calc(100% - 32px)); background:var(--card); border:1px solid var(--border); border-radius:18px; box-shadow:0 25px 70px rgba(0,0,0,0.5); padding:18px 18px 16px; opacity:0; pointer-events:none; transition:opacity 160ms ease, transform 160ms ease; z-index:1000; backdrop-filter:blur(14px); }
      .modal.show { opacity:1; pointer-events:auto; transform:translate(-50%, -50%) scale(1); }
      .modal-header { display:flex; justify-content:space-between; align-items:center; gap:12px; }
      .modal-body { margin-top:12px; display:flex; flex-direction:column; gap:10px; }
      .modal-actions { margin-top:14px; display:flex; justify-content:flex-end; gap:10px; }
      .detail-grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap:10px; }
      .detail-tile { background:rgba(255,255,255,0.05); border:1px solid rgba(255,255,255,0.1); border-radius:14px; padding:10px 12px; box-shadow:0 12px 26px rgba(0,0,0,0.24); }
      .detail-label { color:var(--muted); font-size:12px; margin:0 0 4px; }
      .detail-value { font-weight:700; font-size:14px; }
      .linkish { color:var(--accent-strong); text-decoration:none; font-weight:700; }
      .linkish:hover { text-decoration:underline; }
      .section-title { font-size:17px; font-weight:800; margin:0; }
      .section-sub { color:var(--muted); margin:0; font-size:13px; }
      @media (max-width: 1100px) {
        .tickets-grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
      }
    </style>
  </head>
  <body>
    <div class="layout">
      ${sidebar}
      <div class="content">
        <div style="display:flex; justify-content:space-between; align-items:center; gap:12px;">
          <div>
            <h1>Guild Dashboard</h1>
            <div class="muted">Dashboard & Guild-Config</div>
          </div>
          <div>
            <p class="label" style="margin:0;">Guild</p>
            <select id="guildSelect"></select>
            <div id="status" class="muted"></div>
          </div>
        </div>
        <main>
          <div class="section" data-section="overview">
            <section class="card" style="display:flex; gap:12px; align-items:center;">
              <img id="guildIcon" src="https://cdn.discordapp.com/embed/avatars/0.png" alt="icon" style="width:54px;height:54px;border-radius:14px;object-fit:cover;border:1px solid rgba(255,255,255,0.1);" />
              <div style="flex:1;">
                <p class="section-title" id="guildName">Guild</p>
                <p class="section-sub">ID: <span id="guildIdLabel">-</span></p>
                <div class="module-badges" id="guildModules"></div>
              </div>
              <div class="pill">Bot aktiv</div>
            </section>
            <div class="grid">
              <section class="card">
                <p class="section-title">Guild Infos</p>
                <div class="detail-grid" style="margin-top:8px;">
                  <div class="detail-tile"><div class="detail-label">Owner</div><div class="detail-value" id="guildOwner">-</div></div>
                  <div class="detail-tile"><div class="detail-label">Erstellt</div><div class="detail-value" id="guildCreated">-</div></div>
                  <div class="detail-tile"><div class="detail-label">Member</div><div class="detail-value" id="guildMembers">-</div></div>
                  <div class="detail-tile"><div class="detail-label">Channels</div><div class="detail-value" id="guildChannels">-</div></div>
                  <div class="detail-tile"><div class="detail-label">Tickets offen</div><div class="detail-value" id="openCount">-</div></div>
                  <div class="detail-tile"><div class="detail-label">Tickets IP / Closed</div><div class="detail-value"><span id="ipCount">-</span> / <span id="closedCount">-</span></div></div>
                </div>
              </section>
              <section class="card">
                <p class="section-title">Activity</p>
                <div class="detail-grid" style="margin-top:8px;">
                  <div class="detail-tile"><div class="detail-label">Messages (24h)</div><div class="detail-value" id="actMessages">-</div></div>
                  <div class="detail-tile"><div class="detail-label">Commands (24h)</div><div class="detail-value" id="actCommands">-</div></div>
                  <div class="detail-tile"><div class="detail-label">Automod (24h)</div><div class="detail-value" id="actAutomod">-</div></div>
                </div>
              </section>
              <section class="card">
                <p class="section-title">Guild Logs</p>
                <ul class="log-list" id="guildLogs"></ul>
              </section>
            </div>
          </div>
                    <div class="section" data-section="tickets">
            <div class="card" style="display:flex; gap:10px; flex-wrap:wrap; align-items:center; justify-content:space-between;">
              <div>
                <p class="section-title">Tickets</p>
                <p class="section-sub">bersicht, Pipeline, SLA, Automationen, Knowledge-Base.</p>
              </div>
              <div class="row" style="gap:8px; flex-wrap:wrap;">
                <button class="secondary-btn ticket-tab-btn active" data-tab="overview">bersicht</button>
                <button class="secondary-btn ticket-tab-btn" data-tab="pipeline">Pipeline</button>
                <button class="secondary-btn ticket-tab-btn" data-tab="sla">SLA</button>
                <button class="secondary-btn ticket-tab-btn" data-tab="automations">Automationen</button>
                <button class="secondary-btn ticket-tab-btn" data-tab="kb">Knowledge-Base</button>
              </div>
            </div>

            <div id="ticketTabOverview" class="ticket-tab active">
              <section class="card">
                <div style="display:flex; align-items:center; justify-content:space-between; gap:12px;">
                  <div>
                    <p class="section-title">Ticketliste</p>
                    <p class="section-sub">Links auswhlen, Details im Modal. Plus ffnet Panel-Erstellung.</p>
                  </div>
                  <div class="row" style="gap:10px;">
                    <button class="secondary-btn" id="openSupportLogin" type="button">Support-Login Einstellungen</button>
                    <button class="icon-button" id="openPanelModal" title="Ticket-Panel erstellen">+</button>
                  </div>
                </div>
                <div class="ticket-list-pane" id="ticketListPane"></div>
              </section>
              <section class="card">
                <div class="row" style="justify-content:space-between; align-items:center;">
                  <div>
                    <p class="section-title">Support-Login Status</p>
                    <p class="section-sub">Aktive Supporter und letzte Sessions.</p>
                  </div>
                  <button class="icon-button" id="refreshSupportStatus">?</button>
                </div>
                <div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(240px,1fr)); gap:12px;">
                  <div>
                    <p class="label">Aktiv</p>
                    <div id="supportActiveList" class="ticket-list-pane" style="min-height:80px;"></div>
                  </div>
                  <div>
                    <p class="label">Letzte Sessions</p>
                    <div id="supportRecentList" class="ticket-list-pane" style="min-height:80px;"></div>
                  </div>
                </div>
              </section>
            </div>

            <div id="ticketTabPipeline" class="ticket-tab">
              <section class="card">
                <div style="display:flex; justify-content:space-between; align-items:center; gap:12px;">
                  <div>
                    <p class="section-title">Status-Pipeline</p>
                    <p class="section-sub">Tickets nach Phase. Status per Dropdown ndern.</p>
                  </div>
                </div>
                <div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(240px,1fr)); gap:12px;" id="pipelineGrid">
                  <div><p class="label">Neu</p><div class="ticket-list-pane" id="pipelineNeu"></div></div>
                  <div><p class="label">In Bearbeitung</p><div class="ticket-list-pane" id="pipelineIn"></div></div>
                  <div><p class="label">Warten auf User</p><div class="ticket-list-pane" id="pipelineWait"></div></div>
                  <div><p class="label">Erledigt</p><div class="ticket-list-pane" id="pipelineDone"></div></div>
                </div>
              </section>
            </div>

            <div id="ticketTabSla" class="ticket-tab">
              <section class="card">
                <div style="display:flex; justify-content:space-between; align-items:center; gap:12px;">
                  <div>
                    <p class="section-title">SLA / Response-Zeiten</p>
                    <p class="section-sub">Average Time to Claim / First Response.</p>
                  </div>
                  <select id="slaRange">
                    <option value="7">Letzte 7 Tage</option>
                    <option value="30" selected>Letzte 30 Tage</option>
                    <option value="90">Letzte 90 Tage</option>
                  </select>
                </div>
                <div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(300px,1fr)); gap:12px;">
                  <div>
                    <p class="label">SLA pro Supporter</p>
                    <table style="width:100%; border-collapse:collapse;" id="slaSupporterTable">
                      <thead><tr><th style="text-align:left;">Supporter</th><th>Tickets</th><th>TTC</th><th>TTFR</th></tr></thead>
                      <tbody id="slaSupporterBody"></tbody>
                    </table>
                  </div>
                  <div>
                    <p class="label">SLA pro Tag</p>
                    <table style="width:100%; border-collapse:collapse;" id="slaDaysTable">
                      <thead><tr><th style="text-align:left;">Datum</th><th>Tickets</th><th>TTC</th><th>TTFR</th></tr></thead>
                      <tbody id="slaDaysBody"></tbody>
                    </table>
                  </div>
                </div>
              </section>
            </div>

            <div id="ticketTabAutomations" class="ticket-tab">
              <section class="card">
                <div style="display:flex; justify-content:space-between; gap:12px; flex-wrap:wrap;">
                  <div>
                    <p class="section-title">Automationen</p>
                    <p class="section-sub">Regeln fr Ticket-Aktionen.</p>
                  </div>
                  <button class="secondary-btn" id="addAutomation">Neue Regel</button>
                </div>
                <div id="automationList" class="ticket-list-pane" style="margin-top:10px;"></div>
                <div id="automationFormWrap" style="margin-top:12px;">
                  <p class="label">Regel bearbeiten</p>
                  <form id="automationForm" style="display:grid; grid-template-columns: repeat(auto-fit, minmax(180px,1fr)); gap:10px;">
                    <input type="hidden" id="automationId" />
                    <div class="form-field"><label class="form-label">Name</label><input id="automationName" placeholder="Regelname" /></div>
                    <div class="form-field"><label class="form-label">Bedingung</label><select id="automationConditionType">
                      <option value="category">Kategorie</option>
                      <option value="status">Status</option>
                      <option value="age">Ticketalter (Stunden)</option>
                    </select></div>
                    <div class="form-field"><label class="form-label">Wert</label><input id="automationConditionValue" placeholder="z.B. Bug oder 24" /></div>
                    <div class="form-field"><label class="form-label">Aktion</label><select id="automationActionType">
                      <option value="pingRole">Rolle pingen</option>
                      <option value="reminder">Reminder posten</option>
                      <option value="flag">Status setzen</option>
                    </select></div>
                    <div class="form-field"><label class="form-label">Rolle/Status/Nachricht</label><input id="automationActionValue" placeholder="Rollen-ID, Status oder Nachricht" /></div>
                    <div class="form-field"><label class="form-label">Aktiv</label><div id="automationActive" class="switch on"></div></div>
                    <div class="form-field" style="grid-column:1/-1; display:flex; gap:8px;">
                      <button type="submit">Speichern</button>
                      <button type="button" class="secondary-btn" id="automationReset">Reset</button>
                    </div>
                  </form>
                </div>
              </section>
            </div>

            <div id="ticketTabKb" class="ticket-tab">
              <section class="card">
                <div style="display:flex; justify-content:space-between; gap:12px; flex-wrap:wrap;">
                  <div>
                    <p class="section-title">Knowledge-Base</p>
                    <p class="section-sub">Artikel fr Self-Service.</p>
                  </div>
                  <button class="secondary-btn" id="addKb">Neuer Artikel</button>
                </div>
                <div id="kbList" class="ticket-list-pane" style="margin-top:10px;"></div>
                <div id="kbFormWrap" style="margin-top:12px;">
                  <form id="kbForm" style="display:grid; grid-template-columns: repeat(auto-fit, minmax(200px,1fr)); gap:10px;">
                    <input type="hidden" id="kbId" />
                    <div class="form-field"><label class="form-label">Titel</label><input id="kbTitle" placeholder="Titel" /></div>
                    <div class="form-field"><label class="form-label">Keywords (kommagetrennt)</label><input id="kbKeywords" placeholder="bug, musik, ticket" /></div>
                    <div class="form-field" style="grid-column:1/-1;"><label class="form-label">Inhalt/Link</label><textarea id="kbContent" rows="3" placeholder="Kurze Anleitung oder Link"></textarea></div>
                    <div class="form-field" style="grid-column:1/-1; display:flex; gap:8px;">
                      <button type="submit">Speichern</button>
                      <button type="button" class="secondary-btn" id="kbReset">Reset</button>
                    </div>
                  </form>
                </div>
              </section>
            </div>
          </div><div class="section" data-section="automod">
            <section class="card">
              <div style="display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap;">
                <div>
                  <p class="section-title">Automod Einstellungen</p>
                  <p class="section-sub">Automod pro Guild aktivieren und Regeln konfigurieren.</p>
                </div>
                <div class="inline">
                  <span class="form-label">Automod aktivieren</span>
                  <div id="automodToggle" class="switch"></div>
                </div>
              </div>
              <form id="automodForm" style="margin-top:14px; display:flex; flex-direction:column; gap:12px;">
                <div class="option-grid">
                  <div class="option-card">
                    <label for="badWordFilter">Bad-Word-Filter</label>
                    <div id="badWordFilter" class="switch"></div>
                  </div>
                  <div class="option-card">
                    <label for="linkFilter">Link-/Invite-Filter</label>
                    <div id="linkFilter" class="switch"></div>
                  </div>
                  <div class="option-card">
                    <label for="spamFilter">Spam-/Flood-Erkennung</label>
                    <div id="spamFilter" class="switch"></div>
                  </div>
                  <div class="option-card">
                    <label for="capsFilter">Capslock-Filter</label>
                    <div id="capsFilter" class="switch"></div>
                  </div>
                </div>
                <div class="form-row">
                  <div class="form-field">
                    <label class="form-label">Log Channel ID</label>
                    <input id="automodLogChannel" placeholder="123456789012345678" />
                  </div>
                  <div class="form-field">
                    <label class="form-label">Empfindlichkeit</label>
                    <select id="automodSensitivity">
                      <option value="low">niedrig</option>
                      <option value="medium">mittel</option>
                      <option value="high">hoch</option>
                    </select>
                  </div>
                </div>
                <div class="form-row">
                  <div class="form-field">
                    <label class="form-label">Whitelist-Links (kommagetrennt)</label>
                    <input id="automodWhitelist" placeholder="example.com, partner.de" />
                  </div>
                </div>
                <div class="form-row">
                  <div class="form-field">
                    <label class="form-label">Custom Badwords (kommagetrennt oder zeilenweise)</label>
                    <textarea id="automodBadwords" rows="3" placeholder="badword1, badword2"></textarea>
                    <p class="muted">Diese Woerter werden zusaetzlich zum Standard-Filter geblockt.</p>
                  </div>
                  <div class="form-field">
                    <label class="form-label">Whitelist-Rollen (IDs, Kommagetrennt)</label>
                    <textarea id="automodWhitelistRoles" rows="3" placeholder="123,456"></textarea>
                    <p class="muted">Nachrichten von diesen Rollen werden nicht gefiltert.</p>
                  </div>
                </div>
                <div style="display:flex; justify-content:flex-end; gap:10px;">
                  <button type="submit">Speichern</button>
                </div>
                <p class="muted" id="automodStatus"></p>
              </form>
            </section>
          </div>
          <div class="section" data-section="welcome">
            <section class="card">
              <div style="display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap;">
                <div>
                  <p class="section-title">Willkommensnachrichten</p>
                  <p class="section-sub">Embed konfigurieren und Feature aktivieren.</p>
                </div>
                <div class="inline">
                  <span class="form-label">Aktivieren</span>
                  <div id="welcomeToggle" class="switch"></div>
                </div>
              </div>
              <form id="welcomeForm" style="display:flex; flex-direction:column; gap:12px; margin-top:12px;">
                <div class="form-row">
                  <div class="form-field">
                    <label class="form-label">Channel ID</label>
                    <input id="welcomeChannel" placeholder="123456789012345678" />
                  </div>
                  <div class="form-field">
                    <label class="form-label">Embed-Farbe</label>
                    <input id="welcomeColor" type="color" value="#f97316" />
                  </div>
                </div>
                <div class="form-row">
                  <div class="form-field">
                    <label class="form-label">Embed Titel</label>
                    <input id="welcomeTitle" placeholder="Willkommen!" />
                  </div>
                  <div class="form-field">
                    <label class="form-label">Embed Footer</label>
                    <input id="welcomeFooter" placeholder="Schön, dass du da bist!" />
                  </div>
                </div>
                <div class="form-field">
                  <label class="form-label">Embed Beschreibung</label>
                  <textarea id="welcomeDescription" rows="3" placeholder="Du kannst {user} verwenden."></textarea>
                </div>
                <div class="form-row">
                  <div class="form-field">
                    <label class="form-label">Thumbnail URL oder Upload</label>
                    <input id="welcomeThumbnail" placeholder="https://..." />
                    <input type="file" id="welcomeThumbnailFile" accept="image/*" />
                  </div>
                  <div class="form-field">
                    <label class="form-label">Bild URL oder Upload (GIFs erlaubt)</label>
                    <input id="welcomeImage" placeholder="https://..." />
                    <input type="file" id="welcomeImageFile" accept="image/*" />
                  </div>
                </div>
                <div class="embed-preview" id="welcomePreview">
                  <div class="embed-color" id="welcomePreviewColor"></div>
                  <div class="embed-body">
                    <div class="embed-title" id="welcomePreviewTitle">Willkommen!</div>
                    <div class="embed-desc" id="welcomePreviewDesc">Schön, dass du da bist.</div>
                    <div class="embed-footer" id="welcomePreviewFooter">Footer</div>
                    <img id="welcomePreviewImage" class="embed-image" style="display:none;" />
                  </div>
                </div>
                <div style="display:flex; justify-content:flex-end; gap:10px;">
                  <button type="submit">Speichern</button>
                </div>
                <p class="muted" id="welcomeStatus"></p>
              </form>
            </section>
          </div>
          <div class="section" data-section="dynamicvoice">
            <section class="card">
              <div style="display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap;">
                <div>
                  <p class="section-title">Dynamic Voice</p>
                  <p class="section-sub">Lobby waehlen, Channel-Namen & Limits setzen.</p>
                </div>
                <div class="inline">
                  <span class="form-label">Aktivieren</span>
                  <div id="dynamicVoiceToggle" class="switch"></div>
                </div>
              </div>
              <form id="dynamicVoiceForm" style="display:flex; flex-direction:column; gap:12px; margin-top:12px;">
                <div class="grid">
                  <div class="form-field">
                    <label class="form-label">Lobby Channel ID (Voice)</label>
                    <input id="dynamicVoiceLobby" placeholder="123456789012345678" />
                  </div>
                  <div class="form-field">
                    <label class="form-label">Kategorie ID (optional)</label>
                    <input id="dynamicVoiceCategory" placeholder="123456789012345678" />
                  </div>
                  <div class="form-field">
                    <label class="form-label">Name-Template</label>
                    <input id="dynamicVoiceTemplate" placeholder="{user}s Channel" />
                    <p class="muted">{user} wird durch den Mitgliedsnamen ersetzt.</p>
                  </div>
                  <div class="form-field">
                    <label class="form-label">Userlimit (optional)</label>
                    <input id="dynamicVoiceUserLimit" type="number" min="0" placeholder="0 = kein Limit" />
                  </div>
                  <div class="form-field">
                    <label class="form-label">Bitrate (optional)</label>
                    <input id="dynamicVoiceBitrate" type="number" min="8000" placeholder="z.B. 64000" />
                  </div>
                </div>
                <div style="display:flex; justify-content:flex-end; gap:10px;">
                  <button type="submit">Speichern</button>
                </div>
                <p class="muted" id="dynamicVoiceStatus"></p>
              </form>
            </section>
          </div>
          <div class="section" data-section="modules">
            <section class="card">
              <p class="label">Module</p>
              <div id="moduleList" class="module-list"></div>
            </section>
          </div>
          <div class="section" data-section="birthday">
            <section class="card">
              <div class="row" style="justify-content:space-between; align-items:flex-start; gap:12px;">
                <div>
                  <p class="section-title">Birthday</p>
                  <p class="section-sub">Automatische Glueckwuensche je Guild.</p>
                </div>
                <div class="row" style="align-items:center; gap:10px; flex-wrap:wrap; justify-content:flex-end;">
                  <label class="form-label">Sendezeit (Stunde)</label>
                  <input id="birthdayHour" type="number" min="0" max="23" placeholder="9" style="width:80px;" />
                  <label class="form-label">Channel ID</label>
                  <input id="birthdayChannel" placeholder="123456789012345678" style="width:180px;" />
                  <div id="birthdayToggle" class="switch"></div>
                </div>
              </div>
              <div class="form-field">
                <label class="form-label">Template</label>
                <textarea id="birthdayTemplate" rows="3" placeholder="Alles Gute zum Geburtstag, {user}!"></textarea>
                <p class="muted">Nutze {user} als Platzhalter.</p>
              </div>
              <div style="display:flex; justify-content:flex-end; gap:10px;">
                <button id="birthdaySave" type="button">Speichern</button>
              </div>
              <p class="muted" id="birthdayStatus"></p>
            </section>
            <section class="card">
              <div class="row" style="justify-content:space-between; align-items:center;">
                <div>
                  <p class="section-title">Gespeicherte Geburtstage</p>
                  <p class="section-sub">Eintraege werden per /birthday angelegt.</p>
                </div>
              </div>
              <div id="birthdayList" class="module-list"></div>
            </section>
          </div>
          <div class="section" data-section="reactionroles">
            <section class="card">
              <div class="row" style="justify-content:space-between; align-items:flex-start; gap:12px;">
                <div>
                  <p class="section-title">Reaction Roles</p>
                  <p class="section-sub">Reaktionen verteilen oder entfernen Rollen.</p>
                </div>
                <div class="muted" id="reactionRoleStatus"></div>
              </div>
              <form id="reactionRoleForm" style="display:flex; flex-direction:column; gap:12px; margin-top:8px;">
                <input type="hidden" id="reactionRoleId" />
                <div class="grid">
                  <div class="form-field">
                    <label class="form-label">Channel ID</label>
                    <input id="reactionRoleChannel" placeholder="123456789012345678" />
                  </div>
                  <div class="form-field">
                    <label class="form-label">Message ID (optional)</label>
                    <input id="reactionRoleMessageId" placeholder="Bestehende Nachricht verwenden" />
                  </div>
                  <div class="form-field">
                    <label class="form-label">Titel</label>
                    <input id="reactionRoleTitle" placeholder="Rollenwahl" />
                  </div>
                </div>
                <div class="form-field">
                  <label class="form-label">Beschreibung</label>
                  <textarea id="reactionRoleDescription" rows="2" placeholder="Kurze Beschreibung fuer das Embed"></textarea>
                </div>
                <div class="form-field">
                  <label class="form-label">Eintraege (Emoji | Role ID | Label | Beschreibung)</label>
                  <textarea id="reactionRoleEntries" rows="4" placeholder="😀 | 123456789 | Freunde | Erhaelt Freunde Rolle"></textarea>
                  <p class="muted">Eine Zeile pro Zuordnung. Label/Beschreibung optional.</p>
                </div>
                <div style="display:flex; justify-content:flex-end; gap:10px;">
                  <button type="button" class="secondary-btn" id="reactionRoleReset">Reset</button>
                  <button type="submit" id="reactionRoleSubmit">Speichern &amp; senden</button>
                </div>
              </form>
            </section>
            <section class="card">
              <div class="row" style="justify-content:space-between; align-items:center;">
                <div>
                  <p class="section-title">Reaction Role Nachrichten</p>
                  <p class="section-sub">Bestehende Setups bearbeiten oder syncen.</p>
                </div>
              </div>
              <div id="reactionRoleList" class="module-list"></div>
            </section>
          </div>
          <div class="section" data-section="statuspage">
            <section class="card">
              <div class="row" style="justify-content:space-between;">
                <div>
                  <p class="section-title">Statuspage</p>
                  <p class="section-sub">Services verwalten und Checks steuern.</p>
                </div>
                <div class="row">
                  <label class="form-label">Intervall (ms)</label>
                  <input id="statuspageInterval" type="number" min="30000" step="5000" placeholder="60000" />
                  <label class="form-label">Channel ID</label>
                  <input id="statuspageChannel" placeholder="Optional" />
                  <div id="statuspageToggle" class="switch"></div>
                </div>
              </div>
            </section>
            <section class="card">
              <div class="row" style="justify-content:space-between;align-items:center;">
                <div>
                  <p class="section-title">Services</p>
                  <p class="section-sub">Status, Uptime, letzter Check</p>
                </div>
                <button class="icon-button" id="statuspageAddService">+</button>
              </div>
              <div id="statuspageServices" class="module-list"></div>
            </section>
          </div>
          <div class="section" data-section="serverstats">
            <section class="card">
              <div class="row" style="justify-content:space-between; align-items:center; gap:10px; flex-wrap:wrap;">
                <div>
                  <p class="section-title">Server Stats</p>
                  <p class="section-sub">Kategorie und Counter verwalten.</p>
                </div>
                <div class="row" style="gap:8px; align-items:center;">
                  <label class="form-label">Kategorie-Name</label>
                  <input id="statsCategoryName" placeholder="Server Stats" />
                  <label class="form-label">Refresh (Min)</label>
                  <input id="statsRefresh" type="number" min="1" step="1" placeholder="10" />
                  <div id="statsToggle" class="switch"></div>
                </div>
              </div>
            </section>
            <section class="card">
              <div class="row" style="justify-content:space-between; align-items:center;">
                <div>
                  <p class="section-title">Statistiken</p>
                  <p class="section-sub">Counter und Format anpassen.</p>
                </div>
                <button class="icon-button" id="statsAddItem">+</button>
              </div>
              <div id="statsItems" class="module-list"></div>
            </section>
          </div>
          <div class="section" data-section="events">
            <section class="card">
              <div class="row" style="justify-content:space-between; align-items:center;">
                <div>
                  <p class="section-title">Events</p>
                  <p class="section-sub">Termine planen und Erinnerungen senden.</p>
                </div>
                <button class="icon-button" id="openEventModal">+</button>
              </div>
              <div id="eventList" class="ticket-list-pane"></div>
            </section>
          </div>
          <div class="section" data-section="admin">
            <div class="grid">
              <section class="card">
                <p class="section-title">Guilds</p>
                <p class="stat" id="adminGuilds">-</p>
                <p class="label">aktiv (24h): <span id="adminActiveGuilds">-</span></p>
              </section>
              <section class="card">
                <p class="section-title">Uptime</p>
                <p class="stat" id="adminUptime">-</p>
                <p class="label">Start: <span id="adminStart">-</span></p>
              </section>
            </div>
            <section class="card">
              <div class="row" style="justify-content:space-between;">
                <div>
                  <p class="section-title">Aktivität (letzte 24h)</p>
                  <p class="section-sub">Events/Commands pro Stunde</p>
                </div>
              </div>
              <div class="activity-bars" id="adminActivity"></div>
            </section>
            <section class="card">
              <div class="row" style="justify-content:space-between;">
                <div>
                  <p class="section-title">Logs</p>
                  <p class="section-sub">Neueste Einträge</p>
                </div>
              </div>
              <ul class="log-list" id="adminLogs"></ul>
            </section>
          </div>
          <div class="section" data-section="settings">
            <section class="card">
              <p class="label">Einstellungen speichern</p>
              <form id="settingsForm">
                <input name="welcomeChannelId" placeholder="Welcome Channel ID" />
                <input name="logChannelId" placeholder="Log Channel ID" />
                <input name="supportRoleId" placeholder="Support Role ID (optional)" />
                <button type="submit">Speichern</button>
                <p class="muted" id="saveStatus"></p>
              </form>
            </section>
            <section class="card">
              <p class="label">Logging</p>
              <div class="form-row">
                <div class="form-field">
                  <label class="form-label">Log Channel ID (Logging)</label>
                  <input id="loggingChannel" placeholder="123456789012345678" />
                  <p class="muted">Falls leer, wird der allgemeine Log Channel genutzt.</p>
                </div>
              </div>
              <div class="option-grid">
                <div class="option-card"><span>👋 User Join / Leave</span><div id="logJoinLeave" class="switch on"></div></div>
                <div class="option-card"><span>✏️ Message Edit</span><div id="logMsgEdit" class="switch on"></div></div>
                <div class="option-card"><span>🗑️ Message Delete</span><div id="logMsgDelete" class="switch on"></div></div>
                <div class="option-card"><span>🛡️ Automod Actions</span><div id="logAutomod" class="switch on"></div></div>
                <div class="option-card"><span>🎫 Ticket Actions</span><div id="logTickets" class="switch on"></div></div>
                <div class="option-card"><span>🎵 Musik-Events</span><div id="logMusic" class="switch on"></div></div>
                <div class="option-card"><span>⚙️ System / Channels</span><div id="logSystem" class="switch on"></div></div>
              </div>
              <div style="display:flex; justify-content:flex-end; gap:10px; margin-top:12px;">
                <button id="loggingSave" type="button">Logging speichern</button>
              </div>
              <p class="muted" id="loggingStatus"></p>
            </section>
          </div>
        </main>
      </div>
    </div>

    <div id="modalBackdrop" class="modal-backdrop"></div>

    <div class="modal" id="ticketModal">
      <div class="modal-header">
        <div>
          <p class="section-title" id="detailTitle">Ticket</p>
          <p class="section-sub" id="detailSubtitle">Details</p>
        </div>
        <button class="icon-button" data-close-modal>&times;</button>
      </div>
      <div class="modal-body">
        <div class="detail-grid">
          <div class="detail-tile">
            <p class="detail-label">Ticket-ID</p>
            <p class="detail-value" id="detailTicketId">-</p>
          </div>
          <div class="detail-tile">
            <p class="detail-label">Status</p>
            <p class="detail-value" id="detailStatus">-</p>
          </div>
          <div class="detail-tile">
            <p class="detail-label">Prioritaet</p>
            <p class="detail-value" id="detailPriority">-</p>
          </div>
          <div class="detail-tile">
            <p class="detail-label">Erstellt am</p>
            <p class="detail-value" id="detailCreated">-</p>
          </div>
        </div>
        <div class="detail-tile">
          <p class="detail-label">Ersteller</p>
          <p class="detail-value" id="detailCreator">-</p>
        </div>
        <div class="detail-tile" id="detailTranscriptRow" style="display:none;">
          <p class="detail-label">Transcript</p>
          <a id="detailTranscript" class="linkish" target="_blank" rel="noopener">Transcript anzeigen</a>
        </div>
      </div>
      <div class="modal-actions">
        <button class="secondary-btn" type="button" data-close-modal>Schliessen</button>
        <button class="danger-btn" type="button" id="closeTicketAction">Ticket schliessen</button>
      </div>
    </div>

    <div class="modal" id="panelModal">
      <div class="modal-header">
        <div>
          <p class="section-title">Ticket-Panel erstellen</p>
          <p class="section-sub">Channel und Kategorien definieren, dann Panel senden.</p>
        </div>
        <button class="icon-button" data-close-modal>&times;</button>
      </div>
      <div class="modal-body">
        <form id="panelForm">
          <div class="form-field">
            <label class="form-label">Channel ID (Textkanal)</label>
            <input name="channelId" placeholder="123456789012345678" required />
          </div>
          <div class="form-field">
            <label class="form-label">Panel Titel (optional)</label>
            <input name="panelTitle" placeholder="Support Panel" />
          </div>
          <div class="form-field">
            <label class="form-label">Beschreibung (optional)</label>
            <textarea name="panelDescription" placeholder="Kurze Beschreibung" rows="3"></textarea>
          </div>
          <div class="form-field">
            <label class="form-label">Kategorien (pro Zeile: Label|CustomId|Emoji optional)</label>
            <textarea name="panelCategories" placeholder="Technische Hilfe|support|:bulb:" rows="4"></textarea>
            <p class="muted">Beispiel: Billing|billing|:credit_card:</p>
          </div>
          <p class="muted" id="panelStatus"></p>
        </form>
      </div>
      <div class="modal-actions">
        <button class="secondary-btn" type="button" data-close-modal>Abbrechen</button>
        <button type="button" id="panelSubmit">Panel senden</button>
      </div>
    </div>

    <div class="modal" id="supportLoginModal">
      <div class="modal-header">
        <div>
          <p class="section-title">Support-Login Einstellungen</p>
          <p class="section-sub">Channel, Texte und Buttons fuer das Support-Panel.</p>
        </div>
        <button class="icon-button" data-close-modal>&times;</button>
      </div>
      <div class="modal-body">
        <form id="supportLoginForm">
          <div class="form-field">
            <label class="form-label">Panel Channel ID</label>
            <input id="supportLoginChannel" placeholder="123456789012345678" required />
          </div>
          <div class="form-field">
            <label class="form-label">Titel</label>
            <input id="supportLoginTitle" placeholder="Support Login" />
          </div>
          <div class="form-field">
            <label class="form-label">Beschreibung</label>
            <textarea id="supportLoginDescription" rows="3" placeholder="Melde dich als Support an/ab."></textarea>
          </div>
          <div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(200px,1fr)); gap:12px;">
            <div class="form-field">
              <label class="form-label">Button Label Login</label>
              <input id="supportLoginLabel" placeholder="Ich bin jetzt im Support" />
            </div>
            <div class="form-field">
              <label class="form-label">Button Label Logout</label>
              <input id="supportLogoutLabel" placeholder="Ich bin nicht mehr im Support" />
            </div>
          </div>
          <div class="row" style="justify-content:flex-start; align-items:center; gap:10px;">
            <span class="form-label">Panel automatisch aktualisieren</span>
            <div id="supportLoginAuto" class="switch"></div>
          </div>
          <p class="muted" id="supportLoginStatus"></p>
        </form>
      </div>
      <div class="modal-actions">
        <button class="secondary-btn" type="button" data-close-modal>Abbrechen</button>
        <button type="button" id="supportLoginSave">Speichern &amp; Panel aktualisieren</button>
      </div>
    </div>

    <div class="modal" id="eventModal">
      <div class="modal-header">
        <div>
          <p class="section-title">Event erstellen/bearbeiten</p>
          <p class="section-sub">Titel, Zeit und Reminder festlegen.</p>
        </div>
        <button class="icon-button" data-close-modal>&times;</button>
      </div>
      <div class="modal-body">
        <form id="eventForm">
          <input type="hidden" id="eventId" />
          <div class="form-field">
            <label class="form-label">Titel</label>
            <input id="eventTitle" required />
          </div>
          <div class="form-field">
            <label class="form-label">Beschreibung</label>
            <textarea id="eventDescription" rows="3"></textarea>
          </div>
          <div class="form-field">
            <label class="form-label">Channel ID</label>
            <input id="eventChannel" placeholder="123456789012345678" required />
          </div>
          <div class="grid" style="grid-template-columns: repeat(auto-fit, minmax(200px,1fr)); gap:12px;">
            <div class="form-field">
              <label class="form-label">Start Datum</label>
              <input id="eventDate" type="date" />
            </div>
            <div class="form-field">
              <label class="form-label">Start Zeit</label>
              <input id="eventTime" type="time" />
            </div>
            <div class="form-field">
              <label class="form-label">Wiederholung</label>
              <select id="eventRepeat">
                <option value="none">einmalig</option>
                <option value="daily">taeglich</option>
                <option value="weekly">woechentlich</option>
                <option value="monthly">monatlich</option>
              </select>
            </div>
          </div>
          <div class="form-field" id="eventWeeklyRow" style="display:none;">
            <label class="form-label">Wochentage (0=So)</label>
            <input id="eventWeeklyDays" placeholder="1,3,5" />
          </div>
          <div class="form-field" id="eventMonthlyRow" style="display:none;">
            <label class="form-label">Tag im Monat (1-31)</label>
            <input id="eventMonthlyDay" type="number" min="1" max="31" />
          </div>
          <div class="form-field">
            <label class="form-label">Reminder (Minuten vorher)</label>
            <input id="eventReminder" type="number" min="0" placeholder="120" />
          </div>
          <div class="form-field">
            <label class="form-label">Ping-Rolle (optional)</label>
            <input id="eventRole" placeholder="Role ID" />
          </div>
          <p class="muted" id="eventStatus"></p>
        </form>
      </div>
      <div class="modal-actions">
        <button class="secondary-btn" type="button" data-close-modal>Abbrechen</button>
        <button type="button" id="eventSave">Speichern</button>
      </div>
    </div>

    <div id="toast" class="toast"></div>
    <script>
      ${baseScript}
      const guildSelect = document.getElementById('guildSelect');
      const statusEl = document.getElementById('status');
      const userInfo = document.getElementById('userInfo');
      const sections = Array.from(document.querySelectorAll('.section'));
      const navLinks = Array.from(document.querySelectorAll('.nav a'));
      const automodNav = document.querySelector('.nav .automod-link');
      const welcomeNav = document.querySelector('.nav .welcome-link');
      const dynamicVoiceNav = document.querySelector('.nav .dynamicvoice-link');
      const toastEl = document.getElementById('toast');
      const ticketListPane = document.getElementById('ticketListPane');
      const modalBackdrop = document.getElementById('modalBackdrop');
      const ticketModal = document.getElementById('ticketModal');
      const panelModal = document.getElementById('panelModal');
      const supportLoginModal = document.getElementById('supportLoginModal');
      const automodForm = document.getElementById('automodForm');
      const automodToggle = document.getElementById('automodToggle');
      const badWordToggle = document.getElementById('badWordFilter');
      const linkFilterToggle = document.getElementById('linkFilter');
      const spamFilterToggle = document.getElementById('spamFilter');
      const capsFilterToggle = document.getElementById('capsFilter');
      const automodLogChannel = document.getElementById('automodLogChannel');
      const automodSensitivity = document.getElementById('automodSensitivity');
      const automodWhitelist = document.getElementById('automodWhitelist');
      const automodStatus = document.getElementById('automodStatus');
      const automodBadwords = document.getElementById('automodBadwords');
      const automodWhitelistRoles = document.getElementById('automodWhitelistRoles');
      const loggingChannel = document.getElementById('loggingChannel');
      const loggingStatus = document.getElementById('loggingStatus');
      const logJoinLeave = document.getElementById('logJoinLeave');
      const logMsgEdit = document.getElementById('logMsgEdit');
      const logMsgDelete = document.getElementById('logMsgDelete');
      const logAutomod = document.getElementById('logAutomod');
      const logTickets = document.getElementById('logTickets');
      const logMusic = document.getElementById('logMusic');
      const logSystem = document.getElementById('logSystem');
      const supportLoginForm = document.getElementById('supportLoginForm');
      const supportLoginChannel = document.getElementById('supportLoginChannel');
      const supportLoginTitle = document.getElementById('supportLoginTitle');
      const supportLoginDescription = document.getElementById('supportLoginDescription');
      const supportLoginLabel = document.getElementById('supportLoginLabel');
      const supportLogoutLabel = document.getElementById('supportLogoutLabel');
      const supportLoginAuto = document.getElementById('supportLoginAuto');
      const supportLoginStatus = document.getElementById('supportLoginStatus');
      const supportActiveList = document.getElementById('supportActiveList');
      const supportRecentList = document.getElementById('supportRecentList');
      const welcomeToggle = document.getElementById('welcomeToggle');
      const welcomeForm = document.getElementById('welcomeForm');
      const welcomeChannel = document.getElementById('welcomeChannel');
      const welcomeColor = document.getElementById('welcomeColor');
      const welcomeTitle = document.getElementById('welcomeTitle');
      const welcomeFooter = document.getElementById('welcomeFooter');
      const welcomeDescription = document.getElementById('welcomeDescription');
      const welcomeThumbnail = document.getElementById('welcomeThumbnail');
      const welcomeImage = document.getElementById('welcomeImage');
      const welcomeStatus = document.getElementById('welcomeStatus');
      const dynamicVoiceToggle = document.getElementById('dynamicVoiceToggle');
      const dynamicVoiceLobby = document.getElementById('dynamicVoiceLobby');
      const dynamicVoiceCategory = document.getElementById('dynamicVoiceCategory');
      const dynamicVoiceTemplate = document.getElementById('dynamicVoiceTemplate');
      const dynamicVoiceUserLimit = document.getElementById('dynamicVoiceUserLimit');
      const dynamicVoiceBitrate = document.getElementById('dynamicVoiceBitrate');
      const dynamicVoiceStatus = document.getElementById('dynamicVoiceStatus');
      const birthdayToggle = document.getElementById('birthdayToggle');
      const birthdayChannel = document.getElementById('birthdayChannel');
      const birthdayHour = document.getElementById('birthdayHour');
      const birthdayTemplate = document.getElementById('birthdayTemplate');
      const birthdayList = document.getElementById('birthdayList');
      const birthdayStatus = document.getElementById('birthdayStatus');
      const birthdaySave = document.getElementById('birthdaySave');
      const reactionRoleForm = document.getElementById('reactionRoleForm');
      const reactionRoleId = document.getElementById('reactionRoleId');
      const reactionRoleChannel = document.getElementById('reactionRoleChannel');
      const reactionRoleMessageId = document.getElementById('reactionRoleMessageId');
      const reactionRoleTitle = document.getElementById('reactionRoleTitle');
      const reactionRoleDescription = document.getElementById('reactionRoleDescription');
      const reactionRoleEntries = document.getElementById('reactionRoleEntries');
      const reactionRoleStatus = document.getElementById('reactionRoleStatus');
      const reactionRoleList = document.getElementById('reactionRoleList');
      const reactionRoleReset = document.getElementById('reactionRoleReset');
      const reactionRoleSubmit = document.getElementById('reactionRoleSubmit');
      const openSupportLogin = document.getElementById('openSupportLogin');
      const supportLoginSave = document.getElementById('supportLoginSave');
      const refreshSupportStatus = document.getElementById('refreshSupportStatus');
      const eventList = document.getElementById('eventList');
      const openEventModal = document.getElementById('openEventModal');
      const eventModal = document.getElementById('eventModal');
      const eventId = document.getElementById('eventId');
      const eventTitle = document.getElementById('eventTitle');
      const eventDescription = document.getElementById('eventDescription');
      const eventChannel = document.getElementById('eventChannel');
      const eventDate = document.getElementById('eventDate');
      const eventTime = document.getElementById('eventTime');
      const eventRepeat = document.getElementById('eventRepeat');
      const eventWeeklyDays = document.getElementById('eventWeeklyDays');
      const eventMonthlyDay = document.getElementById('eventMonthlyDay');
      const eventReminder = document.getElementById('eventReminder');
      const eventRole = document.getElementById('eventRole');
      const eventStatus = document.getElementById('eventStatus');
      const eventWeeklyRow = document.getElementById('eventWeeklyRow');
      const eventMonthlyRow = document.getElementById('eventMonthlyRow');
      const eventSave = document.getElementById('eventSave');
      const statuspageToggle = document.getElementById('statuspageToggle');
      const statuspageInterval = document.getElementById('statuspageInterval');
      const statuspageChannel = document.getElementById('statuspageChannel');
      const statuspageServices = document.getElementById('statuspageServices');
      const statuspageAddService = document.getElementById('statuspageAddService');
      const adminGuilds = document.getElementById('adminGuilds');
      const adminActiveGuilds = document.getElementById('adminActiveGuilds');
      const adminUptime = document.getElementById('adminUptime');
      const adminStart = document.getElementById('adminStart');
      const adminActivity = document.getElementById('adminActivity');
      const adminLogs = document.getElementById('adminLogs');
      const guildIcon = document.getElementById('guildIcon');
      const guildNameEl = document.getElementById('guildName');
      const guildIdLabel = document.getElementById('guildIdLabel');
      const guildModules = document.getElementById('guildModules');
      const guildOwner = document.getElementById('guildOwner');
      const guildCreated = document.getElementById('guildCreated');
      const guildMembers = document.getElementById('guildMembers');
      const guildChannels = document.getElementById('guildChannels');
      const actMessages = document.getElementById('actMessages');
      const actCommands = document.getElementById('actCommands');
      const actAutomod = document.getElementById('actAutomod');
      const guildLogs = document.getElementById('guildLogs');
      const musicActiveEl = document.getElementById('musicActive');
      const welcomePreview = {
        color: document.getElementById('welcomePreviewColor'),
        title: document.getElementById('welcomePreviewTitle'),
        desc: document.getElementById('welcomePreviewDesc'),
        footer: document.getElementById('welcomePreviewFooter'),
        image: document.getElementById('welcomePreviewImage')
      };
      let currentGuild = '${guildId}';
      let ticketCache = [];
      let pipelineCache = { neu: [], in_bearbeitung: [], warten_auf_user: [], erledigt: [] };
      let slaSupporters = [];
      let slaDays = [];
      let automationCache = [];
      let kbCache = [];
      let selectedTicket = null;
      let activeModal = null;
      let automodConfigCache = {};
      let modulesCache = {};
      let serverStatsCache = { items: [] };
      let dynamicVoiceCache = {};
      let isAdmin = false;
      let statuspageCache = { services: [] };
      let birthdayCache = { config: {}, birthdays: [] };
      let reactionRoleCache = [];
      let editingReactionRole = null;
      let supportLoginCache = {};
      let eventsCache = [];

      function activateSection(key) {
        sections.forEach((s) => s.classList.toggle('active', s.dataset.section === key));
        navLinks.forEach((l) => l.classList.toggle('active', l.dataset.target === key));
        if (key === 'admin' && isAdmin) loadAdminAll();
      }

      function showToast(message, isError=false) {
        if (!toastEl) return;
        toastEl.textContent = message;
        toastEl.classList.toggle('error', isError);
        toastEl.classList.add('show');
        setTimeout(() => toastEl.classList.remove('show'), 2200);
      }

      function formatDuration(ms) {
        if (ms === null || ms === undefined) return '-';
        const minutes = Math.max(0, Math.round(ms / 60000));
        if (minutes < 60) return minutes + 'm';
        const hours = Math.floor(minutes / 60);
        const mins = minutes % 60;
        return hours + 'h ' + (mins ? mins + 'm' : '');
      }

      function applyNavVisibility() {
        const autoEnabled = Object.prototype.hasOwnProperty.call(modulesCache, 'automodEnabled') ? modulesCache['automodEnabled'] : true;
        const welcomeEnabled = Object.prototype.hasOwnProperty.call(modulesCache, 'welcomeEnabled') ? modulesCache['welcomeEnabled'] : true;
        const dynamicVoiceEnabled = Object.prototype.hasOwnProperty.call(modulesCache, 'dynamicVoiceEnabled') ? modulesCache['dynamicVoiceEnabled'] : true;
        const statuspageEnabled = Object.prototype.hasOwnProperty.call(modulesCache, 'statuspageEnabled') ? modulesCache['statuspageEnabled'] : true;
        const serverStatsEnabled = Object.prototype.hasOwnProperty.call(modulesCache, 'serverStatsEnabled') ? modulesCache['serverStatsEnabled'] : false;
        const birthdayEnabled = Object.prototype.hasOwnProperty.call(modulesCache, 'birthdayEnabled') ? modulesCache['birthdayEnabled'] : true;
        const reactionRolesEnabled = Object.prototype.hasOwnProperty.call(modulesCache, 'reactionRolesEnabled') ? modulesCache['reactionRolesEnabled'] : true;
        const eventsEnabled = Object.prototype.hasOwnProperty.call(modulesCache, 'eventsEnabled') ? modulesCache['eventsEnabled'] : true;
        if (automodNav) automodNav.classList.toggle('hidden', !autoEnabled);
        if (welcomeNav) welcomeNav.classList.toggle('hidden', !welcomeEnabled);
        if (dynamicVoiceNav) dynamicVoiceNav.classList.toggle('hidden', !dynamicVoiceEnabled);
        const statuspageNav = document.querySelector('.nav .statuspage-link');
        if (statuspageNav) statuspageNav.classList.toggle('hidden', !statuspageEnabled);
        const serverstatsNav = document.querySelector('.nav .serverstats-link');
        if (serverstatsNav) serverstatsNav.classList.toggle('hidden', !serverStatsEnabled);
        const birthdayNav = document.querySelector('.nav .birthday-link');
        if (birthdayNav) birthdayNav.classList.toggle('hidden', !birthdayEnabled);
        const reactionRolesNav = document.querySelector('.nav .reactionroles-link');
        if (reactionRolesNav) reactionRolesNav.classList.toggle('hidden', !reactionRolesEnabled);
        const eventsNav = document.querySelector('.nav .events-link');
        if (eventsNav) eventsNav.classList.toggle('hidden', !eventsEnabled);
        const adminNav = document.querySelector('.nav .admin-link');
        if (adminNav) adminNav.classList.toggle('hidden', !isAdmin);
        const current = location.hash.replace('#','') || 'overview';
        if (
          (current === 'automod' && !autoEnabled) ||
          (current === 'welcome' && !welcomeEnabled) ||
          (current === 'dynamicvoice' && !dynamicVoiceEnabled) ||
          (current === 'statuspage' && !statuspageEnabled) ||
          (current === 'serverstats' && !serverStatsEnabled) ||
          (current === 'birthday' && !birthdayEnabled) ||
          (current === 'reactionroles' && !reactionRolesEnabled) ||
          (current === 'events' && !eventsEnabled) ||
          (current === 'admin' && !isAdmin)
        ) {
          activateSection('overview');
          history.replaceState(null, '', '#overview');
        }
      }

      function setSwitch(el, on) {
        if (!el) return;
        el.classList.toggle('on', !!on);
      }

      function getSwitch(el) {
        return !!el?.classList.contains('on');
      }

      function parseList(val) {
        return (val || '')
          .split(/[,\\n]/)
          .map((s) => s.trim())
          .filter(Boolean);
      }

      function formatDuration(ms) {
        const totalMinutes = Math.floor(ms / 60000);
        const days = Math.floor(totalMinutes / 1440);
        const hours = Math.floor((totalMinutes % 1440) / 60);
        const minutes = totalMinutes % 60;
        return days + 'd ' + hours + 'h ' + minutes + 'm';
      }

      async function loadGuildInfo() {
        if (!currentGuild) return;
        const res = await fetch('/api/guild/info?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) {
          if (guildNameEl) guildNameEl.textContent = 'Guild';
          return;
        }
        const data = await res.json();
        const g = data.guild || {};
        if (guildNameEl) guildNameEl.textContent = g.name || 'Guild';
        if (guildIdLabel) guildIdLabel.textContent = g.id || '-';
        if (guildOwner) guildOwner.textContent = g.owner?.tag || '-';
        if (guildCreated) guildCreated.textContent = g.createdAt ? formatDate(g.createdAt) : '-';
        if (guildMembers) guildMembers.textContent = g.memberCount ?? 0;
        if (guildChannels) guildChannels.textContent = (g.textCount || 0) + ' Text / ' + (g.voiceCount || 0) + ' Voice';
        if (guildIcon && g.icon) guildIcon.src = 'https://cdn.discordapp.com/icons/' + g.id + '/' + g.icon + '.png';
        if (guildIcon && !g.icon) guildIcon.src = 'https://cdn.discordapp.com/embed/avatars/0.png';
        if (guildModules) {
          guildModules.innerHTML = '';
          const mods = g.modules || {};
          Object.entries(mods).forEach(([key, on]) => {
            const badge = document.createElement('span');
            badge.className = 'badge' + (on ? ' active' : '');
            badge.textContent = key.replace('Enabled', '');
            guildModules.appendChild(badge);
          });
        }
      }

      async function loadGuildActivity() {
        if (!currentGuild) return;
        const res = await fetch('/api/guild/activity?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) {
          if (actMessages) actMessages.textContent = '0';
          if (actCommands) actCommands.textContent = '0';
          if (actAutomod) actAutomod.textContent = '0';
          return;
        }
        const data = await res.json();
        const a = data.activity || {};
        if (actMessages) actMessages.textContent = a.messages24h ?? 0;
        if (actCommands) actCommands.textContent = a.commands24h ?? 0;
        if (actAutomod) actAutomod.textContent = a.automod24h ?? 0;
      }

      async function loadGuildLogs() {
        if (!currentGuild) return;
        const res = await fetch('/api/guild/logs?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        const logs = data.logs || [];
        if (!guildLogs) return;
        guildLogs.innerHTML = '';
        logs.forEach((l) => {
          const li = document.createElement('li');
          li.className = 'log-item';
          const level = document.createElement('span');
          const lvl = (l.level || 'info').toString().toLowerCase();
          level.className = 'log-level ' + lvl;
          level.textContent = (l.level || '').toUpperCase();
          const body = document.createElement('div');
          body.style.flex = '1';
          const time = document.createElement('div');
          time.className = 'muted';
          time.textContent = formatDate(l.timestamp || Date.now());
          const msg = document.createElement('div');
          msg.textContent = (l.category ? '[' + l.category + '] ' : '') + (l.message || '');
          body.appendChild(time);
          body.appendChild(msg);
          li.appendChild(level);
          li.appendChild(body);
          guildLogs.appendChild(li);
        });
        if (!logs.length) guildLogs.innerHTML = '<li class="muted">Keine Logs</li>';
      }

      const STAT_LABELS = {
        members_total: 'Mitglieder (gesamt)',
        members_humans: 'Mitglieder (ohne Bots)',
        members_bots: 'Bots',
        boosts: 'Server Boosts',
        text_channels: 'Text Channels',
        voice_channels: 'Voice Channels',
        roles: 'Rollen'
      };

      async function loadServerStats() {
        if (!currentGuild) return;
        const res = await fetch('/api/server-stats?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        serverStatsCache = data.config || { items: [] };
        setSwitch(statsToggle, serverStatsCache.enabled !== false);
        if (statsCategoryName) statsCategoryName.value = serverStatsCache.categoryName || 'Server Stats';
        if (statsRefresh) statsRefresh.value = serverStatsCache.refreshMinutes ?? 10;
        renderServerStats();
      }

      function renderServerStats() {
        if (!statsItems) return;
        statsItems.innerHTML = '';
        (serverStatsCache.items || []).forEach((item) => {
          const row = document.createElement('div');
          row.className = 'module-item';
          const meta = document.createElement('div');
          meta.className = 'module-meta';
          const label = STAT_LABELS[item.type] || item.type;
          meta.innerHTML =
            '<div class="module-title">' + label + '</div><div class="module-desc">' + (item.label || label) + ' - ' + (item.format || '{label}: {value}') + '</div>';
          const buttons = document.createElement('div');
          buttons.className = 'row';
          const edit = document.createElement('button');
          edit.className = 'secondary-btn';
          edit.textContent = 'Bearbeiten';
          edit.addEventListener('click', () => editServerStat(item));
          const del = document.createElement('button');
          del.className = 'danger-btn';
          del.textContent = 'Loeschen';
          del.addEventListener('click', () => {
            serverStatsCache.items = (serverStatsCache.items || []).filter((x) => x !== item);
            renderServerStats();
            saveServerStats();
          });
          buttons.appendChild(edit);
          buttons.appendChild(del);
          row.appendChild(meta);
          row.appendChild(buttons);
          statsItems.appendChild(row);
        });
        if (!(serverStatsCache.items || []).length) statsItems.innerHTML = '<div class="muted">Keine Statistiken</div>';
      }

      function editServerStat(item) {
        const typeKeys = Object.keys(STAT_LABELS);
        const nextType = prompt('Typ (' + typeKeys.join(', ') + ')', item?.type || 'members_total');
        if (!nextType || !STAT_LABELS[nextType]) return;
        const nextLabel = prompt('Label', item?.label || STAT_LABELS[nextType]) || STAT_LABELS[nextType];
        const nextFormat = prompt('Format ({label} / {value})', item?.format || '{label}: {value}') || '{label}: {value}';
        if (item) {
          item.type = nextType;
          item.label = nextLabel;
          item.format = nextFormat;
        } else {
          (serverStatsCache.items = serverStatsCache.items || []).push({
            id: (crypto.randomUUID && crypto.randomUUID()) || String(Date.now()),
            type: nextType,
            label: nextLabel,
            format: nextFormat
          });
        }
        renderServerStats();
        saveServerStats();
      }

      async function saveServerStats() {
        if (!currentGuild) return;
        const payload = {
          guildId: currentGuild,
          config: {
            enabled: getSwitch(statsToggle),
            categoryName: statsCategoryName?.value || undefined,
            refreshMinutes: statsRefresh?.value ? Number(statsRefresh.value) : undefined,
            items: serverStatsCache.items || []
          }
        };
        const res = await fetch('/api/server-stats', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(payload)
        });
        if (!res.ok) showToast('Server Stats speichern fehlgeschlagen', true);
      }

      async function loadStatuspage() {
        if (!currentGuild) return;
        const res = await fetch('/api/statuspage?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        statuspageCache = data.config || { services: [] };
        setSwitch(statuspageToggle, statuspageCache.enabled !== false);
        if (statuspageInterval) statuspageInterval.value = statuspageCache.intervalMs ?? 60000;
        if (statuspageChannel) statuspageChannel.value = statuspageCache.statusChannelId ?? '';
        renderStatuspageServices();
      }

      function renderStatuspageServices() {
        if (!statuspageServices) return;
        statuspageServices.innerHTML = '';
        (statuspageCache.services || []).forEach((svc) => {
          const card = document.createElement('div');
          card.className = 'status-card';
          const top = document.createElement('div');
          top.className = 'status-top';
          const name = document.createElement('div');
          name.innerHTML = '<strong>' + (svc.name || 'Service') + '</strong><div class="muted">' + (svc.description || '') + '</div>';
          const badge = document.createElement('span');
          badge.className = 'status-badge ' + (svc.status === 'down' ? 'status-down' : svc.status === 'up' ? 'status-up' : 'status-unknown');
          badge.textContent = (svc.status || 'unknown').toUpperCase();
          top.appendChild(name);
          top.appendChild(badge);
          const meta = document.createElement('div');
          meta.className = 'status-meta';
          const uptime =
            svc.upChecks && svc.totalChecks
              ? Math.round(((svc.upChecks ?? 0) / Math.max(1, svc.totalChecks ?? 1)) * 100)
              : 0;
          meta.innerHTML =
            '<span>Type: ' +
            (svc.type || 'unknown') +
            '</span><span>Target: ' +
            (svc.target || '') +
            '</span><span>Uptime: ' +
            uptime +
            '%</span><span>Last: ' +
            (svc.lastChecked ? formatDate(svc.lastChecked) : 'n/a') +
            '</span>';
          const actions = document.createElement('div');
          actions.className = 'row';
          const del = document.createElement('button');
          del.className = 'danger-btn';
          del.textContent = 'Löschen';
          del.addEventListener('click', async () => {
            await deleteService(svc.id);
          });
          actions.appendChild(del);
          card.appendChild(top);
          card.appendChild(meta);
          card.appendChild(actions);
          statuspageServices.appendChild(card);
        });
        if (!(statuspageCache.services || []).length) statuspageServices.innerHTML = '<div class="muted">Keine Services</div>';
      }

      async function saveStatuspageConfig() {
        if (!currentGuild) return;
        const cfg = {
          enabled: getSwitch(statuspageToggle),
          intervalMs: statuspageInterval?.value ? Number(statuspageInterval.value) : undefined,
          statusChannelId: statuspageChannel?.value || undefined,
          services: statuspageCache.services || []
        };
        const res = await fetch('/api/statuspage', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ guildId: currentGuild, config: cfg })
        });
        if (!res.ok) showToast('Statuspage speichern fehlgeschlagen', true);
      }

      async function addServicePrompt() {
        if (!currentGuild) return;
        const name = prompt('Name?');
        if (!name) return;
        const target = prompt('Target (URL/Host)?') || '';
        const type = prompt('Typ (http/ping/tcp/custom)?') || 'http';
        const description = prompt('Beschreibung?') || '';
        const res = await fetch('/api/statuspage/service', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ guildId: currentGuild, service: { name, target, type, description } })
        });
        if (res.ok) {
          await loadStatuspage();
        } else {
          showToast('Service konnte nicht angelegt werden', true);
        }
      }

      async function deleteService(id) {
        if (!currentGuild || !id) return;
        const res = await fetch('/api/statuspage/service/' + encodeURIComponent(id), {
          method: 'DELETE',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ guildId: currentGuild })
        });
        if (res.ok) {
          await loadStatuspage();
        } else {
          showToast('Service löschen fehlgeschlagen', true);
        }
      }

      async function loadAdminOverview() {
        if (!isAdmin) return;
        const res = await fetch('/api/admin/overview');
        if (!res.ok) return;
        const data = await res.json();
        const ov = data.overview || {};
        if (adminGuilds) adminGuilds.textContent = ov.guildCount ?? '-';
        if (adminActiveGuilds) adminActiveGuilds.textContent = ov.activeGuilds24 ?? '-';
        if (adminUptime) adminUptime.textContent = typeof ov.uptimeMs === 'number' ? formatDuration(ov.uptimeMs) : '-';
        if (adminStart) adminStart.textContent = ov.startTime ? formatDate(ov.startTime) : '-';
      }

      async function loadAdminActivity() {
        if (!isAdmin || !adminActivity) return;
        const res = await fetch('/api/admin/activity');
        if (!res.ok) return;
        const data = await res.json();
        const points = (data.points || []).slice(-24);
        adminActivity.innerHTML = '';
        const max = Math.max(...points.map((p) => p.count || 0), 1);
        points.forEach((p) => {
          const bar = document.createElement('div');
          bar.className = 'activity-bar';
          const height = Math.max(6, Math.round((p.count / max) * 120));
          bar.style.height = height + 'px';
          const label = document.createElement('span');
          const d = new Date(p.hour);
          label.textContent = d.getHours().toString().padStart(2, '0') + ':00';
          bar.appendChild(label);
          adminActivity.appendChild(bar);
        });
        if (!points.length) adminActivity.innerHTML = '<div class="muted">Keine Daten</div>';
      }

      async function loadAdminLogs() {
        if (!isAdmin || !adminLogs) return;
        const res = await fetch('/api/admin/logs');
        if (!res.ok) return;
        const data = await res.json();
        const logs = data.logs || [];
        adminLogs.innerHTML = '';
        logs.forEach((l) => {
          const li = document.createElement('li');
          li.className = 'log-item';
          const level = document.createElement('span');
          const lvl = (l.level || 'info').toString().toLowerCase();
          level.className = 'log-level ' + lvl;
          level.textContent = (l.level || '').toUpperCase();
          const body = document.createElement('div');
          body.style.flex = '1';
          const time = document.createElement('div');
          time.className = 'muted';
          time.textContent = formatDate(l.timestamp || Date.now());
          const msg = document.createElement('div');
          msg.textContent = l.message || '';
          body.appendChild(time);
          body.appendChild(msg);
          li.appendChild(level);
          li.appendChild(body);
          adminLogs.appendChild(li);
        });
        if (!logs.length) adminLogs.innerHTML = '<li class="muted">Keine Logs</li>';
      }

      async function loadAdminAll() {
        await Promise.all([loadAdminOverview(), loadAdminActivity(), loadAdminLogs()]);
      }

      function updateWelcomePreview() {
        if (welcomePreview.color) welcomePreview.color.style.background = '#' + (welcomeColor?.value || 'f97316').replace('#','');
        if (welcomePreview.title) welcomePreview.title.textContent = welcomeTitle?.value || 'Willkommen!';
        if (welcomePreview.desc) welcomePreview.desc.textContent = welcomeDescription?.value || 'Schoen, dass du da bist.';
        if (welcomePreview.footer) welcomePreview.footer.textContent = welcomeFooter?.value || '';
        const imgSrc = welcomeImageData || welcomeImage?.value || '';
        if (welcomePreview.image) {
          if (imgSrc) {
            welcomePreview.image.src = imgSrc;
            welcomePreview.image.style.display = 'block';
          } else {
            welcomePreview.image.style.display = 'none';
          }
        }
      }

      function readFileToDataUrl(input, cb) {
        const file = input?.files?.[0];
        if (!file) return cb('');
        const reader = new FileReader();
        reader.onload = () => cb(typeof reader.result === 'string' ? reader.result : '');
        reader.readAsDataURL(file);
      }

      function formatDate(value) {
        if (!value) return '-';
        const dt = new Date(value);
        return isNaN(dt.getTime()) ? '-' : dt.toLocaleString('de-DE');
      }

      function showModal(el) {
        if (!el) return;
        activeModal = el;
        modalBackdrop.classList.add('show');
        el.classList.add('show');
      }

      function hideModal() {
        if (activeModal) activeModal.classList.remove('show');
        modalBackdrop.classList.remove('show');
        activeModal = null;
      }

      function statusClass(status) {
        const key = String(status || 'open').toLowerCase().replace(/\\s+/g, '-');
        if (key === 'in-progress') return 'status-in-progress';
        if (key === 'closed') return 'status-closed';
        return 'status-open';
      }

      function renderTickets() {
        if (!ticketListPane) return;
        ticketListPane.innerHTML = '';
        if (!ticketCache.length) {
          ticketListPane.innerHTML = '<div class="ticket-empty">Keine Tickets vorhanden.</div>';
          return;
        }
        ticketCache.forEach((t) => {
          const item = document.createElement('div');
          item.className = 'ticket-list-item';
          const stat = document.createElement('span');
          stat.className = 'ticket-status-badge ' + statusClass(t.status);
          stat.textContent = t.status || 'open';
          const top = document.createElement('div');
          top.className = 'ticket-item-top';
          const title = document.createElement('div');
          title.className = 'ticket-title';
          title.textContent = t.topic || 'Ticket';
          top.appendChild(title);
          top.appendChild(stat);
          const meta = document.createElement('div');
          meta.className = 'ticket-meta';
          meta.innerHTML =
            '<span>#' + (t.id || t.channelId || '-') + '</span>' +
            '<span>Prio: ' + (t.priority || 'normal') + '</span>' +
            '<span>' + formatDate(t.createdAt) + '</span>';
          item.appendChild(top);
          item.appendChild(meta);
          item.addEventListener('click', () => openTicketDetail(t));
          ticketListPane.appendChild(item);
        });
      }

      function openTicketDetail(ticket) {
        selectedTicket = ticket;
        const creator = ticket.userTag || ticket.userName || ticket.userId || '-';
        document.getElementById('detailTitle').textContent = ticket.topic || 'Ticket';
        document.getElementById('detailSubtitle').textContent = 'Ticket Details';
        document.getElementById('detailTicketId').textContent = ticket.id || ticket.channelId || '-';
        document.getElementById('detailStatus').textContent = ticket.status || 'open';
        document.getElementById('detailPriority').textContent = ticket.priority || 'normal';
        document.getElementById('detailCreated').textContent = formatDate(ticket.createdAt);
        document.getElementById('detailCreator').textContent = creator;
        const transcriptRow = document.getElementById('detailTranscriptRow');
        const transcriptLink = document.getElementById('detailTranscript');
        if (ticket.transcript) {
          transcriptRow.style.display = 'block';
          transcriptLink.href = prependBase('/api/tickets/' + ticket.id + '/transcript');
        } else {
          transcriptRow.style.display = 'none';
        }
        showModal(ticketModal);
      }

      async function ensureAuth() {
        const res = await fetch('/api/me');
        if (res.status === 401) { window.location.href = BASE_AUTH + '/discord'; return null; }
        const data = await res.json();
        if (userInfo) userInfo.textContent = data.user ? data.user.username + '#' + data.user.discriminator : '';
        isAdmin = !!data.user?.isAdmin;
        const adminNav = document.querySelector('.nav .admin-link');
        if (adminNav) adminNav.classList.toggle('hidden', !isAdmin);
        applyNavVisibility();
        return data;
      }

      async function loadGuilds() {
        const res = await fetch('/api/guilds');
        if (res.status === 401) { window.location.href = BASE_AUTH + '/discord'; return; }
        const data = await res.json();
        guildSelect.innerHTML = '';
        (data.guilds || []).forEach(g => {
          const opt = document.createElement('option');
          opt.value = g.id;
          opt.textContent = g.name;
          guildSelect.appendChild(opt);
        });
        if (data.guilds?.length) {
          currentGuild = currentGuild || guildSelect.value || data.guilds[0].id;
          guildSelect.value = currentGuild;
          await loadSettings(currentGuild);
          await loadModules();
          await loadOverview();
          await loadTickets();
          await loadPipeline();
          await loadSla();
          await loadAutomations();
          await loadKb();
          await loadAutomodSettings(currentGuild);
          await loadLoggingSettings(currentGuild);
          await loadWelcomeSettings(currentGuild);
        } else {
          statusEl.textContent = 'Keine Guilds verfuegbar. Fuege den Bot zu einer Guild hinzu.';
        }
      }

      async function loadOverview() {
        if (!currentGuild) return;
        const res = await fetch('/api/overview?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        document.getElementById('openCount').textContent = data.tickets?.open ?? '-';
        document.getElementById('ipCount').textContent = data.tickets?.inProgress ?? '-';
        document.getElementById('closedCount').textContent = data.tickets?.closed ?? '-';
        if (musicActiveEl) musicActiveEl.textContent = data.music?.activeGuilds ?? 0;
        await loadGuildInfo();
        await loadGuildActivity();
        await loadGuildLogs();
      }

      async function loadTickets() {
        if (!currentGuild) return;
        const res = await fetch('/api/tickets?guildId=' + encodeURIComponent(currentGuild));
        const data = await res.json();
        ticketCache = data.tickets || [];
        renderTickets();
      }

      async function loadPipeline() {
        if (!currentGuild) return;
        const res = await fetch('/api/tickets/pipeline?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        pipelineCache = data.pipeline || pipelineCache;
        renderPipeline();
      }

      function renderPipeline() {
        const states = [
          { key: 'neu', el: document.getElementById('pipelineNeu') },
          { key: 'in_bearbeitung', el: document.getElementById('pipelineIn') },
          { key: 'warten_auf_user', el: document.getElementById('pipelineWait') },
          { key: 'erledigt', el: document.getElementById('pipelineDone') }
        ];
        states.forEach((s) => {
          if (!s.el) return;
          const list = pipelineCache[s.key] || [];
          if (!list.length) {
            s.el.innerHTML = '<div class=\"ticket-empty\">Keine Tickets.</div>';
            return;
          }
          s.el.innerHTML = '';
          list.forEach((t) => {
            const card = document.createElement('div');
            card.className = 'ticket-list-item';
            card.innerHTML =
              '<div class=\"ticket-item-top\"><div class=\"ticket-title\">' +
              (t.topic || 'Ticket') +
              '</div><div class=\"ticket-status-badge\">' +
              (t.status || '') +
              '</div></div>' +
              '<div class=\"ticket-meta\">Erstellt: ' +
              (t.createdAt ? new Date(t.createdAt).toLocaleString() : '-') +
              '</div>' +
              '<div class=\"ticket-meta\">User: ' +
              (t.userId || '-') +
              (t.claimedBy ? '  Supporter: ' + t.claimedBy : '') +
              '</div>';
            const select = document.createElement('select');
            select.innerHTML =
              '<option value=\"neu\">Neu</option><option value=\"in_bearbeitung\">In Bearbeitung</option><option value=\"warten_auf_user\">Warten auf User</option><option value=\"erledigt\">Erledigt</option>';
            select.value = ['neu', 'in_bearbeitung', 'warten_auf_user', 'erledigt'].includes(t.status) ? t.status : 'neu';
            select.addEventListener('change', async (e) => {
              await fetch('/api/tickets/' + t.id + '/status', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ status: e.target.value })
              });
              await loadPipeline();
              await loadTickets();
            });
            select.style.marginTop = '6px';
            card.appendChild(select);
            s.el.appendChild(card);
          });
        });
      }

      async function loadSla() {
        if (!currentGuild) return;
        const days = document.getElementById('slaRange')?.value || '30';
        const res = await fetch('/api/tickets/sla?guildId=' + encodeURIComponent(currentGuild) + '&days=' + days);
        if (!res.ok) return;
        const data = await res.json();
        slaSupporters = data.supporters || [];
        slaDays = data.days || [];
        renderSla();
      }

      function renderSla() {
        const supBody = document.getElementById('slaSupporterBody');
        const dayBody = document.getElementById('slaDaysBody');
        if (supBody) {
          supBody.innerHTML = '';
          if (!slaSupporters.length) supBody.innerHTML = '<tr><td colspan=\"4\" class=\"muted\">Keine Daten</td></tr>';
          slaSupporters.forEach((s) => {
            const tr = document.createElement('tr');
            tr.innerHTML =
              '<td>' +
              (s.supporterId || '-') +
              '</td><td style=\"text-align:center;\">' +
              (s.tickets ?? '-') +
              '</td><td style=\"text-align:center;\">' +
              formatDuration(s.avgTTC) +
              '</td><td style=\"text-align:center;\">' +
              formatDuration(s.avgTTFR) +
              '</td>';
            supBody.appendChild(tr);
          });
        }
        if (dayBody) {
          dayBody.innerHTML = '';
          if (!slaDays.length) dayBody.innerHTML = '<tr><td colspan=\"4\" class=\"muted\">Keine Daten</td></tr>';
          slaDays.forEach((d) => {
            const tr = document.createElement('tr');
            tr.innerHTML =
              '<td>' +
              (d.date || '-') +
              '</td><td style=\"text-align:center;\">' +
              (d.tickets ?? '-') +
              '</td><td style=\"text-align:center;\">' +
              formatDuration(d.avgTTC) +
              '</td><td style=\"text-align:center;\">' +
              formatDuration(d.avgTTFR) +
              '</td>';
            dayBody.appendChild(tr);
          });
        }
      }

      async function loadAutomations() {
        if (!currentGuild) return;
        const res = await fetch('/api/automations?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        automationCache = data.rules || [];
        renderAutomations();
      }

      function renderAutomations() {
        const list = document.getElementById('automationList');
        if (!list) return;
        list.innerHTML = '';
        if (!automationCache.length) {
          list.innerHTML = '<div class=\"ticket-empty\">Keine Regeln.</div>';
          return;
        }
        automationCache.forEach((r) => {
          const row = document.createElement('div');
          row.className = 'ticket-list-item';
          row.innerHTML =
            '<div class=\"ticket-item-top\"><div class=\"ticket-title\">' +
            (r.name || 'Regel') +
            '</div><div class=\"ticket-status-badge\">' +
            (r.active ? 'aktiv' : 'inaktiv') +
            '</div></div>' +
            '<div class=\"ticket-meta\">Condition: ' +
            JSON.stringify(r.condition || {}) +
            '</div>' +
            '<div class=\"ticket-meta\">Action: ' +
            JSON.stringify(r.action || {}) +
            '</div>';
          const actions = document.createElement('div');
          actions.className = 'row';
          const edit = document.createElement('button');
          edit.className = 'secondary-btn';
          edit.textContent = 'Bearbeiten';
          edit.addEventListener('click', () => fillAutomationForm(r));
          const del = document.createElement('button');
          del.className = 'danger-btn';
          del.textContent = 'Lschen';
          del.addEventListener('click', async () => {
            const res = await fetch('/api/automations/' + r.id, {
              method: 'DELETE',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ guildId: currentGuild })
            });
            showToast(res.ok ? 'Regel gelscht' : 'Lschen fehlgeschlagen', !res.ok);
            if (res.ok) loadAutomations();
          });
          actions.appendChild(edit);
          actions.appendChild(del);
          row.appendChild(actions);
          list.appendChild(row);
        });
      }

      function fillAutomationForm(rule) {
        document.getElementById('automationId').value = rule.id || '';
        document.getElementById('automationName').value = rule.name || '';
        document.getElementById('automationConditionType').value =
          rule.condition?.category ? 'category' : rule.condition?.status ? 'status' : rule.condition?.minHours ? 'age' : 'category';
        document.getElementById('automationConditionValue').value =
          rule.condition?.category || rule.condition?.status || rule.condition?.minHours || '';
        document.getElementById('automationActionType').value =
          rule.action?.type === 'reminder' ? 'reminder' : rule.action?.type === 'flag' ? 'flag' : 'pingRole';
        document.getElementById('automationActionValue').value =
          rule.action?.roleId || rule.action?.message || rule.action?.status || '';
        setSwitch(document.getElementById('automationActive'), rule.active !== false);
      }

      async function loadKb() {
        if (!currentGuild) return;
        const res = await fetch('/api/kb?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        kbCache = data.articles || [];
        renderKb();
      }

      function renderKb() {
        const list = document.getElementById('kbList');
        if (!list) return;
        list.innerHTML = '';
        if (!kbCache.length) {
          list.innerHTML = '<div class=\"ticket-empty\">Keine Artikel.</div>';
          return;
        }
        kbCache.forEach((a) => {
          const row = document.createElement('div');
          row.className = 'ticket-list-item';
          row.innerHTML =
            '<div class=\"ticket-item-top\"><div class=\"ticket-title\">' +
            (a.title || 'Artikel') +
            '</div></div><div class=\"ticket-meta\">Keywords: ' +
            (Array.isArray(a.keywords) ? a.keywords.join(', ') : '') +
            '</div><div class=\"ticket-meta\">' +
            (a.content || '') +
            '</div>';
          const actions = document.createElement('div');
          actions.className = 'row';
          const edit = document.createElement('button');
          edit.className = 'secondary-btn';
          edit.textContent = 'Bearbeiten';
          edit.addEventListener('click', () => fillKbForm(a));
          const del = document.createElement('button');
          del.className = 'danger-btn';
          del.textContent = 'Lschen';
          del.addEventListener('click', async () => {
            const res = await fetch('/api/kb/' + a.id, {
              method: 'DELETE',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({ guildId: currentGuild })
            });
            showToast(res.ok ? 'Artikel gelscht' : 'Lschen fehlgeschlagen', !res.ok);
            if (res.ok) loadKb();
          });
          actions.appendChild(edit);
          actions.appendChild(del);
          row.appendChild(actions);
          list.appendChild(row);
        });
      }

      function fillKbForm(a) {
        document.getElementById('kbId').value = a.id || '';
        document.getElementById('kbTitle').value = a.title || '';
        document.getElementById('kbKeywords').value = Array.isArray(a.keywords) ? a.keywords.join(', ') : '';
        document.getElementById('kbContent').value = a.content || '';
      }

      function parseCategories(raw) {
        const lines = (raw || '').split('\\n').map((l) => l.trim()).filter(Boolean);
        return lines.slice(0, 5).map((line) => {
          const parts = line.split('|').map((s) => (s ? s.trim() : ''));
          const label = parts[0];
          const customId = parts[1];
          const emoji = parts[2] || undefined;
          return { label, customId, emoji };
        }).filter((c) => c.label && c.customId);
      }

      async function createPanel(channelId, title, description, categoriesRaw) {
        const categories = parseCategories(categoriesRaw);
        const res = await fetch('/api/tickets/panel', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ guildId: currentGuild, channelId, title, description, categories }) });
        return res.ok;
      }

      async function loadSettings(guildId) {
        const res = await fetch('/api/settings?guildId=' + encodeURIComponent(guildId));
        if (!res.ok) return;
        const data = await res.json();
        const cfg = data.settings || {};
        document.querySelector('[name="welcomeChannelId"]').value = cfg.welcomeChannelId || '';
        document.querySelector('[name="logChannelId"]').value = cfg.logChannelId || '';
        document.querySelector('[name="supportRoleId"]').value = cfg.supportRoleId || '';
        automodConfigCache = cfg;
        modulesCache['ticketsEnabled'] = cfg.ticketsEnabled !== false;
        modulesCache['automodEnabled'] = cfg.automodEnabled !== false;
        modulesCache['welcomeEnabled'] = (cfg.welcomeConfig?.enabled ?? cfg.automodConfig?.welcomeConfig?.enabled ?? true) !== false;
        modulesCache['dynamicVoiceEnabled'] = cfg.dynamicVoiceEnabled !== false;
        modulesCache['statuspageEnabled'] = cfg.statuspageEnabled !== false && cfg.automodConfig?.statuspageEnabled !== false;
        modulesCache['serverStatsEnabled'] = cfg.serverStatsEnabled === true || cfg.serverStatsConfig?.enabled === true;
        modulesCache['birthdayEnabled'] = cfg.birthdayEnabled !== false && cfg.birthdayConfig?.enabled !== false;
        modulesCache['reactionRolesEnabled'] = cfg.reactionRolesEnabled !== false && cfg.reactionRolesConfig?.enabled !== false;
        modulesCache['eventsEnabled'] = cfg.eventsEnabled !== false;
        dynamicVoiceCache = cfg.dynamicVoiceConfig || {};
        applyNavVisibility();
        await loadAutomodSettings(guildId);
        await loadLoggingSettings(guildId);
        await loadWelcomeSettings(guildId);
        await loadDynamicVoiceSettings(guildId);
        await loadStatuspage();
        await loadBirthday();
        await loadReactionRoles();
        await loadSupportLogin();
        await loadEvents();
      }

      async function loadAutomodSettings(guildId) {
        const res = await fetch('/api/settings?guildId=' + encodeURIComponent(guildId));
        if (!res.ok) return;
        const data = await res.json();
        const cfg = data.settings || {};
        const auto = cfg.automodConfig || {};
        setSwitch(automodToggle, cfg.automodEnabled !== false);
        setSwitch(badWordToggle, auto.badWordFilter ?? false);
        setSwitch(linkFilterToggle, auto.linkFilter ?? auto.deleteLinks ?? false);
        setSwitch(spamFilterToggle, auto.spamFilter ?? auto.spamDetection ?? false);
        setSwitch(capsFilterToggle, auto.capsFilter ?? false);
        if (automodLogChannel) automodLogChannel.value = auto.logChannelId || cfg.logChannelId || '';
        if (automodSensitivity) automodSensitivity.value = auto.sensitivity || 'medium';
        if (automodWhitelist) automodWhitelist.value = (auto.linkWhitelist || []).join(', ');
        if (automodBadwords) automodBadwords.value = (auto.customBadwords || []).join(', ');
        if (automodWhitelistRoles) automodWhitelistRoles.value = (auto.whitelistRoles || []).join(', ');
      }

      async function loadLoggingSettings(guildId) {
        const res = await fetch('/api/settings?guildId=' + encodeURIComponent(guildId));
        if (!res.ok) return;
        const data = await res.json();
        const cfg = data.settings || {};
        const logging = cfg.loggingConfig || cfg.automodConfig?.loggingConfig || {};
        const cats = logging.categories || {};
        setSwitch(logJoinLeave, cats.joinLeave !== false);
        setSwitch(logMsgEdit, cats.messageEdit !== false);
        setSwitch(logMsgDelete, cats.messageDelete !== false);
        setSwitch(logAutomod, cats.automodActions !== false);
        setSwitch(logTickets, cats.ticketActions !== false);
        setSwitch(logMusic, cats.musicEvents !== false);
        setSwitch(logSystem, cats.system !== false);
        if (loggingChannel) loggingChannel.value = logging.logChannelId || cfg.logChannelId || '';
      }

      async function loadWelcomeSettings(guildId) {
        const res = await fetch('/api/settings?guildId=' + encodeURIComponent(guildId));
        if (!res.ok) return;
        const data = await res.json();
        const cfg = data.settings || {};
        const welcome = cfg.welcomeConfig || cfg.automodConfig?.welcomeConfig || {};
        setSwitch(welcomeToggle, welcome.enabled !== false);
        if (welcomeChannel) welcomeChannel.value = welcome.channelId || cfg.welcomeChannelId || '';
        const colorValue = '#' + (welcome.embedColor || 'f97316').replace('#', '');
        if (welcomeColor) welcomeColor.value = colorValue;
        if (welcomeTitle) welcomeTitle.value = welcome.embedTitle || 'Willkommen!';
        if (welcomeFooter) welcomeFooter.value = welcome.embedFooter || '';
        if (welcomeDescription) welcomeDescription.value = welcome.embedDescription || '';
        if (welcomeThumbnail) welcomeThumbnail.value = welcome.embedThumbnail || '';
        if (welcomeImage) welcomeImage.value = welcome.embedImage || '';
        welcomeThumbData = welcome.embedThumbnailData || '';
        welcomeImageData = welcome.embedImageData || '';
        updateWelcomePreview();
      }

      async function loadDynamicVoiceSettings(guildId) {
        const res = await fetch('/api/settings?guildId=' + encodeURIComponent(guildId));
        if (!res.ok) return;
        const data = await res.json();
        const cfg = data.settings || {};
        const dv = cfg.dynamicVoiceConfig || {};
        setSwitch(dynamicVoiceToggle, cfg.dynamicVoiceEnabled !== false);
        if (dynamicVoiceLobby) dynamicVoiceLobby.value = dv.lobbyChannelId || '';
        if (dynamicVoiceCategory) dynamicVoiceCategory.value = dv.categoryId || '';
        if (dynamicVoiceTemplate) dynamicVoiceTemplate.value = dv.template || '{user}s Channel';
        if (dynamicVoiceUserLimit) dynamicVoiceUserLimit.value = dv.userLimit ?? '';
        if (dynamicVoiceBitrate) dynamicVoiceBitrate.value = dv.bitrate ?? '';
      }

      async function loadSupportLogin() {
        if (!currentGuild) return;
        const res = await fetch('/api/tickets/support-login?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        supportLoginCache = data.config || {};
        if (supportLoginChannel) supportLoginChannel.value = supportLoginCache.panelChannelId || '';
        if (supportLoginTitle) supportLoginTitle.value = supportLoginCache.title || '';
        if (supportLoginDescription) supportLoginDescription.value = supportLoginCache.description || '';
        if (supportLoginLabel) supportLoginLabel.value = supportLoginCache.loginLabel || '';
        if (supportLogoutLabel) supportLogoutLabel.value = supportLoginCache.logoutLabel || '';
        setSwitch(supportLoginAuto, supportLoginCache.autoRefresh !== false);
        renderSupportStatus(data.status || {});
      }

      function renderSupportStatus(status) {
        if (supportActiveList) {
          supportActiveList.innerHTML = '';
          const active = status.active || [];
          if (!active.length) supportActiveList.innerHTML = '<div class="muted">Niemand aktiv.</div>';
          active.forEach((s) => {
            const div = document.createElement('div');
            div.className = 'ticket-list-item';
            div.innerHTML = '<div><strong>' + (s.userId || '-') + '</strong></div><div class="muted">Seit: ' + formatDate(s.startedAt || Date.now()) + '</div>';
            supportActiveList.appendChild(div);
          });
        }
        if (supportRecentList) {
          supportRecentList.innerHTML = '';
          const recent = status.recent || [];
          if (!recent.length) supportRecentList.innerHTML = '<div class="muted">Keine Sessions</div>';
          recent.forEach((s) => {
            const div = document.createElement('div');
            div.className = 'ticket-list-item';
            const dur = s.durationSeconds ? Math.round(s.durationSeconds / 60) + 'm' : '-';
            div.innerHTML =
              '<div><strong>' +
              (s.userId || '-') +
              '</strong></div><div class="muted">Ende: ' +
              formatDate(s.endedAt || Date.now()) +
              ' · Dauer: ' +
              dur +
              '</div>';
            supportRecentList.appendChild(div);
          });
        }
      }

      async function saveSupportLogin() {
        if (!currentGuild) return;
        const payload = {
          guildId: currentGuild,
          panelChannelId: supportLoginChannel?.value || '',
          title: supportLoginTitle?.value || '',
          description: supportLoginDescription?.value || '',
          loginLabel: supportLoginLabel?.value || '',
          logoutLabel: supportLogoutLabel?.value || '',
          autoRefresh: getSwitch(supportLoginAuto)
        };
        const res = await fetch('/api/tickets/support-login', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
        if (supportLoginStatus) supportLoginStatus.textContent = res.ok ? 'Gespeichert' : 'Fehler';
        showToast(res.ok ? 'Support-Login gespeichert' : 'Speichern fehlgeschlagen', !res.ok);
        if (res.ok) {
          hideModal();
          await loadSupportLogin();
        }
      }

      async function loadEvents() {
        if (!currentGuild || modulesCache['eventsEnabled'] === false) {
          eventsCache = [];
          if (eventList) eventList.innerHTML = '<div class="muted">Events deaktiviert.</div>';
          return;
        }
        const res = await fetch('/api/events?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        eventsCache = data.events || [];
        renderEvents();
      }

      function renderEvents() {
        if (!eventList) return;
        eventList.innerHTML = '';
        if (!eventsCache.length) {
          eventList.innerHTML = '<div class="ticket-empty">Keine Events</div>';
          return;
        }
        eventsCache.forEach((ev) => {
          const row = document.createElement('div');
          row.className = 'ticket-list-item';
          row.innerHTML =
            '<div class="ticket-item-top"><div class="ticket-title">' +
            (ev.title || 'Event') +
            '</div><span class="ticket-status-badge">' +
            (ev.repeatType || 'none') +
            '</span></div><div class="ticket-meta">Start: ' +
            formatDate(ev.startTime) +
            ' · Channel: ' +
            (ev.channelId || '-') +
            ' · Anmeldungen: ' +
            (ev._count?.signups ?? 0) +
            '</div>';
          const actions = document.createElement('div');
          actions.className = 'row';
          const editBtn = document.createElement('button');
          editBtn.className = 'secondary-btn';
          editBtn.textContent = 'Bearbeiten';
          editBtn.style.padding = '8px 10px';
          editBtn.addEventListener('click', () => fillEventForm(ev));
          const delBtn = document.createElement('button');
          delBtn.className = 'danger-btn';
          delBtn.textContent = 'Loeschen';
          delBtn.style.padding = '8px 10px';
          delBtn.addEventListener('click', () => deleteEvent(ev.id));
          actions.appendChild(editBtn);
          actions.appendChild(delBtn);
          row.appendChild(actions);
          eventList.appendChild(row);
        });
      }

      function fillEventForm(ev) {
        if (eventId) eventId.value = ev.id || '';
        if (eventTitle) eventTitle.value = ev.title || '';
        if (eventDescription) eventDescription.value = ev.description || '';
        if (eventChannel) eventChannel.value = ev.channelId || '';
        const dt = new Date(ev.startTime);
        if (eventDate) eventDate.value = dt.toISOString().slice(0, 10);
        if (eventTime) eventTime.value = dt.toISOString().slice(11, 16);
        if (eventRepeat) eventRepeat.value = ev.repeatType || 'none';
        if (eventWeeklyDays) eventWeeklyDays.value = Array.isArray(ev.repeatConfig?.days) ? ev.repeatConfig.days.join(',') : '';
        if (eventMonthlyDay) eventMonthlyDay.value = ev.repeatConfig?.day || '';
        if (eventReminder) eventReminder.value = ev.reminderOffsetMinutes ?? '';
        if (eventRole) eventRole.value = ev.roleId || '';
        toggleRepeatRows();
        showModal(eventModal);
      }

      function toggleRepeatRows() {
        const val = eventRepeat?.value || 'none';
        if (eventWeeklyRow) eventWeeklyRow.style.display = val === 'weekly' ? 'block' : 'none';
        if (eventMonthlyRow) eventMonthlyRow.style.display = val === 'monthly' ? 'block' : 'none';
      }

      async function saveEvent() {
        if (!currentGuild) return;
        const startIso = (eventDate?.value || '') + 'T' + (eventTime?.value || '00:00');
        const payload = {
          id: eventId?.value || undefined,
          guildId: currentGuild,
          title: eventTitle?.value || '',
          description: eventDescription?.value || '',
          channelId: eventChannel?.value || '',
          startTime: startIso,
          repeatType: eventRepeat?.value || 'none',
          repeatConfig: {
            days: (eventWeeklyDays?.value || '')
              .split(',')
              .map((s) => Number(s.trim()))
              .filter((n) => !isNaN(n)),
            day: eventMonthlyDay?.value ? Number(eventMonthlyDay.value) : undefined
          },
          reminderOffsetMinutes: eventReminder?.value ? Number(eventReminder.value) : 60,
          roleId: eventRole?.value || undefined
        };
        const res = await fetch('/api/events', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
        if (eventStatus) eventStatus.textContent = res.ok ? 'Gespeichert' : 'Fehler';
        showToast(res.ok ? 'Event gespeichert' : 'Event speichern fehlgeschlagen', !res.ok);
        if (res.ok) {
          hideModal();
          await loadEvents();
        }
      }

      async function deleteEvent(id) {
        if (!currentGuild) return;
        const res = await fetch('/api/events/' + id, { method:'DELETE', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ guildId: currentGuild }) });
        showToast(res.ok ? 'Event geloescht' : 'Event loeschen fehlgeschlagen', !res.ok);
        if (res.ok) loadEvents();
      }

      async function loadBirthday() {
        if (!currentGuild) return;
        const res = await fetch('/api/birthday?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        birthdayCache = data || {};
        const cfg = data.config || {};
        setSwitch(birthdayToggle, cfg.enabled !== false);
        if (birthdayChannel) birthdayChannel.value = cfg.channelId || '';
        if (birthdayHour) birthdayHour.value = cfg.sendHour ?? '';
        if (birthdayTemplate) birthdayTemplate.value = cfg.messageTemplate || 'Alles Gute zum Geburtstag, {user}!';
        renderBirthdays();
      }

      function renderBirthdays() {
        if (!birthdayList) return;
        const entries = birthdayCache.birthdays || [];
        birthdayList.innerHTML = '';
        if (!entries.length) {
          birthdayList.innerHTML = '<div class="muted">Keine Geburtstage hinterlegt.</div>';
          return;
        }
        entries.forEach((b) => {
          const row = document.createElement('div');
          row.className = 'module-item';
          const meta = document.createElement('div');
          meta.className = 'module-meta';
          const date = (b.birthDate || '').replace(/^--/, '');
          meta.innerHTML = '<div class="module-title">' + (date || '-') + '</div><div class="module-desc">User: ' + b.userId + '</div>';
          row.appendChild(meta);
          birthdayList.appendChild(row);
        });
      }

      async function saveBirthdayConfig() {
        if (!currentGuild) return;
        const payload = {
          guildId: currentGuild,
          enabled: getSwitch(birthdayToggle),
          channelId: birthdayChannel?.value || '',
          sendHour: birthdayHour?.value,
          messageTemplate: birthdayTemplate?.value
        };
        const res = await fetch('/api/birthday', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
        if (birthdayStatus) birthdayStatus.textContent = res.ok ? 'Gespeichert' : 'Fehler';
        showToast(res.ok ? 'Birthday gespeichert' : 'Birthday Fehler', !res.ok);
        if (res.ok) await loadBirthday();
      }

      function parseReactionRoleEntries(raw) {
        return (raw || '')
          .split('\\n')
          .map((l) => l.trim())
          .filter(Boolean)
          .map((line) => {
            const parts = line.split('|').map((p) => p.trim());
            return { emoji: parts[0], roleId: parts[1], label: parts[2] || undefined, description: parts[3] || undefined };
          })
          .filter((e) => e.emoji && e.roleId);
      }

      function resetReactionRoleForm() {
        editingReactionRole = null;
        if (reactionRoleId) reactionRoleId.value = '';
        if (reactionRoleChannel) reactionRoleChannel.value = '';
        if (reactionRoleMessageId) reactionRoleMessageId.value = '';
        if (reactionRoleTitle) reactionRoleTitle.value = '';
        if (reactionRoleDescription) reactionRoleDescription.value = '';
        if (reactionRoleEntries) reactionRoleEntries.value = '';
        if (reactionRoleStatus) reactionRoleStatus.textContent = '';
      }

      function resetEventForm() {
        if (eventId) eventId.value = '';
        if (eventTitle) eventTitle.value = '';
        if (eventDescription) eventDescription.value = '';
        if (eventChannel) eventChannel.value = '';
        if (eventDate) eventDate.value = '';
        if (eventTime) eventTime.value = '';
        if (eventRepeat) eventRepeat.value = 'none';
        if (eventWeeklyDays) eventWeeklyDays.value = '';
        if (eventMonthlyDay) eventMonthlyDay.value = '';
        if (eventReminder) eventReminder.value = '120';
        if (eventRole) eventRole.value = '';
        if (eventStatus) eventStatus.textContent = '';
        toggleRepeatRows();
      }

      function fillReactionRoleForm(set) {
        editingReactionRole = set.id;
        if (reactionRoleId) reactionRoleId.value = set.id || '';
        if (reactionRoleChannel) reactionRoleChannel.value = set.channelId || '';
        if (reactionRoleMessageId) reactionRoleMessageId.value = set.messageId || '';
        if (reactionRoleTitle) reactionRoleTitle.value = set.title || '';
        if (reactionRoleDescription) reactionRoleDescription.value = set.description || '';
        if (reactionRoleEntries) {
          const lines = (set.entries || []).map((e) => [e.emoji, e.roleId, e.label || '', e.description || ''].join(' | '));
          reactionRoleEntries.value = lines.join('\\n');
        }
        if (reactionRoleStatus) reactionRoleStatus.textContent = 'Bearbeitung aktiv';
      }

      async function loadReactionRoles() {
        if (!currentGuild) return;
        resetReactionRoleForm();
        if (modulesCache['reactionRolesEnabled'] === false) {
          reactionRoleCache = [];
          if (reactionRoleList) reactionRoleList.innerHTML = '<div class="muted">Modul deaktiviert.</div>';
          return;
        }
        const res = await fetch('/api/reactionroles?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        reactionRoleCache = data.sets || [];
        renderReactionRoleSets();
      }

      function renderReactionRoleSets() {
        if (!reactionRoleList) return;
        reactionRoleList.innerHTML = '';
        if (!reactionRoleCache.length) {
          reactionRoleList.innerHTML = '<div class="muted">Keine Reaction Roles angelegt.</div>';
          return;
        }
        reactionRoleCache.forEach((set) => {
          const row = document.createElement('div');
          row.className = 'module-item';
          const meta = document.createElement('div');
          meta.className = 'module-meta';
          const descParts = ['Channel: ' + (set.channelId || '-')];
          if (set.messageId) descParts.push('Message: ' + set.messageId);
          meta.innerHTML = '<div class="module-title">' + (set.title || 'Reaction Role') + '</div><div class="module-desc">' + descParts.join(' • ') + '</div>';
          const actions = document.createElement('div');
          actions.className = 'row';
          const editBtn = document.createElement('button');
          editBtn.className = 'secondary-btn';
          editBtn.style.padding = '8px 10px';
          editBtn.style.fontSize = '12px';
          editBtn.textContent = 'Bearbeiten';
          editBtn.addEventListener('click', () => fillReactionRoleForm(set));
          const syncBtn = document.createElement('button');
          syncBtn.className = 'secondary-btn';
          syncBtn.style.padding = '8px 10px';
          syncBtn.style.fontSize = '12px';
          syncBtn.textContent = 'Sync';
          syncBtn.addEventListener('click', () => syncReactionRole(set.id));
          const delBtn = document.createElement('button');
          delBtn.className = 'danger-btn';
          delBtn.style.padding = '8px 10px';
          delBtn.style.fontSize = '12px';
          delBtn.textContent = 'Loeschen';
          delBtn.addEventListener('click', () => deleteReactionRole(set.id));
          actions.appendChild(editBtn);
          actions.appendChild(syncBtn);
          actions.appendChild(delBtn);
          row.appendChild(meta);
          row.appendChild(actions);
          reactionRoleList.appendChild(row);
        });
      }

      async function syncReactionRole(id) {
        const set = reactionRoleCache.find((s) => s.id === id);
        if (!set) return;
        const payload = {
          guildId: currentGuild,
          channelId: set.channelId,
          messageId: set.messageId,
          title: set.title,
          description: set.description,
          entries: set.entries || []
        };
        const res = await fetch('/api/reactionroles/' + id, { method:'PUT', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
        showToast(res.ok ? 'Reaction Role aktualisiert' : 'Sync fehlgeschlagen', !res.ok);
        if (res.ok) loadReactionRoles();
      }

      async function deleteReactionRole(id) {
        if (!currentGuild) return;
        const res = await fetch('/api/reactionroles/' + id, { method:'DELETE', headers:{'Content-Type':'application/json'}, body: JSON.stringify({ guildId: currentGuild }) });
        showToast(res.ok ? 'Geloescht' : 'Fehler beim Loeschen', !res.ok);
        if (res.ok) {
          if (editingReactionRole === id) resetReactionRoleForm();
          loadReactionRoles();
        }
      }

      // TODO: MODULE: Liste um Musik/Forum/Automod-Konfiguration ergaenzen.
      //  - Module-Status inkl. Direktlinks zu Detailseiten (Automod/Welcome/Musik) rendern.
      //  - Module-Flags aus BotModuleService spiegeln statt doppeltem Fetch.
      async function loadModules() {
        if (!currentGuild) return;
        const res = await fetch('/api/modules?guildId=' + encodeURIComponent(currentGuild));
        if (!res.ok) return;
        const data = await res.json();
        const list = document.getElementById('moduleList');
        list.innerHTML = '';
        let ticketsActive = false;
        let statuspageActive = false;
        let serverStatsActive = false;
        let birthdayActive = false;
        let reactionRolesActive = false;
        let eventsActive = false;
        (data.modules || []).forEach((m) => {
          modulesCache[m.key] = !!m.enabled;
          const row = document.createElement('div');
          row.className = 'module-item';
          const meta = document.createElement('div');
          meta.className = 'module-meta';
          meta.innerHTML = '<div class="module-title">' + m.name + '</div><div class="module-desc">' + (m.description || '') + '</div>';
          const toggle = document.createElement('div');
          toggle.className = 'toggle' + (m.enabled ? ' active' : '');
          toggle.dataset.key = m.key;
          toggle.addEventListener('click', async () => {
            const willEnable = !toggle.classList.contains('active');
            const ok = await saveModuleToggle(m.key, willEnable);
            if (ok) {
              toggle.classList.toggle('active', willEnable);
              showToast(willEnable ? m.name + ' aktiviert' : m.name + ' deaktiviert');
              modulesCache[m.key] = willEnable;
              if (m.key === 'ticketsEnabled') applyTicketsVisibility(willEnable);
              if (m.key === 'automodEnabled') modulesCache['automodEnabled'] = willEnable;
              if (m.key === 'welcomeEnabled') modulesCache['welcomeEnabled'] = willEnable;
              if (m.key === 'statuspageEnabled') modulesCache['statuspageEnabled'] = willEnable;
              if (m.key === 'serverStatsEnabled') modulesCache['serverStatsEnabled'] = willEnable;
              if (m.key === 'birthdayEnabled') modulesCache['birthdayEnabled'] = willEnable;
              if (m.key === 'reactionRolesEnabled') modulesCache['reactionRolesEnabled'] = willEnable;
              if (m.key === 'eventsEnabled') modulesCache['eventsEnabled'] = willEnable;
              applyNavVisibility();
            } else {
              showToast('Speichern fehlgeschlagen', true);
            }
          });
          row.appendChild(meta);
          row.appendChild(toggle);
          list.appendChild(row);
          if (m.key === 'ticketsEnabled' && m.enabled) ticketsActive = true;
          if (m.key === 'automodEnabled') modulesCache['automodEnabled'] = !!m.enabled;
          if (m.key === 'welcomeEnabled') modulesCache['welcomeEnabled'] = !!m.enabled;
          if (m.key === 'dynamicVoiceEnabled') modulesCache['dynamicVoiceEnabled'] = !!m.enabled;
          if (m.key === 'statuspageEnabled') statuspageActive = !!m.enabled;
          if (m.key === 'serverStatsEnabled') serverStatsActive = !!m.enabled;
          if (m.key === 'birthdayEnabled') birthdayActive = !!m.enabled;
          if (m.key === 'reactionRolesEnabled') reactionRolesActive = !!m.enabled;
          if (m.key === 'eventsEnabled') eventsActive = !!m.enabled;
        });
        applyNavVisibility();
        applyTicketsVisibility(ticketsActive);
        if (statuspageActive) loadStatuspage();
        if (serverStatsActive) loadServerStats();
        if (birthdayActive) loadBirthday();
        if (reactionRolesActive) loadReactionRoles();
        if (eventsActive) loadEvents();
      }

      async function saveModuleToggle(key, enabled) {
        if (!currentGuild) return false;
        const payload = { guildId: currentGuild };
        ['ticketsEnabled', 'automodEnabled', 'welcomeEnabled', 'musicEnabled', 'levelingEnabled', 'statuspageEnabled', 'serverStatsEnabled', 'birthdayEnabled', 'reactionRolesEnabled', 'eventsEnabled'].forEach((k) => {
          if (modulesCache[k] !== undefined) payload[k] = modulesCache[k];
        });
        payload['dynamicVoiceEnabled'] = modulesCache['dynamicVoiceEnabled'];
        payload[key] = enabled;
        const res = await fetch('/api/settings', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
        return res.ok;
      }

      function applyTicketsVisibility(active) {
        const ticketsNav = document.querySelector('.nav a[data-target="tickets"]');
        const ticketsSection = document.querySelector('.section[data-section="tickets"]');
        if (ticketsNav && ticketsSection) {
          ticketsNav.classList.toggle('hidden', !active);
          ticketsSection.classList.toggle('hidden', !active);
          if (!active && location.hash.replace('#','') === 'tickets') {
            activateSection('overview');
            history.replaceState(null, '', '#overview');
          }
        }
      }

      document.getElementById('settingsForm').addEventListener('submit', async (e) => {
        e.preventDefault();
        if (!currentGuild) return;
        const form = new FormData(e.currentTarget);
        const payload = Object.fromEntries(form.entries());
        payload.supportRoleId = payload.supportRoleId || undefined;
        payload.guildId = currentGuild;
        const res = await fetch('/api/settings', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
        document.getElementById('saveStatus').textContent = res.ok ? 'Gespeichert' : 'Fehler';
        if (res.ok) {
          await loadSettings(currentGuild);
          await loadModules();
        }
      });

      document.getElementById('openPanelModal').addEventListener('click', () => {
        document.getElementById('panelStatus').textContent = '';
        showModal(panelModal);
      });

      if (openSupportLogin) openSupportLogin.addEventListener('click', () => { showModal(supportLoginModal); });
      if (supportLoginSave) supportLoginSave.addEventListener('click', saveSupportLogin);
      if (refreshSupportStatus) refreshSupportStatus.addEventListener('click', loadSupportLogin);

      document.getElementById('panelSubmit').addEventListener('click', async () => {
        if (!currentGuild) return;
        const form = new FormData(document.getElementById('panelForm'));
        const channelId = form.get('channelId');
        const panelTitle = form.get('panelTitle');
        const panelDescription = form.get('panelDescription');
        const panelCategories = form.get('panelCategories');
        const status = document.getElementById('panelStatus');
        const ok = await createPanel(channelId, panelTitle, panelDescription, panelCategories);
        if (status) status.textContent = ok ? 'Panel gesendet' : 'Fehler beim Senden';
        showToast(ok ? 'Ticket-Panel gesendet' : 'Ticket-Panel Fehler', !ok);
        if (ok) hideModal();
      });

      document.querySelectorAll('[data-close-modal]').forEach((btn) => btn.addEventListener('click', hideModal));
      modalBackdrop.addEventListener('click', hideModal);

      document.getElementById('closeTicketAction').addEventListener('click', async () => {
        if (!selectedTicket) return;
        const res = await fetch('/api/tickets/' + selectedTicket.id + '/close', { method: 'POST' });
        showToast(res.ok ? 'Ticket geschlossen' : 'Ticket schliessen fehlgeschlagen', !res.ok);
        if (res.ok) {
          hideModal();
          await loadTickets();
        }
      });

      guildSelect.addEventListener('change', async (e) => {
        currentGuild = e.target.value;
        await loadSettings(currentGuild);
        await loadOverview();
        await loadTickets();
        await loadPipeline();
        await loadSla();
        await loadAutomations();
        await loadKb();
        await loadModules();
        await loadStatuspage();
      });

      navLinks.forEach((link) => {
        link.addEventListener('click', (e) => {
          e.preventDefault();
          const target = link.dataset.target || 'overview';
          activateSection(target);
          history.replaceState(null, '', '#' + target);
          if (target === 'admin' && isAdmin) loadAdminAll();
        });
      });

      document.querySelectorAll('.ticket-tab-btn').forEach((btn) => {
        btn.addEventListener('click', async () => {
          document.querySelectorAll('.ticket-tab-btn').forEach((b) => b.classList.remove('active'));
          btn.classList.add('active');
          const tab = btn.dataset.tab;
          document.querySelectorAll('.ticket-tab').forEach((t) => t.classList.remove('active'));
          const target = document.getElementById('ticketTab' + (tab ? tab.charAt(0).toUpperCase() + tab.slice(1) : ''));
          if (target) target.classList.add('active');
          if (tab === 'pipeline') await loadPipeline();
          if (tab === 'sla') await loadSla();
          if (tab === 'automations') await loadAutomations();
          if (tab === 'kb') await loadKb();
        });
      });

      const slaRange = document.getElementById('slaRange');
      if (slaRange) slaRange.addEventListener('change', loadSla);

      const automationForm = document.getElementById('automationForm');
      if (automationForm) {
        automationForm.addEventListener('submit', async (e) => {
          e.preventDefault();
          if (!currentGuild) return;
          const id = document.getElementById('automationId')?.value || '';
          const name = document.getElementById('automationName')?.value || '';
          const condType = document.getElementById('automationConditionType')?.value;
          const condVal = document.getElementById('automationConditionValue')?.value;
          const actionType = document.getElementById('automationActionType')?.value;
          const actionVal = document.getElementById('automationActionValue')?.value;
          const active = getSwitch(document.getElementById('automationActive'));
          const condition = {};
          if (condType === 'category') condition.category = condVal;
          if (condType === 'status') condition.status = condVal;
          if (condType === 'age') condition.minHours = Number(condVal || 0);
          const action = { type: actionType };
          if (actionType === 'pingRole') action.roleId = actionVal;
          if (actionType === 'reminder') action.message = actionVal;
          if (actionType === 'flag') action.status = actionVal;
          const payload = { guildId: currentGuild, name, condition, action, active };
          const url = id ? '/api/automations/' + id : '/api/automations';
          const method = id ? 'PUT' : 'POST';
          const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) });
          showToast(res.ok ? 'Regel gespeichert' : 'Fehler', !res.ok);
          if (res.ok) {
            document.getElementById('automationId').value = '';
            automationForm.reset();
            setSwitch(document.getElementById('automationActive'), true);
            await loadAutomations();
          }
        });
      }
      const automationReset = document.getElementById('automationReset');
      if (automationReset) automationReset.addEventListener('click', () => {
        document.getElementById('automationId').value = '';
        if (automationForm) automationForm.reset();
        setSwitch(document.getElementById('automationActive'), true);
      });
      const addAutomation = document.getElementById('addAutomation');
      if (addAutomation) addAutomation.addEventListener('click', () => {
        document.getElementById('automationId').value = '';
        if (automationForm) automationForm.reset();
        setSwitch(document.getElementById('automationActive'), true);
      });

      const kbForm = document.getElementById('kbForm');
      if (kbForm) {
        kbForm.addEventListener('submit', async (e) => {
          e.preventDefault();
          if (!currentGuild) return;
          const id = document.getElementById('kbId')?.value || '';
          const title = document.getElementById('kbTitle')?.value || '';
          const keywords = document.getElementById('kbKeywords')?.value || '';
          const content = document.getElementById('kbContent')?.value || '';
          const payload = { guildId: currentGuild, title, keywords, content };
          const url = id ? '/api/kb/' + id : '/api/kb';
          const method = id ? 'PUT' : 'POST';
          const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) });
          showToast(res.ok ? 'Artikel gespeichert' : 'Fehler', !res.ok);
          if (res.ok) {
            document.getElementById('kbId').value = '';
            kbForm.reset();
            await loadKb();
          }
        });
      }
      const kbReset = document.getElementById('kbReset');
      if (kbReset) kbReset.addEventListener('click', () => {
        document.getElementById('kbId').value = '';
        if (kbForm) kbForm.reset();
      });
      const addKb = document.getElementById('addKb');
      if (addKb) addKb.addEventListener('click', () => {
        document.getElementById('kbId').value = '';
        if (kbForm) kbForm.reset();
      });

      document.getElementById('logoutBtn').addEventListener('click', () => window.location.href = BASE_AUTH + '/logout');

      [automodToggle, badWordToggle, linkFilterToggle, spamFilterToggle, capsFilterToggle, logJoinLeave, logMsgEdit, logMsgDelete, logAutomod, logTickets, logMusic, dynamicVoiceToggle, supportLoginAuto].forEach((el) => {
        if (el) el.addEventListener('click', () => el.classList.toggle('on'));
      });
      if (logSystem) logSystem.addEventListener('click', () => logSystem.classList.toggle('on'));
      if (welcomeToggle) welcomeToggle.addEventListener('click', () => welcomeToggle.classList.toggle('on'));
      if (birthdayToggle) birthdayToggle.addEventListener('click', () => birthdayToggle.classList.toggle('on'));
      if (statuspageToggle) statuspageToggle.addEventListener('click', async () => { statuspageToggle.classList.toggle('on'); await saveStatuspageConfig(); });
      if (statuspageInterval) statuspageInterval.addEventListener('change', saveStatuspageConfig);
      if (statuspageChannel) statuspageChannel.addEventListener('change', saveStatuspageConfig);
      if (statuspageAddService) statuspageAddService.addEventListener('click', addServicePrompt);
      if (statsToggle) statsToggle.addEventListener('click', async () => { statsToggle.classList.toggle('on'); await saveServerStats(); });
      if (statsCategoryName) statsCategoryName.addEventListener('change', saveServerStats);
      if (statsRefresh) statsRefresh.addEventListener('change', saveServerStats);
      if (statsAddItem) statsAddItem.addEventListener('click', () => editServerStat(null));
      [welcomeTitle, welcomeDescription, welcomeFooter, welcomeColor].forEach((el) => {
        if (el) el.addEventListener('input', updateWelcomePreview);
      });
      if (welcomeThumbnailFile) welcomeThumbnailFile.addEventListener('change', () => readFileToDataUrl(welcomeThumbnailFile, (data) => { welcomeThumbData = data; }));
      if (welcomeImageFile) welcomeImageFile.addEventListener('change', () => readFileToDataUrl(welcomeImageFile, (data) => { welcomeImageData = data; updateWelcomePreview(); }));
      if (welcomeImage) welcomeImage.addEventListener('input', updateWelcomePreview);
      if (birthdaySave) birthdaySave.addEventListener('click', saveBirthdayConfig);
      if (reactionRoleReset) reactionRoleReset.addEventListener('click', (e) => { e.preventDefault(); resetReactionRoleForm(); });
      if (reactionRoleForm) reactionRoleForm.addEventListener('submit', async (e) => {
        e.preventDefault();
        if (!currentGuild) return;
        const entries = parseReactionRoleEntries(reactionRoleEntries?.value || '');
        if (!reactionRoleChannel?.value) {
          if (reactionRoleStatus) reactionRoleStatus.textContent = 'Channel erforderlich';
          return;
        }
        if (!entries.length) {
          if (reactionRoleStatus) reactionRoleStatus.textContent = 'Mindestens ein Eintrag erforderlich';
          return;
        }
        const payload = {
          guildId: currentGuild,
          channelId: (reactionRoleChannel?.value || '').trim(),
          messageId: reactionRoleMessageId?.value ? reactionRoleMessageId.value.trim() : undefined,
          title: reactionRoleTitle?.value?.trim() || undefined,
          description: reactionRoleDescription?.value?.trim() || undefined,
          entries
        };
        const url = editingReactionRole ? '/api/reactionroles/' + editingReactionRole : '/api/reactionroles';
        const method = editingReactionRole ? 'PUT' : 'POST';
        const res = await fetch(url, { method, headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
        if (reactionRoleStatus) reactionRoleStatus.textContent = res.ok ? 'Gespeichert' : 'Fehler';
        showToast(res.ok ? 'Reaction Role gespeichert' : 'Speichern fehlgeschlagen', !res.ok);
        if (res.ok) {
          resetReactionRoleForm();
          await loadReactionRoles();
        }
      });

      if (openEventModal) openEventModal.addEventListener('click', () => { resetEventForm(); showModal(eventModal); });
      if (eventRepeat) eventRepeat.addEventListener('change', toggleRepeatRows);
      if (eventSave) eventSave.addEventListener('click', saveEvent);
      if (dynamicVoiceToggle) dynamicVoiceToggle.addEventListener('click', () => dynamicVoiceToggle.classList.toggle('on'));

      document.getElementById('dynamicVoiceForm')?.addEventListener('submit', async (e) => {
        e.preventDefault();
        if (!currentGuild) return;
        const payload = {
          guildId: currentGuild,
          dynamicVoiceEnabled: getSwitch(dynamicVoiceToggle),
          dynamicVoiceConfig: {
            lobbyChannelId: dynamicVoiceLobby?.value || undefined,
            categoryId: dynamicVoiceCategory?.value || undefined,
            template: dynamicVoiceTemplate?.value || undefined,
            userLimit: dynamicVoiceUserLimit?.value ? Number(dynamicVoiceUserLimit.value) : undefined,
            bitrate: dynamicVoiceBitrate?.value ? Number(dynamicVoiceBitrate.value) : undefined
          }
        };
        const res = await fetch('/api/settings', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
        if (dynamicVoiceStatus) dynamicVoiceStatus.textContent = res.ok ? 'Gespeichert' : 'Fehler beim Speichern';
        showToast(res.ok ? 'Dynamic Voice gespeichert' : 'Dynamic Voice Fehler', !res.ok);
        if (res.ok) await loadDynamicVoiceSettings(currentGuild);
      });

      if (automodForm) {
        automodForm.addEventListener('submit', async (e) => {
          e.preventDefault();
          if (!currentGuild) return;
          const config = {
            badWordFilter: getSwitch(badWordToggle),
            linkFilter: getSwitch(linkFilterToggle),
            spamFilter: getSwitch(spamFilterToggle),
            capsFilter: getSwitch(capsFilterToggle),
            logChannelId: automodLogChannel?.value || undefined,
            sensitivity: automodSensitivity?.value || 'medium',
            linkWhitelist: (automodWhitelist?.value || '')
              .split(',')
              .map((s) => s.trim())
              .filter(Boolean),
            customBadwords: parseList(automodBadwords?.value),
            whitelistRoles: parseList(automodWhitelistRoles?.value)
          };
          const payload = {
            guildId: currentGuild,
            automodEnabled: getSwitch(automodToggle),
            automodConfig: config
          };
          const res = await fetch('/api/settings', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
          if (automodStatus) automodStatus.textContent = res.ok ? 'Gespeichert' : 'Fehler beim Speichern';
          showToast(res.ok ? 'Automod gespeichert' : 'Automod Fehler', !res.ok);
          if (res.ok) await loadAutomodSettings(currentGuild);
        });
      }

      document.getElementById('loggingSave')?.addEventListener('click', async () => {
        if (!currentGuild) return;
        const payload = {
          guildId: currentGuild,
          loggingConfig: {
            logChannelId: loggingChannel?.value || undefined,
            categories: {
              joinLeave: getSwitch(logJoinLeave),
              messageEdit: getSwitch(logMsgEdit),
              messageDelete: getSwitch(logMsgDelete),
              automodActions: getSwitch(logAutomod),
              ticketActions: getSwitch(logTickets),
              musicEvents: getSwitch(logMusic),
              system: getSwitch(logSystem)
            }
          }
        };
        const res = await fetch('/api/settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) });
        if (loggingStatus) loggingStatus.textContent = res.ok ? 'Logging gespeichert' : 'Fehler beim Speichern';
        showToast(res.ok ? 'Logging gespeichert' : 'Logging Fehler', !res.ok);
        if (res.ok) await loadLoggingSettings(currentGuild);
      });

      if (welcomeForm) {
        welcomeForm.addEventListener('submit', async (e) => {
          e.preventDefault();
          if (!currentGuild) return;
          const payload = {
            guildId: currentGuild,
            welcomeConfig: {
              enabled: getSwitch(welcomeToggle),
              channelId: welcomeChannel?.value || undefined,
              embedTitle: welcomeTitle?.value || undefined,
              embedDescription: welcomeDescription?.value || undefined,
              embedColor: (welcomeColor?.value || '').replace('#', ''),
              embedFooter: welcomeFooter?.value || undefined,
              embedThumbnail: welcomeThumbnail?.value || undefined,
              embedImage: welcomeImage?.value || undefined,
              embedThumbnailData: welcomeThumbData || undefined,
              embedImageData: welcomeImageData || undefined
            },
            welcomeEnabled: getSwitch(welcomeToggle)
          };
          const res = await fetch('/api/settings', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(payload) });
          if (welcomeStatus) welcomeStatus.textContent = res.ok ? 'Gespeichert' : 'Fehler beim Speichern';
          showToast(res.ok ? 'Welcome gespeichert' : 'Welcome Fehler', !res.ok);
          if (res.ok) await loadWelcomeSettings(currentGuild);
        });
      }

      const initialSection = location.hash.replace('#', '') || 'overview';
      activateSection(initialSection);

      ensureAuth().then(() => {
        loadGuilds();
        if (initialSection === 'admin' && isAdmin) loadAdminAll();
      });
      setInterval(loadOverview, 10000);
      setInterval(loadTickets, 12000);
      setInterval(() => { if (isAdmin) loadAdminAll(); }, 20000);
    </script>
  </body>
  </html>
  `);
});

router.get('/settings', (_req, res) => {
  res.json({ settings: [] });
});

export default router;


