#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import os
import time
import urllib.parse
import mimetypes
import re
import traceback
import sys
import signal
import socket
import threading

# Konfiguration
PORT = 8081
UPLOAD_DIR = "uploads"
SERVER_ADDRESS = "77.90.60.235"  # Ändern Sie diese zu Ihrer Server-IP
ADMIN_USERNAME = "admin"
ADMIN_PASSWORD = "0911"  # Ändern Sie dies zu Ihrem gewünschten Passwort
UPLOAD_PASSWORD = "0911"  # Passwort für den Upload-Bereich
LOG_FILE = "server.log"
BANNER_PATH = "/uploads/Vantastic_Banner.png"  # Pfad zum Banner relativ zur Webroot

# Caching-Konfiguration
FILE_CACHE_TIMEOUT = 60  # Dateiliste-Cache in Sekunden
file_list_cache = {"timestamp": 0, "data": []}
file_list_lock = threading.Lock()

# Stellen Sie sicher, dass das Upload-Verzeichnis existiert
if not os.path.exists(UPLOAD_DIR):
    os.makedirs(UPLOAD_DIR)

# Logging-Funktion
def log_message(message, level="INFO"):
    timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
    log_entry = f"[{timestamp}] [{level}] {message}\n"
    
    print(log_entry, end="")
    
    try:
        with open(LOG_FILE, "a") as log_file:
            log_file.write(log_entry)
    except Exception as e:
        print(f"Fehler beim Schreiben ins Log-File: {str(e)}")

# Signal-Handler für ordnungsgemäßes Herunterfahren
def signal_handler(sig, frame):
    log_message("Server wird heruntergefahren...", "INFO")
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)

class FileServerHandler(BaseHTTPRequestHandler):
    # Errorhandling für Verbindungsabbrüche
    def handle(self):
        try:
            super().handle()
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler bei der Verbindungsbehandlung: {str(e)}", "ERROR")
            traceback.print_exc()
    
    def log_message(self, format, *args):
        """Verbesserte Protokollierung"""
        client_address = self.address_string()
        log_message(f"{client_address} - {format % args}", "INFO")
    
    def send_html_response(self, content, status=200):
        """Sendet eine HTML-Antwort"""
        try:
            self.send_response(status)
            self.send_header('Content-Type', 'text/html; charset=utf-8')
            
            # Prüfen, ob der Client Komprimierung unterstützt
            accept_encoding = self.headers.get('Accept-Encoding', '')
            if 'gzip' in accept_encoding:
                import gzip
                content_bytes = content.encode('utf-8')
                compressed_content = gzip.compress(content_bytes)
                
                self.send_header('Content-Encoding', 'gzip')
                self.send_header('Content-Length', str(len(compressed_content)))
                self.end_headers()
                self.wfile.write(compressed_content)
            else:
                self.end_headers()
                self.wfile.write(content.encode('utf-8'))
                
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen beim Senden der HTML-Antwort: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler beim Senden der HTML-Antwort: {str(e)}", "ERROR")
    
    def send_json_response(self, data, status=200):
        """Sendet eine JSON-Antwort"""
        try:
            self.send_response(status)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps(data).encode('utf-8'))
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen beim Senden der JSON-Antwort: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler beim Senden der JSON-Antwort: {str(e)}", "ERROR")
    
    def send_error_response(self, message, status=500):
        """Sendet eine Fehlerantwort"""
        try:
            self.send_response(status)
            self.send_header('Content-Type', 'text/html; charset=utf-8')
            self.end_headers()
            error_page = f"""
            <!DOCTYPE html>
            <html lang="de">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>Fehler</title>
                <link rel="preconnect" href="https://fonts.googleapis.com">
                <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
                <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
                <style>
                    :root {{
                        --primary-color: #1E3A8A;
                        --primary-light: #2563EB;
                        --accent-color: #0EA5E9;
                        --text-color: #1E293B;
                        --light-text: #64748B;
                        --bg-color: #F8FAFC;
                        --white: #FFFFFF;
                        --danger-color: #EF4444;
                        --danger-light: #FEE2E2;
                    }}
                    
                    body {{
                        font-family: 'Inter', sans-serif;
                        line-height: 1.6;
                        background-color: var(--bg-color);
                        color: var(--text-color);
                        margin: 0;
                        padding: 20px;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                    }}
                    
                    .error-container {{
                        background-color: var(--white);
                        border-radius: 12px;
                        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
                        padding: 2rem;
                        max-width: 500px;
                        width: 100%;
                        text-align: center;
                    }}
                    
                    .error-icon {{
                        font-size: 3rem;
                        color: var(--danger-color);
                        margin-bottom: 1rem;
                    }}
                    
                    h1 {{
                        color: var(--primary-color);
                        font-size: 1.5rem;
                        margin-bottom: 1rem;
                    }}
                    
                    .error-message {{
                        background-color: var(--danger-light);
                        color: var(--danger-color);
                        padding: 1rem;
                        border-radius: 8px;
                        margin-bottom: 1.5rem;
                    }}
                    
                    .back-link {{
                        display: inline-block;
                        background-color: var(--primary-color);
                        color: var(--white);
                        text-decoration: none;
                        padding: 0.75rem 1.5rem;
                        border-radius: 8px;
                        font-weight: 500;
                        transition: all 0.3s ease;
                    }}
                    
                    .back-link:hover {{
                        background-color: var(--primary-light);
                        transform: translateY(-2px);
                        box-shadow: 0 4px 12px rgba(30, 58, 138, 0.3);
                    }}
                </style>
            </head>
            <body>
                <div class="error-container">
                    <div class="error-icon">⚠️</div>
                    <h1>Ein Fehler ist aufgetreten</h1>
                    <div class="error-message">
                        <p>{message}</p>
                    </div>
                    <a href="/" class="back-link">Zurück zur Startseite</a>
                </div>
            </body>
            </html>
            """
            self.wfile.write(error_page.encode('utf-8'))
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen beim Senden der Fehlerantwort: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler beim Senden der Fehlerantwort: {str(e)}", "ERROR")
    
    def check_admin_auth(self):
        """Überprüft, ob der Benutzer authentifiziert ist"""
        auth_header = self.headers.get('Authorization')
        if not auth_header:
            return False
        
        try:
            auth_type, auth_string = auth_header.split(' ', 1)
            if auth_type.lower() != 'basic':
                return False
            
            import base64
            decoded = base64.b64decode(auth_string).decode('utf-8')
            username, password = decoded.split(':', 1)
            
            return username == ADMIN_USERNAME and password == ADMIN_PASSWORD
        except Exception:
            return False
    
    def request_admin_auth(self):
        """Fordert Authentifizierung an"""
        try:
            self.send_response(401)
            self.send_header('WWW-Authenticate', 'Basic realm="Admin-Bereich"')
            self.send_header('Content-Type', 'text/html; charset=utf-8')
            self.end_headers()
            
            auth_page = """
            <!DOCTYPE html>
            <html lang="de">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>Authentifizierung erforderlich</title>
                <link rel="preconnect" href="https://fonts.googleapis.com">
                <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
                <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
                <style>
                    :root {
                        --primary-color: #1E3A8A;
                        --primary-light: #2563EB;
                        --accent-color: #0EA5E9;
                        --text-color: #1E293B;
                        --light-text: #64748B;
                        --bg-color: #F8FAFC;
                        --white: #FFFFFF;
                        --info-color: #3B82F6;
                        --info-light: #EFF6FF;
                    }
                    
                    body {
                        font-family: 'Inter', sans-serif;
                        line-height: 1.6;
                        background-color: var(--bg-color);
                        color: var(--text-color);
                        margin: 0;
                        padding: 20px;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                    }
                    
                    .auth-container {
                        background-color: var(--white);
                        border-radius: 12px;
                        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
                        padding: 2rem;
                        max-width: 500px;
                        width: 100%;
                        text-align: center;
                    }
                    
                    .auth-icon {
                        font-size: 3rem;
                        color: var(--info-color);
                        margin-bottom: 1rem;
                    }
                    
                    h1 {
                        color: var(--primary-color);
                        font-size: 1.5rem;
                        margin-bottom: 1rem;
                    }
                    
                    .auth-message {
                        background-color: var(--info-light);
                        color: var(--info-color);
                        padding: 1rem;
                        border-radius: 8px;
                        margin-bottom: 1.5rem;
                    }
                    
                    .back-link {
                        display: inline-block;
                        background-color: var(--primary-color);
                        color: var(--white);
                        text-decoration: none;
                        padding: 0.75rem 1.5rem;
                        border-radius: 8px;
                        font-weight: 500;
                        transition: all 0.3s ease;
                    }
                    
                    .back-link:hover {
                        background-color: var(--primary-light);
                        transform: translateY(-2px);
                        box-shadow: 0 4px 12px rgba(30, 58, 138, 0.3);
                    }
                </style>
            </head>
            <body>
                <div class="auth-container">
                    <div class="auth-icon">🔒</div>
                    <h1>Authentifizierung erforderlich</h1>
                    <div class="auth-message">
                        <p>Bitte geben Sie Ihren Benutzernamen und Passwort ein, um auf den Admin-Bereich zuzugreifen.</p>
                    </div>
                    <a href="/" class="back-link">Zurück zur Startseite</a>
                </div>
            </body>
            </html>
            """
            self.wfile.write(auth_page.encode('utf-8'))
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen beim Anfordern der Admin-Auth: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler beim Anfordern der Admin-Auth: {str(e)}", "ERROR")
    
    def generate_main_page(self):
        """Generiert die modernisierte Hauptseite"""
        banner_url = f"http://{SERVER_ADDRESS}{BANNER_PATH}"
        current_year = time.strftime('%Y')
        
        return f"""
        <!DOCTYPE html>
        <html lang="de">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Vantastic Uploads</title>
            <link rel="preconnect" href="https://fonts.googleapis.com">
            <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
            <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
            <style>
                :root {{
                    /* Haupt-Farbpalette */
                    --primary-color: #1E3A8A;
                    --primary-light: #2563EB;
                    --primary-dark: #1E40AF;
                    --accent-color: #0EA5E9;
                    --accent-light: #38BDF8;
                    --accent-dark: #0284C7;
                    
                    /* Text und Hintergrund */
                    --text-color: #1E293B;
                    --text-muted: #64748B;
                    --text-light: #94A3B8;
                    --bg-color: #F8FAFC;
                    --bg-card: #FFFFFF;
                    --bg-hover: #F1F5F9;
                    
                    /* Status-Farben */
                    --success-color: #10B981;
                    --success-light: #D1FAE5;
                    --warning-color: #F59E0B;
                    --warning-light: #FEF3C7;
                    --danger-color: #EF4444;
                    --danger-light: #FEE2E2;
                    
                    /* Abstände */
                    --space-xs: 0.25rem;
                    --space-sm: 0.5rem;
                    --space-md: 1rem;
                    --space-lg: 1.5rem;
                    --space-xl: 2rem;
                    --space-2xl: 3rem;
                    
                    /* Schatten */
                    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
                    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
                    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
                    
                    /* Rahmen */
                    --border-radius-sm: 0.375rem;
                    --border-radius-md: 0.5rem;
                    --border-radius-lg: 0.75rem;
                    --border-color: #E2E8F0;
                }}
                
                * {{
                    margin: 0;
                    padding: 0;
                    box-sizing: border-box;
                }}
                
                body {{
                    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
                    font-size: 16px;
                    line-height: 1.6;
                    color: var(--text-color);
                    background-color: var(--bg-color);
                    -webkit-font-smoothing: antialiased;
                    -moz-osx-font-smoothing: grayscale;
                }}
                
                .container {{
                    max-width: 1200px;
                    margin: 0 auto;
                    padding: var(--space-lg);
                }}
                
                /* Header-Bereich */
                .header {{
                    background-color: var(--bg-card);
                    box-shadow: var(--shadow-md);
                    padding: var(--space-lg) 0;
                    position: relative;
                    top: 0;
                    z-index: 10;
                }}
                
                .header .container {{
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    padding-top: var(--space-md);
                    padding-bottom: var(--space-md);
                }}
                
                .header-banner {{
                    width: 100%;            /* Volle Breite erzwingen */
    		    max-width: 1200px;      /* Maximale Breite begrenzen */
    		    height: auto;           /* Höhe proportional anpassen */
   		    min-height: 120px;      /* Minimale Höhe festlegen */
   		    max-height: 200px;      /* Maximale Höhe begrenzen */
    		    object-fit: contain;    /* Gesamtes Bild anzeigen, proportional */
    		    margin: 0 auto;         /* Zentrieren */
                }}
                
                /* Bedienleiste */
                .toolbar {{
                    background-color: var(--bg-card);
                    border-radius: var(--border-radius-lg);
                    box-shadow: var(--shadow-sm);
                    padding: var(--space-lg);
                    margin-bottom: var(--space-xl);
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    flex-wrap: wrap;
                    gap: var(--space-md);
                }}
                
                /* Schaltflächen */
                .btn {{
                    display: inline-flex;
                    align-items: center;
                    justify-content: center;
                    gap: var(--space-sm);
                    padding: var(--space-sm) var(--space-lg);
                    border-radius: var(--border-radius-md);
                    font-weight: 500;
                    font-size: 1rem;
                    cursor: pointer;
                    transition: all 0.3s ease;
                    border: none;
                    outline: none;
                    text-decoration: none;
                    white-space: nowrap;
                }}
                
                .btn-primary {{
                    background-color: var(--primary-color);
                    color: white;
                }}
                
                .btn-primary:hover, .btn-primary:focus {{
                    background-color: var(--primary-dark);
                    box-shadow: 0 4px 12px rgba(30, 58, 138, 0.3);
                    transform: translateY(-2px);
                }}
                
                .btn-accent {{
                    background-color: var(--accent-color);
                    color: white;
                }}
                
                .btn-accent:hover, .btn-accent:focus {{
                    background-color: var(--accent-dark);
                    box-shadow: 0 4px 12px rgba(14, 165, 233, 0.3);
                    transform: translateY(-2px);
                }}
                
                .btn-outline {{
                    background-color: transparent;
                    color: var(--primary-color);
                    border: 1px solid var(--primary-color);
                }}
                
                .btn-outline:hover, .btn-outline:focus {{
                    background-color: var(--primary-color);
                    color: white;
                    transform: translateY(-2px);
                }}
                
                .btn-danger {{
                    background-color: var(--danger-color);
                    color: white;
                }}
                
                .btn-danger:hover, .btn-danger:focus {{
                    background-color: #dc2626;
                    box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
                    transform: translateY(-2px);
                }}
                
                .btn-lg {{
                    padding: var(--space-md) var(--space-xl);
                    font-size: 1.125rem;
                }}
                
                .btn-fab {{
                    position: fixed;
                    bottom: 2rem;
                    right: 2rem;
                    width: 60px;
                    height: 60px;
                    border-radius: 50%;
                    background-color: var(--accent-color);
                    color: white;
                    font-size: 1.5rem;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    box-shadow: var(--shadow-lg);
                    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
                    z-index: 100;
                }}
                
                .btn-fab:hover, .btn-fab:focus {{
                    background-color: var(--accent-dark);
                    box-shadow: 0 6px 18px rgba(14, 165, 233, 0.35);
                    transform: translateY(-4px) scale(1.05);
                }}
                
                /* Upload-Bereich */
                .upload-section {{
                    background-color: var(--bg-card);
                    border-radius: var(--border-radius-lg);
                    box-shadow: var(--shadow-md);
                    padding: var(--space-xl);
                    margin-bottom: var(--space-2xl);
                }}
                
                .section-title {{
                    color: var(--primary-color);
                    font-size: 1.5rem;
                    font-weight: 600;
                    margin-bottom: var(--space-lg);
                    position: relative;
                    padding-bottom: var(--space-sm);
                }}
                
                .section-title::after {{
                    content: '';
                    position: absolute;
                    bottom: 0;
                    left: 0;
                    width: 50px;
                    height: 3px;
                    background-color: var(--accent-color);
                    border-radius: 3px;
                }}
                
                .drop-area {{
                    border: 2px dashed var(--accent-light);
                    border-radius: var(--border-radius-lg);
                    padding: var(--space-2xl);
                    text-align: center;
                    color: var(--text-muted);
                    background-color: rgba(14, 165, 233, 0.05);
                    transition: all 0.3s ease;
                    position: relative;
                    overflow: hidden;
                }}
                
                .drop-area:hover, .drop-area.highlight {{
                    background-color: rgba(14, 165, 233, 0.1);
                    border-color: var(--accent-color);
                    cursor: pointer;
                }}
                
                .drop-icon {{
                    font-size: 2.5rem;
                    color: var(--accent-color);
                    margin-bottom: var(--space-md);
                }}
                
                .drop-text {{
                    font-size: 1.125rem;
                    margin-bottom: var(--space-lg);
                }}
                
                .drop-hint {{
                    font-size: 0.875rem;
                    color: var(--text-light);
                }}
                
                .file-input {{
                    display: none;
                }}
                
                .file-info {{
                    margin-top: var(--space-lg);
                    padding: var(--space-lg);
                    background-color: var(--bg-hover);
                    border-radius: var(--border-radius-md);
                    display: none;
                }}
                
                .file-info-title {{
                    font-weight: 600;
                    margin-bottom: var(--space-sm);
                }}
                
                .file-item-preview {{
                    display: flex;
                    align-items: center;
                    padding: var(--space-sm) 0;
                }}
                
                .file-item-icon {{
                    margin-right: var(--space-md);
                    color: var(--accent-color);
                    font-size: 1.25rem;
                }}
                
                .file-item-name {{
                    flex-grow: 1;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                }}
                
                .file-item-size {{
                    color: var(--text-muted);
                    font-size: 0.875rem;
                    white-space: nowrap;
                    margin-left: var(--space-md);
                }}
                
                .upload-progress {{
                    height: 8px;
                    width: 100%;
                    background-color: var(--bg-hover);
                    border-radius: var(--border-radius-sm);
                    overflow: hidden;
                    margin-top: var(--space-lg);
                    display: none;
                }}
                
                .progress-bar {{
                    height: 100%;
                    background-color: var(--accent-color);
                    width: 0%;
                    transition: width 0.2s ease;
                }}
                
                /* Benachrichtigungen */
                .alert {{
                    padding: var(--space-lg);
                    border-radius: var(--border-radius-md);
                    margin-bottom: var(--space-lg);
                    font-weight: 500;
                    display: flex;
                    align-items: center;
                    gap: var(--space-md);
                    opacity: 0;
                    transform: translateY(-10px);
                    transition: all 0.3s ease;
                    position: fixed;
                    top: var(--space-lg);
                    right: var(--space-lg);
                    z-index: 1000;
                    max-width: 400px;
                    box-shadow: var(--shadow-lg);
                }}
                
                .alert.show {{
                    opacity: 1;
                    transform: translateY(0);
                }}
                
                .alert-success {{
                    background-color: var(--success-light);
                    color: var(--success-color);
                }}
                
                .alert-error {{
                    background-color: var(--danger-light);
                    color: var(--danger-color);
                }}
                
                .alert-icon {{
                    font-size: 1.25rem;
                }}
                
                .alert-close {{
                    margin-left: auto;
                    cursor: pointer;
                    opacity: 0.7;
                    transition: opacity 0.2s ease;
                }}
                
                .alert-close:hover {{
                    opacity: 1;
                }}
                
                /* Dateianzeige */
                .view-options {{
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-bottom: var(--space-lg);
                }}
                
                .view-selector {{
                    display: flex;
                    background-color: var(--bg-hover);
                    border-radius: var(--border-radius-md);
                    overflow: hidden;
                    padding: var(--space-xs);
                }}
                
                .view-selector button {{
                    background: none;
                    border: none;
                    outline: none;
                    padding: var(--space-sm) var(--space-md);
                    cursor: pointer;
                    transition: all 0.2s ease;
                    border-radius: var(--border-radius-sm);
                    font-size: 0.875rem;
                    color: var(--text-muted);
                }}
                
                .view-selector button.active {{
                    background-color: var(--bg-card);
                    color: var(--primary-color);
                    box-shadow: var(--shadow-sm);
                }}
                
                .view-selector button:hover:not(.active) {{
                    color: var(--text-color);
                }}
                
                .refresh-btn {{
                    background: none;
                    border: none;
                    outline: none;
                    color: var(--primary-color);
                    font-size: 1rem;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    display: flex;
                    align-items: center;
                    gap: var(--space-sm);
                }}
                
                .refresh-btn:hover {{
                    color: var(--primary-dark);
                    transform: translateY(-2px);
                }}
                
                /* Spinner für Laden */
                .loading {{
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    padding: var(--space-2xl);
                }}
                
                .spinner {{
                    width: 40px;
                    height: 40px;
                    border: 3px solid rgba(14, 165, 233, 0.2);
                    border-radius: 50%;
                    border-top-color: var(--accent-color);
                    animation: spinner 1s linear infinite;
                }}
                
                @keyframes spinner {{
                    to {{ transform: rotate(360deg); }}
                }}
                
                /* Dateiliste */
                .files-container {{
                    margin-bottom: var(--space-2xl);
                }}
                
                /* Grid-Ansicht */
                .files-grid {{
                    display: grid;
                    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
                    gap: var(--space-lg);
                }}
                
                .file-card {{
                    background-color: var(--bg-card);
                    border-radius: var(--border-radius-lg);
                    box-shadow: var(--shadow-sm);
                    overflow: hidden;
                    transition: all 0.3s ease;
                    position: relative;
                }}
                
                .file-card:hover {{
                    transform: translateY(-4px);
                    box-shadow: var(--shadow-md);
                }}
                
                .file-card-preview {{
                    height: 160px;
                    background-color: var(--bg-hover);
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    overflow: hidden;
                    position: relative;
                }}
                
                .file-card-preview img {{
                    max-width: 100%;
                    max-height: 100%;
                    object-fit: contain;
                }}
                
                .file-card-icon {{
                    font-size: 3rem;
                    color: var(--accent-color);
                }}
                
                .file-card-content {{
                    padding: var(--space-lg);
                }}
                
                .file-card-name {{
                    font-weight: 600;
                    margin-bottom: var(--space-sm);
                    display: -webkit-box;
                    -webkit-line-clamp: 2;
                    -webkit-box-orient: vertical;
                    overflow: hidden;
                    word-break: break-word;
                }}
                
                .file-card-meta {{
                    color: var(--text-muted);
                    font-size: 0.875rem;
                    margin-bottom: var(--space-md);
                }}
                
                .file-card-actions {{
                    display: flex;
                    justify-content: space-between;
                    margin-top: var(--space-md);
                }}
                
                .action-btn {{
                    background-color: var(--bg-hover);
                    color: var(--text-color);
                    border: none;
                    padding: var(--space-sm) var(--space-md);
                    border-radius: var(--border-radius-md);
                    font-size: 0.875rem;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    display: flex;
                    align-items: center;
                    gap: var(--space-xs);
                }}
                
                .action-btn:hover {{
                    background-color: var(--primary-color);
                    color: white;
                }}
                
                .action-btn.view-btn:hover {{
                    background-color: var(--accent-color);
                }}
                
                .file-card-overlay {{
                    position: absolute;
                    top: 0;
                    left: 0;
                    right: 0;
                    bottom: 0;
                    background-color: rgba(30, 58, 138, 0.8);
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: var(--space-md);
                    opacity: 0;
                    transition: opacity 0.3s ease;
                }}
                
                .file-card:hover .file-card-overlay {{
                    opacity: 1;
                }}
                
                .overlay-btn {{
                    background-color: white;
                    color: var(--primary-color);
                    border: none;
                    width: 40px;
                    height: 40px;
                    border-radius: 50%;
                    font-size: 1rem;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }}
                
                .overlay-btn:hover {{
                    background-color: var(--accent-color);
                    color: white;
                    transform: scale(1.1);
                }}
                
                /* Listenansicht */
                .files-list {{
                    display: none;
                }}
                
                .file-row {{
                    background-color: var(--bg-card);
                    border-radius: var(--border-radius-md);
                    padding: var(--space-md) var(--space-lg);
                    margin-bottom: var(--space-md);
                    box-shadow: var(--shadow-sm);
                    display: flex;
                    align-items: center;
                    transition: all 0.2s ease;
                }}
                
                .file-row:hover {{
                    background-color: var(--bg-hover);
                    transform: translateX(4px);
                }}
                
                .file-row-icon {{
                    flex: 0 0 40px;
                    font-size: 1.5rem;
                    color: var(--accent-color);
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }}
                
                .file-row-content {{
                    flex: 1;
                    min-width: 0;
                    padding: 0 var(--space-lg);
                }}
                
                .file-row-name {{
                    font-weight: 500;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                }}
                
                .file-row-meta {{
                    color: var(--text-muted);
                    font-size: 0.875rem;
                }}
                
                .file-row-actions {{
                    display: flex;
                    gap: var(--space-sm);
                }}
                
                /* Keine Dateien Zustand */
                .empty-state {{
                    text-align: center;
                    padding: var(--space-2xl);
                    color: var(--text-muted);
                }}
                
                .empty-icon {{
                    font-size: 3rem;
                    color: var(--accent-light);
                    margin-bottom: var(--space-lg);
                }}
                
                .empty-title {{
                    font-size: 1.25rem;
                    margin-bottom: var(--space-md);
                }}
                
                .empty-message {{
                    margin-bottom: var(--space-lg);
                }}
                
                /* Paginierung */
                .pagination {{
                    display: flex;
                    justify-content: center;
                    gap: var(--space-sm);
                    margin-top: var(--space-xl);
                }}
                
                .pagination-btn {{
                    width: 40px;
                    height: 40px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    border-radius: var(--border-radius-md);
                    transition: all 0.2s ease;
                    cursor: pointer;
                    font-weight: 500;
                    border: 1px solid var(--border-color);
                    background-color: var(--bg-card);
                }}
                
                .pagination-btn.active {{
                    background-color: var(--primary-color);
                    color: white;
                    border-color: var(--primary-color);
                }}
                
                .pagination-btn:hover:not(.active):not(.disabled) {{
                    background-color: var(--bg-hover);
                    border-color: var(--primary-light);
                }}
                
                .pagination-btn.disabled {{
                    opacity: 0.5;
                    cursor: not-allowed;
                }}
                
                /* Modal-Fenster */
                .modal {{
                    display: none;
                    position: fixed;
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100%;
                    background-color: rgba(15, 23, 42, 0.8);
                    z-index: 1000;
                    padding: var(--space-md);
                    overflow-y: auto;
                }}
                
                .modal-content {{
                    background-color: var(--bg-card);
                    border-radius: var(--border-radius-lg);
                    box-shadow: var(--shadow-lg);
                    width: 100%;
                    max-width: 800px;
                    margin: 5vh auto;
                    animation: modalEnter 0.3s ease;
                    overflow: hidden;
                    display: flex;
                    flex-direction: column;
                    max-height: 90vh;
                }}
                
                @keyframes modalEnter {{
                    from {{ opacity: 0; transform: scale(0.9); }}
                    to {{ opacity: 1; transform: scale(1); }}
                }}
                
                .modal-header {{
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    padding: var(--space-lg);
                    border-bottom: 1px solid var(--border-color);
                }}
                
                .modal-title {{
                    font-weight: 600;
                    color: var(--primary-color);
                    font-size: 1.25rem;
                }}
                
                .modal-close {{
                    background: none;
                    border: none;
                    font-size: 1.5rem;
                    color: var(--text-muted);
                    cursor: pointer;
                    transition: color 0.2s ease;
                }}
                
                .modal-close:hover {{
                    color: var(--danger-color);
                }}
                
                .modal-body {{
                    padding: var(--space-lg);
                    overflow-y: auto;
                    flex: 1;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                }}
                
                .modal-body img {{
                    max-width: 100%;
                    max-height: 70vh;
                    object-fit: contain;
                }}
                
                .modal-body video,
                .modal-body audio {{
                    width: 100%;
                }}
                
                .modal-footer {{
                    padding: var(--space-lg);
                    border-top: 1px solid var(--border-color);
                    display: flex;
                    justify-content: flex-end;
                    gap: var(--space-md);
                }}
                
                /* Password-Modal */
                .password-modal-content {{
                    max-width: 400px;
                    text-align: center;
                }}
                
                .password-form {{
                    margin-bottom: var(--space-lg);
                }}
                
                .form-group {{
                    margin-bottom: var(--space-md);
                }}
                
                .form-input {{
                    width: 100%;
                    padding: var(--space-md);
                    border: 1px solid var(--border-color);
                    border-radius: var(--border-radius-md);
                    font-size: 1rem;
                    transition: all 0.2s ease;
                }}
                
                .form-input:focus {{
                    border-color: var(--accent-color);
                    box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.2);
                    outline: none;
                }}
                
                .form-error {{
                    color: var(--danger-color);
                    font-size: 0.875rem;
                    margin-top: var(--space-sm);
                    display: none;
                }}
                
                /* Toast (Kopieren) */
                .toast {{
                    position: fixed;
                    left: 50%;
                    transform: translateX(-50%);
                    bottom: var(--space-xl);
                    background-color: var(--primary-color);
                    color: white;
                    padding: var(--space-md) var(--space-xl);
                    border-radius: var(--border-radius-md);
                    box-shadow: var(--shadow-lg);
                    display: flex;
                    align-items: center;
                    gap: var(--space-md);
                    opacity: 0;
                    transition: all 0.3s ease;
                    z-index: 1001;
                }}
                
                .toast.show {{
                    opacity: 1;
                    transform: translate(-50%, -20px);
                }}
                
                /* Footer */
                .footer {{
                    background-color: var(--bg-card);
                    box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.05);
                    padding: var(--space-xl) 0;
                    text-align: center;
                    color: var(--text-muted);
                    margin-top: var(--space-2xl);
                }}
                
                .footer-content {{
                    max-width: 600px;
                    margin: 0 auto;
                }}
                
                /* Responsive Design */
                @media (max-width: 768px) {{
                    .container {{
                        padding: var(--space-md);
                    }}
                    
                    .upload-section, .files-container {{
                        padding: var(--space-lg);
                    }}
                    
                    .files-grid {{
                        grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
                    }}
                    
                    .toolbar {{
                        flex-direction: column;
                        align-items: flex-start;
                    }}
                    
                    .file-row {{
                        flex-direction: column;
                        align-items: flex-start;
                    }}
                    
                    .file-row-icon {{
                        margin-bottom: var(--space-sm);
                    }}
                    
                    .file-row-content {{
                        padding: var(--space-sm) 0;
                        width: 100%;
                    }}
                    
                    .file-row-actions {{
                        width: 100%;
                        justify-content: space-between;
                        margin-top: var(--space-sm);
                    }}
                    
                    .modal-content {{
                        margin: 0;
                        max-height: 100vh;
                        height: 100%;
                        border-radius: 0;
                    }}
                    
                    .btn-fab {{
                        bottom: var(--space-lg);
                        right: var(--space-lg);
                    }}
                }}
            </style>
        </head>
        <body>
            <!-- Header mit Logo -->
            <header class="header">
                <div class="container">
                    <img src="{banner_url}" alt="Vantastic Uploads" class="header-banner">
                </div>
            </header>
            
            <div class="container">
                <!-- Toolbar -->
                <div class="toolbar">
                    <a href="/admin" class="btn btn-primary">
                        <i class="fas fa-cog"></i> Verwaltungsbereich
                    </a>
                </div>
                
                <!-- Upload-Bereich -->
                <section class="upload-section">
                    <h2 class="section-title">Dateien hochladen</h2>
                    
                    <div id="dropArea" class="drop-area">
                        <div class="drop-icon">
                            <i class="fas fa-cloud-upload-alt"></i>
                        </div>
                        <div class="drop-text">Dateien hier hinziehen oder klicken zum Auswählen</div>
                        <div class="drop-hint">Maximale Dateigröße: 1 GB</div>
                        <input type="file" id="fileInput" class="file-input" multiple>
                    </div>
                    
                    <div id="fileInfo" class="file-info">
                        <div class="file-info-title">Ausgewählte Dateien:</div>
                        <div id="fileListPreview"></div>
                        <button id="uploadBtn" class="btn btn-accent btn-lg" style="margin-top: var(--space-lg); width: 100%;">
                            <i class="fas fa-upload"></i> Dateien hochladen
                        </button>
                    </div>
                    
                    <div id="uploadProgress" class="upload-progress">
                        <div id="progressBar" class="progress-bar"></div>
                    </div>
                </section>
                
                <!-- Dateienbereich -->
                <section class="files-container">
                    <div class="view-options">
                        <h2 class="section-title">Verfügbare Dateien</h2>
                        
                        <div class="toolbar-actions">
                            <div class="view-selector">
                                <button id="gridViewBtn" class="active"><i class="fas fa-th"></i> Kacheln</button>
                                <button id="listViewBtn"><i class="fas fa-list"></i> Liste</button>
                            </div>
                        </div>
                        
                        <button id="refreshBtn" class="refresh-btn">
                            <i class="fas fa-sync-alt"></i> Aktualisieren
                        </button>
                    </div>
                    
                    <!-- Ladeanimation -->
                    <div id="loading" class="loading">
                        <div class="spinner"></div>
                    </div>
                    
                    <!-- Grid-Ansicht (Standard) -->
                    <div id="filesGrid" class="files-grid">
                        <!-- Hier werden die Dateikarten dynamisch eingefügt -->
                    </div>
                    
                    <!-- Listenansicht (Alternative) -->
                    <div id="filesList" class="files-list">
                        <!-- Hier werden die Dateilisteneinträge dynamisch eingefügt -->
                    </div>
                    
                    <!-- Paginierung -->
                    <div id="pagination" class="pagination"></div>
                </section>
            </div>
            
            <!-- Erfolgsmeldung Toast -->
            <div id="successAlert" class="alert alert-success">
                <div class="alert-icon"><i class="fas fa-check-circle"></i></div>
                <div class="alert-message">Datei erfolgreich hochgeladen!</div>
                <div class="alert-close"><i class="fas fa-times"></i></div>
            </div>
            
            <!-- Fehlermeldung Toast -->
            <div id="errorAlert" class="alert alert-error">
                <div class="alert-icon"><i class="fas fa-exclamation-circle"></i></div>
                <div class="alert-message">Fehler beim Hochladen der Datei.</div>
                <div class="alert-close"><i class="fas fa-times"></i></div>
            </div>
            
            <!-- Toast Benachrichtigung (Kopieren) -->
            <div id="copyToast" class="toast">
                <i class="fas fa-check-circle"></i>
                <span>Link in Zwischenablage kopiert!</span>
            </div>
            
            <!-- Schwebender Upload-Button (FAB) -->
            <button id="fabUploadBtn" class="btn-fab">
                <i class="fas fa-plus"></i>
            </button>
            
            <!-- Modal-Fenster für Dateivorschau -->
            <div id="fileViewerModal" class="modal">
                <div class="modal-content">
                    <div class="modal-header">
                        <h3 id="modalTitle" class="modal-title">Dateiname</h3>
                        <button class="modal-close" onclick="closeModal()">×</button>
                    </div>
                    <div id="modalBody" class="modal-body">
                        <!-- Hier wird der Inhalt dynamisch eingefügt -->
                    </div>
                    <div class="modal-footer">
                        <a id="modalDownloadLink" href="#" class="btn btn-accent">
                            <i class="fas fa-download"></i> Herunterladen
                        </a>
                    </div>
                </div>
            </div>
            
            <!-- Passwort-Modal für Upload -->
            <div id="uploadPasswordModal" class="modal">
                <div class="modal-content password-modal-content">
                    <div class="modal-header">
                        <h3 class="modal-title">Passwort erforderlich</h3>
                        <button class="modal-close" onclick="closePasswordModal()">×</button>
                    </div>
                    <div class="modal-body">
                        <div class="password-form">
                            <p style="margin-bottom: var(--space-lg);">Bitte geben Sie das Passwort ein, um Dateien hochzuladen:</p>
                            <div class="form-group">
                                <input type="password" id="uploadPassword" class="form-input" placeholder="Passwort eingeben">
                                <div id="passwordErrorMessage" class="form-error">Falsches Passwort. Bitte versuchen Sie es erneut.</div>
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-outline" onclick="closePasswordModal()">Abbrechen</button>
                        <button class="btn btn-accent" onclick="verifyUploadPassword()">Bestätigen</button>
                    </div>
                </div>
            </div>
            
            <!-- Footer -->
            <footer class="footer">
                <div class="footer-content">
                    <p>&copy; {current_year} Vantastic Uploads. Alle Rechte vorbehalten.</p>
                </div>
            </footer>
            
            <script>
                // DOM-Elemente
                const dropArea = document.getElementById('dropArea');
                const fileInput = document.getElementById('fileInput');
                const fileInfo = document.getElementById('fileInfo');
                const fileListPreview = document.getElementById('fileListPreview');
                const uploadBtn = document.getElementById('uploadBtn');
                const uploadProgress = document.getElementById('uploadProgress');
                const progressBar = document.getElementById('progressBar');
                const loading = document.getElementById('loading');
                const filesGrid = document.getElementById('filesGrid');
                const filesList = document.getElementById('filesList');
                const pagination = document.getElementById('pagination');
                const successAlert = document.getElementById('successAlert');
                const errorAlert = document.getElementById('errorAlert');
                const copyToast = document.getElementById('copyToast');
                const fileViewerModal = document.getElementById('fileViewerModal');
                const modalTitle = document.getElementById('modalTitle');
                const modalBody = document.getElementById('modalBody');
                const modalDownloadLink = document.getElementById('modalDownloadLink');
                const uploadPasswordModal = document.getElementById('uploadPasswordModal');
                const uploadPasswordInput = document.getElementById('uploadPassword');
                const passwordErrorMessage = document.getElementById('passwordErrorMessage');
                const refreshBtn = document.getElementById('refreshBtn');
                const fabUploadBtn = document.getElementById('fabUploadBtn');
                const gridViewBtn = document.getElementById('gridViewBtn');
                const listViewBtn = document.getElementById('listViewBtn');
                
                // Ansichtseinstellung (Grid/Liste)
                let currentView = 'grid';
                
                // Paginierungsvariablen
                let currentPage = 1;
                const filesPerPage = 12;
                let allFiles = [];
                
                // Ansicht umschalten
                gridViewBtn.addEventListener('click', () => {{
                    if (currentView !== 'grid') {{
                        currentView = 'grid';
                        filesGrid.style.display = 'grid';
                        filesList.style.display = 'none';
                        gridViewBtn.classList.add('active');
                        listViewBtn.classList.remove('active');
                        // Lokale Einstellung speichern
                        localStorage.setItem('preferredView', 'grid');
                    }}
                }});
                
                listViewBtn.addEventListener('click', () => {{
                    if (currentView !== 'list') {{
                        currentView = 'list';
                        filesGrid.style.display = 'none';
                        filesList.style.display = 'block';
                        gridViewBtn.classList.remove('active');
                        listViewBtn.classList.add('active');
                        // Lokale Einstellung speichern
                        localStorage.setItem('preferredView', 'list');
                    }}
                }});
                
                // Gespeicherte Ansichtseinstellung laden
                document.addEventListener('DOMContentLoaded', () => {{
                    const savedView = localStorage.getItem('preferredView');
                    if (savedView === 'list') {{
                        listViewBtn.click();
                    }}
                }});
                
                // FAB-Button zum Upload
                fabUploadBtn.addEventListener('click', () => {{
                    // Zum Upload-Bereich scrollen
                    const uploadSection = document.querySelector('.upload-section');
                    uploadSection.scrollIntoView({{ behavior: 'smooth' }});
                    // Nach kurzem Delay das Passwort-Modal öffnen
                    setTimeout(() => {{
                        showUploadPasswordModal();
                    }}, 500);
                }});
                
                // Alert-Schließen-Buttons
                document.querySelectorAll('.alert-close').forEach(closeBtn => {{
                    closeBtn.addEventListener('click', (e) => {{
                        const alert = e.target.closest('.alert');
                        alert.classList.remove('show');
                    }});
                }});
                
                // Benachrichtigung anzeigen
                function showAlert(alert, message) {{
                    const messageEl = alert.querySelector('.alert-message');
                    messageEl.textContent = message;
                    
                    alert.classList.add('show');
                    
                    // Nach 5 Sekunden ausblenden
                    setTimeout(() => {{
                        alert.classList.remove('show');
                    }}, 5000);
                }}
                
                // Passwort-Modal anzeigen
function showUploadPasswordModal() {{
    // Prüfen, ob das Passwort bereits eingegeben wurde
    const passwordVerified = sessionStorage.getItem('passwordVerified');
    
    if (passwordVerified === 'true') {{
        // Wenn das Passwort bereits verifiziert wurde
        if (window.droppedFiles && window.droppedFiles.length > 0) {{
            handleFiles(window.droppedFiles);
            window.droppedFiles = null;
        }} else {{
            fileInput.click();
        }}
        return;
    }}
    
    uploadPasswordModal.style.display = 'block';
    uploadPasswordInput.value = '';
    passwordErrorMessage.style.display = 'none';
    
    // Fokus auf das Password-Feld setzen
    setTimeout(() => uploadPasswordInput.focus(), 100);
    
    // Enter-Taste für Bestätigung
    uploadPasswordInput.addEventListener('keydown', function(e) {{
        if (e.key === 'Enter') {{
            verifyUploadPassword();
            e.preventDefault();
        }}
    }});
}}
                
                // Passwort-Modal schließen
function closePasswordModal() {{
    uploadPasswordModal.style.display = 'none';
}}
                
// Passwort überprüfen
function verifyUploadPassword() {{
    const password = uploadPasswordInput.value;
    
    if (password === "{UPLOAD_PASSWORD}") {{
        // Passwort korrekt
        closePasswordModal();
        
        // Passwort für diese Session speichern
        sessionStorage.setItem('passwordVerified', 'true');
        
        // Wenn Dateien bereits gedroppt wurden
        if (window.droppedFiles && window.droppedFiles.length > 0) {{
            handleFiles(window.droppedFiles);
            window.droppedFiles = null;
        }} else {{
            // Dateiauswahl öffnen
            fileInput.click();
        }}
    }} else {{
        // Falsches Passwort
        passwordErrorMessage.style.display = 'block';
        uploadPasswordInput.focus();
    }}
}}
                
                // Event-Listener für Drag & Drop
                ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {{
                    dropArea.addEventListener(eventName, preventDefaults, false);
                }});
                
                function preventDefaults(e) {{
                    e.preventDefault();
                    e.stopPropagation();
                }}
                
                ['dragenter', 'dragover'].forEach(eventName => {{
                    dropArea.addEventListener(eventName, highlight, false);
                }});
                
                ['dragleave', 'drop'].forEach(eventName => {{
                    dropArea.addEventListener(eventName, unhighlight, false);
                }});
                
                function highlight() {{
                    dropArea.classList.add('highlight');
                }}
                
                function unhighlight() {{
                    dropArea.classList.remove('highlight');
                }}
                
                // Klick auf Drop-Area
                dropArea.addEventListener('click', () => {{
                    showUploadPasswordModal();
                }});
                
// Event-Handler für Datei-Drop
dropArea.addEventListener('drop', function(e) {{
    e.preventDefault(); // Verhindere Standard-Browser-Aktion
    
    // Dateien speichern
    window.droppedFiles = e.dataTransfer.files;
    
    // Passwort-Dialog zeigen
    showUploadPasswordModal();
}});
                
                // Event-Handler für Dateiauswahl
                fileInput.addEventListener('change', function() {{
                    handleFiles(this.files);
                }});

		// Automatisches Upload-Starten nach Dateiauswahl
fileInput.addEventListener('change', function() {{
   // Wenn die Datei nach Passwort-Überprüfung ausgewählt wurde, bereite sie vor
   if (this.files.length > 0) {{
      handleFiles(this.files);
      // Optional: Automatisches Hochladen, wenn gewünscht
      // uploadFiles();
   }}
}});
                
                // Datei verarbeiten
                function handleFiles(files) {{
                    if (files.length === 0) return;
                    
                    // Dateien im Vorschaubereich anzeigen
                    fileInfo.style.display = 'block';
                    fileListPreview.innerHTML = '';
                    
                    for (let i = 0; i < files.length; i++) {{
                        const file = files[i];
                        const fileItem = document.createElement('div');
                        fileItem.className = 'file-item-preview';
                        
                        // Icon je nach Dateityp
                        const fileIcon = document.createElement('div');
                        fileIcon.className = 'file-item-icon';
                        fileIcon.innerHTML = getFileTypeIcon(file.name);
                        
                        const fileName = document.createElement('div');
                        fileName.className = 'file-item-name';
                        fileName.textContent = file.name;
                        
                        const fileSize = document.createElement('div');
                        fileSize.className = 'file-item-size';
                        fileSize.textContent = formatFileSize(file.size);
                        
                        fileItem.appendChild(fileIcon);
                        fileItem.appendChild(fileName);
                        fileItem.appendChild(fileSize);
                        
                        fileListPreview.appendChild(fileItem);
                    }}
                    
                    // Upload-Button anzeigen
                    uploadBtn.style.display = 'block';
                }}
                
                // Event-Handler für Upload-Button
                uploadBtn.addEventListener('click', uploadFiles);
                
                // Dateien hochladen
                function uploadFiles() {{
                    const files = fileInput.files;
                    if (files.length === 0) return;
                    
                    // UI-Status zurücksetzen
                    uploadProgress.style.display = 'block';
                    progressBar.style.width = '0%';
                    uploadBtn.disabled = true;
                    
                    let totalUploaded = 0;
                    let successCount = 0;
                    let errorCount = 0;
                    
                    const totalFiles = files.length;
                    
                    // Alle Dateien einzeln hochladen
                    for (let i = 0; i < files.length; i++) {{
                        const file = files[i];
                        const formData = new FormData();
                        formData.append('file', file);
                        
                        const xhr = new XMLHttpRequest();
                        
                        xhr.upload.addEventListener('progress', function(e) {{
                            if (e.lengthComputable) {{
                                // Anteilige Fortschrittsanzeige
                                const fileProgress = (e.loaded / e.total) * (1 / totalFiles);
                                const overallProgress = (i / totalFiles) + fileProgress;
                                progressBar.style.width = (overallProgress * 100) + '%';
                            }}
                        }});
                        
                        xhr.addEventListener('load', function() {{
                            totalUploaded++;
                            
                            if (xhr.status === 200) {{
                                const response = JSON.parse(xhr.responseText);
                                
                                if (response.success) {{
                                    successCount++;
                                }} else {{
                                    errorCount++;
                                    console.error(`Fehler beim Upload von ${{file.name}}: ${{response.error || 'Unbekannter Fehler'}}`);
                                }}
                            }} else {{
                                errorCount++;
                                console.error(`HTTP-Fehler beim Upload von ${{file.name}}: ${{xhr.status}}`);
                            }}
                            
                            // Wenn alle Uploads abgeschlossen sind
                            if (totalUploaded === totalFiles) {{
                                uploadProgress.style.display = 'none';
                                uploadBtn.disabled = false;
                                
                                if (errorCount === 0) {{
                                    showAlert(successAlert, `${{successCount}} Datei(en) erfolgreich hochgeladen.`);
                                }} else if (successCount === 0) {{
                                    showAlert(errorAlert, `Beim Hochladen der Dateien sind Fehler aufgetreten.`);
                                }} else {{
                                    showAlert(successAlert, `${{successCount}} von ${{totalFiles}} Datei(en) erfolgreich hochgeladen. ${{errorCount}} fehlgeschlagen.`);
                                }}
                                
                                // Formular zurücksetzen
                                fileInput.value = '';
                                fileInfo.style.display = 'none';
                                fileListPreview.innerHTML = '';
                                
                                // Dateien neu laden
                                loadFiles();
                            }}
                        }});
                        
                        xhr.addEventListener('error', function() {{
                            totalUploaded++;
                            errorCount++;
                            
                            if (totalUploaded === totalFiles) {{
                                uploadProgress.style.display = 'none';
                                uploadBtn.disabled = false;
                                
                                showAlert(errorAlert, 'Netzwerkfehler beim Hochladen der Dateien.');
                                
                                // Formular zurücksetzen
                                fileInput.value = '';
                                fileInfo.style.display = 'none';
                            }}
                        }});
                        
                        xhr.open('POST', '/upload');
                        xhr.send(formData);
                    }}
                }}
                
                // Laden der Dateien vom Server
                function loadFiles() {{
                    loading.style.display = 'flex';
                    filesGrid.innerHTML = '';
                    filesList.innerHTML = '';
                    pagination.innerHTML = '';
                    
                    // Cache für die API-Antwort verwenden, wenn verfügbar
                    const cachedFiles = sessionStorage.getItem('fileListCache');
                    const cacheTimestamp = sessionStorage.getItem('fileListCacheTime');
                    const now = Date.now();
                    
                    // Cache verwenden, wenn er nicht älter als 60 Sekunden ist
                    if (cachedFiles && cacheTimestamp && (now - parseInt(cacheTimestamp)) < 60000) {{
                        try {{
                            const files = JSON.parse(cachedFiles);
                            processFiles(files);
                            return;
                        }} catch (e) {{
                            console.error('Fehler beim Verarbeiten des Cache:', e);
                            // Bei Fehlern trotzdem vom Server laden
                        }}
                    }}
                    
                    fetch('/list-files')
                        .then(response => response.json())
                        .then(files => {{
                            // Ergebnis im Cache speichern
                            sessionStorage.setItem('fileListCache', JSON.stringify(files));
                            sessionStorage.setItem('fileListCacheTime', Date.now().toString());
                            
                            processFiles(files);
                        }})
                        .catch(error => {{
                            loading.style.display = 'none';
                            
                            // Leerer Zustand anzeigen
                            const emptyState = `
                                <div class="empty-state">
                                    <div class="empty-icon">
                                        <i class="fas fa-exclamation-circle"></i>
                                    </div>
                                    <div class="empty-title">Fehler beim Laden der Dateien</div>
                                    <div class="empty-message">${{error.message}}</div>
                                    <button class="btn btn-accent" onclick="loadFiles()">
                                        <i class="fas fa-sync-alt"></i> Erneut versuchen
                                    </button>
                                </div>
                            `;
                            
                            filesGrid.innerHTML = emptyState;
                            filesList.innerHTML = emptyState;
                        }});
                }}
                
                // Verarbeitet die geladenen Dateien
                function processFiles(files) {{
                    loading.style.display = 'none';
                    
                    // Dateien nach Datum sortieren (neueste zuerst)
                    files.sort((a, b) => b.timestamp - a.timestamp);
                    
                    // Alle Dateien speichern
                    allFiles = files;
                    
                    if (files.length === 0) {{
                        // Leerer Zustand anzeigen
                        const emptyState = `
                            <div class="empty-state">
                                <div class="empty-icon">
                                    <i class="fas fa-file-upload"></i>
                                </div>
                                <div class="empty-title">Keine Dateien vorhanden</div>
                                <div class="empty-message">Laden Sie Ihre ersten Dateien hoch, um sie hier zu sehen.</div>
                                <button class="btn btn-accent" onclick="showUploadPasswordModal()">
                                    <i class="fas fa-upload"></i> Dateien hochladen
                                </button>
                            </div>
                        `;
                        
                        filesGrid.innerHTML = emptyState;
                        filesList.innerHTML = emptyState;
                        return;
                    }}
                    
                    // Paginierung einrichten und Dateien anzeigen
                    displayPaginatedFiles();
                }}
                
                // Zeigt paginierte Dateien an
                function displayPaginatedFiles() {{
                    // Berechnen der Start- und Endindizes für die aktuelle Seite
                    const startIndex = (currentPage - 1) * filesPerPage;
                    const endIndex = Math.min(startIndex + filesPerPage, allFiles.length);
                    
                    // Nur die Dateien für die aktuelle Seite filtern
                    const currentPageFiles = allFiles.slice(startIndex, endIndex);
                    
                    // Listen leeren
                    filesGrid.innerHTML = '';
                    filesList.innerHTML = '';
                    
                    // Dateien in Grid-Ansicht anzeigen
                    currentPageFiles.forEach(file => {{
                        // Grid-Ansicht: Karten
                        const isImage = isImageFile(file.name);
                        
                        // Karten-Ansicht (Grid)
                        const fileCard = document.createElement('div');
                        fileCard.className = 'file-card';
                        
                        // Preview-Bereich
                        const preview = document.createElement('div');
                        preview.className = 'file-card-preview';
                        
                        // Für Bilder eine Thumbnail-Vorschau anzeigen
                        if (isImage) {{
                            const img = document.createElement('img');
                            img.src = `${{file.download_url}}?view=true`;
                            img.alt = file.name;
                            img.loading = 'lazy'; // Lazy loading für bessere Performance
                            preview.appendChild(img);
                        }} else {{
                            // Icon für andere Dateitypen
                            const icon = document.createElement('div');
                            icon.className = 'file-card-icon';
                            icon.innerHTML = getFileTypeIcon(file.name);
                            preview.appendChild(icon);
                        }}
                        
                        // Overlay mit Schnellaktionen
                        const overlay = document.createElement('div');
                        overlay.className = 'file-card-overlay';
                        
                        // Direkte Aktionen im Overlay
                        const viewable = isViewableInBrowser(file.name);
                        
                        if (viewable) {{
                            const viewBtn = document.createElement('button');
                            viewBtn.className = 'overlay-btn';
                            viewBtn.innerHTML = '<i class="fas fa-eye"></i>';
                            viewBtn.title = 'Anzeigen';
                            viewBtn.onclick = () => showFileInModal(file);
                            overlay.appendChild(viewBtn);
                        }}
                        
                        const downloadBtn = document.createElement('a');
                        downloadBtn.className = 'overlay-btn';
                        downloadBtn.href = file.download_url;
                        downloadBtn.innerHTML = '<i class="fas fa-download"></i>';
                        downloadBtn.title = 'Herunterladen';
                        downloadBtn.setAttribute('download', '');
                        overlay.appendChild(downloadBtn);
                        
                        const copyBtn = document.createElement('button');
                        copyBtn.className = 'overlay-btn';
                        copyBtn.innerHTML = '<i class="fas fa-link"></i>';
                        copyBtn.title = 'Link kopieren';
                        copyBtn.onclick = () => {{
                            copyToClipboard(file.full_url);
                            showCopyToast();
                        }};
                        overlay.appendChild(copyBtn);
                        
                        preview.appendChild(overlay);
                        fileCard.appendChild(preview);
                        
                        // Inhalt/Details
                        const content = document.createElement('div');
                        content.className = 'file-card-content';
                        
                        const name = document.createElement('div');
                        name.className = 'file-card-name';
                        name.textContent = file.name;
                        content.appendChild(name);
                        
                        const meta = document.createElement('div');
                        meta.className = 'file-card-meta';
                        meta.textContent = `${{formatFileSize(file.size)}} • ${{formatDate(file.timestamp)}}`;
                        content.appendChild(meta);
                        
                        fileCard.appendChild(content);
                        filesGrid.appendChild(fileCard);
                        
                        // Listenansicht
                        const fileRow = document.createElement('div');
                        fileRow.className = 'file-row';
                        
                        const fileRowIcon = document.createElement('div');
                        fileRowIcon.className = 'file-row-icon';
                        fileRowIcon.innerHTML = getFileTypeIcon(file.name);
                        
                        const fileRowContent = document.createElement('div');
                        fileRowContent.className = 'file-row-content';
                        
                        const fileRowName = document.createElement('div');
                        fileRowName.className = 'file-row-name';
                        fileRowName.textContent = file.name;
                        fileRowContent.appendChild(fileRowName);
                        
                        const fileRowMeta = document.createElement('div');
                        fileRowMeta.className = 'file-row-meta';
                        fileRowMeta.textContent = `${{formatFileSize(file.size)}} • ${{formatDate(file.timestamp)}}`;
                        fileRowContent.appendChild(fileRowMeta);
                        
                        const fileRowActions = document.createElement('div');
                        fileRowActions.className = 'file-row-actions';
                        
                        if (viewable) {{
                            const viewAction = document.createElement('button');
                            viewAction.className = 'action-btn view-btn';
                            viewAction.innerHTML = '<i class="fas fa-eye"></i> Anzeigen';
                            viewAction.onclick = () => showFileInModal(file);
                            fileRowActions.appendChild(viewAction);
                        }}
                        
                        const downloadAction = document.createElement('a');
                        downloadAction.className = 'action-btn';
                        downloadAction.href = file.download_url;
                        downloadAction.innerHTML = '<i class="fas fa-download"></i> Download';
                        downloadAction.setAttribute('download', '');
                        fileRowActions.appendChild(downloadAction);
                        
                        const copyAction = document.createElement('button');
                        copyAction.className = 'action-btn';
                        copyAction.innerHTML = '<i class="fas fa-link"></i> Link kopieren';
                        copyAction.onclick = () => {{
                            copyToClipboard(file.full_url);
                            showCopyToast();
                        }};
                        fileRowActions.appendChild(copyAction);
                        
                        fileRow.appendChild(fileRowIcon);
                        fileRow.appendChild(fileRowContent);
                        fileRow.appendChild(fileRowActions);
                        
                        filesList.appendChild(fileRow);
                    }});
                    
                    // Paginierung aktualisieren
                    updatePagination();
                }}
                
                // Aktualisiert die Paginierungssteuerung
                function updatePagination() {{
                    pagination.innerHTML = '';
                    
                    const totalPages = Math.ceil(allFiles.length / filesPerPage);
                    
                    if (totalPages <= 1) return;
                    
                    // Zurück-Button
                    const prevBtn = document.createElement('button');
                    prevBtn.className = 'pagination-btn' + (currentPage === 1 ? ' disabled' : '');
                    prevBtn.innerHTML = '<i class="fas fa-chevron-left"></i>';
                    prevBtn.disabled = currentPage === 1;
                    
                    if (currentPage > 1) {{
                        prevBtn.onclick = () => {{
                            currentPage--;
                            displayPaginatedFiles();
                            // Nach oben scrollen
                            window.scrollTo({{ top: document.querySelector('.files-container').offsetTop - 20, behavior: 'smooth' }});
                        }};
                    }}
                    
                    pagination.appendChild(prevBtn);
                    
                    // Seitenzahlen
                    const maxVisiblePages = 5;
                    let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
                    let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
                    
                    if (endPage - startPage + 1 < maxVisiblePages) {{
                        startPage = Math.max(1, endPage - maxVisiblePages + 1);
                    }}
                    
                    for (let i = startPage; i <= endPage; i++) {{
                        const pageBtn = document.createElement('button');
                        pageBtn.className = 'pagination-btn' + (i === currentPage ? ' active' : '');
                        pageBtn.textContent = i;
                        
                        if (i !== currentPage) {{
                            pageBtn.onclick = () => {{
                                currentPage = i;
                                displayPaginatedFiles();
                                // Nach oben scrollen
                                window.scrollTo({{ top: document.querySelector('.files-container').offsetTop - 20, behavior: 'smooth' }});
                            }};
                        }}
                        
                        pagination.appendChild(pageBtn);
                    }}
                    
                    // Weiter-Button
                    const nextBtn = document.createElement('button');
                    nextBtn.className = 'pagination-btn' + (currentPage === totalPages ? ' disabled' : '');
                    nextBtn.innerHTML = '<i class="fas fa-chevron-right"></i>';
                    nextBtn.disabled = currentPage === totalPages;
                    
                    if (currentPage < totalPages) {{
                        nextBtn.onclick = () => {{
                            currentPage++;
                            displayPaginatedFiles();
                            // Nach oben scrollen
                            window.scrollTo({{ top: document.querySelector('.files-container').offsetTop - 20, behavior: 'smooth' }});
                        }};
                    }}
                    
                    pagination.appendChild(nextBtn);
                }}
                
                // Prüft, ob die Datei ein Bild ist
                function isImageFile(filename) {{
                    const extension = filename.split('.').pop().toLowerCase();
                    return ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(extension);
                }}
                
                // Prüft, ob eine Datei direkt im Browser angezeigt werden kann
                function isViewableInBrowser(filename) {{
                    const extension = filename.split('.').pop().toLowerCase();
                    const viewableExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'mp3', 'mp4', 'webm', 'ogg', 'pdf', 'txt'];
                    return viewableExtensions.includes(extension);
                }}
                
                // Modal öffnen und Datei anzeigen
                function showFileInModal(file) {{
                    // Modal-Titel setzen
                    modalTitle.textContent = file.name;
                    
                    // Download-Link setzen
                    modalDownloadLink.href = file.download_url;
                    
                    // Modal-Inhalt leeren
                    modalBody.innerHTML = '';
                    
                    // Dateityp bestimmen und entsprechenden Inhalt laden
                    const fileExtension = file.name.split('.').pop().toLowerCase();
                    
                    if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(fileExtension)) {{
                        // Bild anzeigen
                        const img = document.createElement('img');
                        img.src = file.download_url + '?view=true';
                        img.alt = file.name;
                        modalBody.appendChild(img);
                    }} else if (['mp4', 'webm', 'ogg'].includes(fileExtension)) {{
                        // Video anzeigen
                        const video = document.createElement('video');
                        video.controls = true;
                        video.autoplay = false;
                        const source = document.createElement('source');
                        source.src = file.download_url + '?view=true';
                        source.type = `video/${{fileExtension}}`;
                        video.appendChild(source);
                        modalBody.appendChild(video);
                    }} else if (['mp3', 'wav'].includes(fileExtension)) {{
                        // Audio anzeigen
                        const audio = document.createElement('audio');
                        audio.controls = true;
                        audio.autoplay = false;
                        const source = document.createElement('source');
                        source.src = file.download_url + '?view=true';
                        source.type = `audio/${{fileExtension === 'mp3' ? 'mpeg' : fileExtension}}`;
                        audio.appendChild(source);
                        modalBody.appendChild(audio);
                    }} else if (fileExtension === 'pdf') {{
                        // PDF anzeigen
                        const iframe = document.createElement('iframe');
                        iframe.src = file.download_url + '?view=true';
                        iframe.width = '100%';
                        iframe.height = '70vh';
                        iframe.style.border = 'none';
                        modalBody.appendChild(iframe);
                    }} else if (fileExtension === 'txt') {{
                        // Text anzeigen mit Ladeanimation
                        const loadingSpinner = document.createElement('div');
                        loadingSpinner.className = 'spinner';
                        modalBody.appendChild(loadingSpinner);
                        
                        fetch(file.download_url + '?view=true')
                            .then(response => response.text())
                            .then(text => {{
                                modalBody.innerHTML = '';  // Spinner entfernen
                                const pre = document.createElement('pre');
                                pre.style.textAlign = 'left';
                                pre.style.overflow = 'auto';
                                pre.style.padding = 'var(--space-md)';
                                pre.style.whiteSpace = 'pre-wrap';
                                pre.style.wordBreak = 'break-word';
                                pre.style.maxHeight = '70vh';
                                pre.style.background = '#f8f9fa';
                                pre.style.borderRadius = 'var(--border-radius-sm)';
                                pre.textContent = text;
                                modalBody.appendChild(pre);
                            }})
                            .catch(error => {{
                                modalBody.innerHTML = '';
                                modalBody.textContent = 'Fehler beim Laden der Textdatei: ' + error.message;
                            }});
                    }} else {{
                        // Nicht anzeigbarer Dateityp
                        const notViewableMessage = document.createElement('div');
                        notViewableMessage.style.textAlign = 'center';
                        notViewableMessage.style.padding = 'var(--space-2xl)';
                        
                        const icon = document.createElement('div');
                        icon.innerHTML = '<i class="fas fa-file-download"></i>';
                        icon.style.fontSize = '4rem';
                        icon.style.color = 'var(--accent-color)';
                        icon.style.marginBottom = 'var(--space-lg)';
                        
                        const message = document.createElement('p');
                        message.textContent = 'Dieser Dateityp kann nicht direkt angezeigt werden.';
                        message.style.marginBottom = 'var(--space-md)';
                        
                        const downloadHint = document.createElement('p');
                        downloadHint.textContent = 'Bitte laden Sie die Datei herunter, um sie zu öffnen.';
                        downloadHint.style.color = 'var(--text-muted)';
                        
                        notViewableMessage.appendChild(icon);
                        notViewableMessage.appendChild(message);
                        notViewableMessage.appendChild(downloadHint);
                        
                        modalBody.appendChild(notViewableMessage);
                    }}
                    
                    // Modal anzeigen mit Animation
                    fileViewerModal.style.display = 'block';
                    document.body.style.overflow = 'hidden'; // Scroll verhindern
                    
                    // Bei Klick außerhalb des Modals schließen
                    fileViewerModal.addEventListener('click', function(event) {{
                        if (event.target === fileViewerModal) {{
                            closeModal();
                        }}
                    }});
                    
                    // ESC-Taste zum Schließen
                    document.addEventListener('keydown', closeModalOnEscape);
                }}
                
                // Schließen mit ESC-Taste
                function closeModalOnEscape(e) {{
                    if (e.key === 'Escape') {{
                        closeModal();
                    }}
                }}
                
                // Modal schließen
                function closeModal() {{
                    fileViewerModal.style.display = 'none';
                    document.body.style.overflow = ''; // Scroll wiederherstellen
                    modalBody.innerHTML = '';  // Inhalte entfernen
                    document.removeEventListener('keydown', closeModalOnEscape);
                }}
                
                // Zeigt den Copy-Toast an
                function showCopyToast() {{
                    copyToast.classList.add('show');
                    setTimeout(() => {{
                        copyToast.classList.remove('show');
                    }}, 2000);
                }}
                
                // Hilfsfunktionen
                function formatFileSize(bytes) {{
                    if (bytes < 1024) return bytes + ' Bytes';
                    else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
                    else if (bytes < 1073741824) return (bytes / 1048576).toFixed(1) + ' MB';
                    else return (bytes / 1073741824).toFixed(1) + ' GB';
                }}
                
                function formatDate(timestamp) {{
                    const date = new Date(timestamp * 1000);
                    const options = {{ 
                        day: '2-digit', 
                        month: '2-digit', 
                        year: 'numeric',
                        hour: '2-digit',
                        minute: '2-digit'
                    }};
                    return new Intl.DateTimeFormat('de-DE', options).format(date);
                }}
                
                // Liefert ein Icon basierend auf dem Dateityp
                function getFileTypeIcon(filename) {{
                    const ext = filename.split('.').pop().toLowerCase();
                    
                    // Dateityp Icon Mapping
                    const iconMap = {{
                        // Dokumente
                        'pdf': '<i class="fas fa-file-pdf"></i>',
                        'doc': '<i class="fas fa-file-word"></i>',
                        'docx': '<i class="fas fa-file-word"></i>',
                        'xls': '<i class="fas fa-file-excel"></i>',
                        'xlsx': '<i class="fas fa-file-excel"></i>',
                        'ppt': '<i class="fas fa-file-powerpoint"></i>',
                        'pptx': '<i class="fas fa-file-powerpoint"></i>',
                        'txt': '<i class="fas fa-file-alt"></i>',
                        
                        // Bilder
                        'jpg': '<i class="fas fa-file-image"></i>',
                        'jpeg': '<i class="fas fa-file-image"></i>',
                        'png': '<i class="fas fa-file-image"></i>',
                        'gif': '<i class="fas fa-file-image"></i>',
                        'svg': '<i class="fas fa-file-image"></i>',
                        'webp': '<i class="fas fa-file-image"></i>',
                        'bmp': '<i class="fas fa-file-image"></i>',
                        
                        // Audio & Video
                        'mp3': '<i class="fas fa-file-audio"></i>',
                        'wav': '<i class="fas fa-file-audio"></i>',
                        'ogg': '<i class="fas fa-file-audio"></i>',
                        'mp4': '<i class="fas fa-file-video"></i>',
                        'webm': '<i class="fas fa-file-video"></i>',
                        'avi': '<i class="fas fa-file-video"></i>',
                        'mov': '<i class="fas fa-file-video"></i>',
                        
                        // Archive
                        'zip': '<i class="fas fa-file-archive"></i>',
                        'rar': '<i class="fas fa-file-archive"></i>',
                        '7z': '<i class="fas fa-file-archive"></i>',
                        'tar': '<i class="fas fa-file-archive"></i>',
                        'gz': '<i class="fas fa-file-archive"></i>',
                        
                        // Code
                        'html': '<i class="fas fa-file-code"></i>',
                        'css': '<i class="fas fa-file-code"></i>',
                        'js': '<i class="fas fa-file-code"></i>',
                        'php': '<i class="fas fa-file-code"></i>',
                        'py': '<i class="fas fa-file-code"></i>',
                        'json': '<i class="fas fa-file-code"></i>',
                        'xml': '<i class="fas fa-file-code"></i>',
                        
                        // Sonstige
                        'exe': '<i class="fas fa-cog"></i>',
                    }};
                    
                    return iconMap[ext] || '<i class="fas fa-file"></i>';
                }}
                
                // In die Zwischenablage kopieren
                function copyToClipboard(text) {{
                    if (navigator.clipboard && navigator.clipboard.writeText) {{
                        navigator.clipboard.writeText(text)
                            .catch(err => {{
                                console.error('Fehler beim Kopieren: ', err);
                                fallbackCopyTextToClipboard(text);
                            }});
                    }} else {{
                        fallbackCopyTextToClipboard(text);
                    }}
                }}
                
                // Fallback für ältere Browser
                function fallbackCopyTextToClipboard(text) {{
                    const textArea = document.createElement('textarea');
                    textArea.value = text;
                    textArea.style.position = 'fixed';
                    textArea.style.left = '-9999px';
                    textArea.style.top = '-9999px';
                    document.body.appendChild(textArea);
                    textArea.focus();
                    textArea.select();
                    
                    try {{
                        document.execCommand('copy');
                    }} catch (err) {{
                        console.error('Fallback Fehler beim Kopieren: ', err);
                    }}
                    
                    document.body.removeChild(textArea);
                }}
                
                // Wenn Dateien gedroppt wurden und das Passwort korrekt ist, diese verwenden
                document.addEventListener('uploadPasswordCorrect', function() {{
                    if (window.droppedFiles && window.droppedFiles.length > 0) {{
                        handleFiles(window.droppedFiles);
                        window.droppedFiles = null;
                    }}
                }});
                
                // Aktualisierungsbutton
                refreshBtn.addEventListener('click', function() {{
                    // Cache leeren, um frische Daten zu bekommen
                    sessionStorage.removeItem('fileListCache');
                    // Animation für Refresh-Button
                    this.classList.add('rotating');
                    setTimeout(() => {{
                        this.classList.remove('rotating');
                    }}, 500);
                    // Dateien neu laden
                    loadFiles();
                }});
                
                // Initialisieren
                document.addEventListener('DOMContentLoaded', function() {{
                    // Dateien mit leichter Verzögerung für bessere Benutzererfahrung laden
                    setTimeout(loadFiles, 100);
                    
                    // Style für die Rotation des Refresh-Buttons hinzufügen
                    const style = document.createElement('style');
                    style.textContent = `
                        @keyframes rotation {{
                            from {{ transform: rotate(0deg); }}
                            to {{ transform: rotate(360deg); }}
                        }}
                        .rotating i {{
                            animation: rotation 0.5s linear;
                        }}
                    `;
                    document.head.appendChild(style);
                }});
            </script>
        </body>
        </html>
        """
    
    def generate_admin_page(self):
        """Generiert die modernisierte Admin-Seite"""
        banner_url = f"http://{SERVER_ADDRESS}{BANNER_PATH}"
        current_year = time.strftime('%Y')
        
        return f"""
        <!DOCTYPE html>
        <html lang="de">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Vantastic Uploads - Admin</title>
            <link rel="preconnect" href="https://fonts.googleapis.com">
            <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
            <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
            <style>
                :root {{
                    /* Haupt-Farbpalette */
                    --primary-color: #1E3A8A;
                    --primary-light: #2563EB;
                    --primary-dark: #1E40AF;
                    --accent-color: #0EA5E9;
                    --accent-light: #38BDF8;
                    --accent-dark: #0284C7;
                    
                    /* Verwaltungsfarben */
                    --admin-color: #7E22CE;
                    --admin-light: #A855F7;
                    --admin-dark: #6B21A8;
                    
                    /* Text und Hintergrund */
                    --text-color: #1E293B;
                    --text-muted: #64748B;
                    --text-light: #94A3B8;
                    --bg-color: #F8FAFC;
                    --bg-card: #FFFFFF;
                    --bg-hover: #F1F5F9;
                    
                    /* Status-Farben */
                    --success-color: #10B981;
                    --success-light: #D1FAE5;
                    --warning-color: #F59E0B;
                    --warning-light: #FEF3C7;
                    --danger-color: #EF4444;
                    --danger-light: #FEE2E2;
                    
                    /* Abstände */
                    --space-xs: 0.25rem;
                    --space-sm: 0.5rem;
                    --space-md: 1rem;
                    --space-lg: 1.5rem;
                    --space-xl: 2rem;
                    --space-2xl: 3rem;
                    
                    /* Schatten */
                    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
                    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
                    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
                    
                    /* Rahmen */
                    --border-radius-sm: 0.375rem;
                    --border-radius-md: 0.5rem;
                    --border-radius-lg: 0.75rem;
                    --border-color: #E2E8F0;
                }}
                
                * {{
                    margin: 0;
                    padding: 0;
                    box-sizing: border-box;
                }}
                
                body {{
                    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
                    font-size: 16px;
                    line-height: 1.6;
                    color: var(--text-color);
                    background-color: var(--bg-color);
                    -webkit-font-smoothing: antialiased;
                    -moz-osx-font-smoothing: grayscale;
                }}
                
                .container {{
                    max-width: 1200px;
                    margin: 0 auto;
                    padding: var(--space-lg);
                }}
                
                /* Header-Bereich */
                .header {{
                    background-color: var(--bg-card);
                    box-shadow: var(--shadow-md);
                    padding: var(--space-lg) 0;
                    position: relative;
                    top: 0;
                    z-index: 10;
                }}
                
                .header .container {{
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    padding-top: var(--space-md);
                    padding-bottom: var(--space-md);
                }}
                
                .header-banner {{
                    width: 100%;
    	 	    max-width: 1200px;
    		    min-height: 150px;
   		    object-fit: scale-down;  /* Versucht das Bild zu vergrößern, wobei das Seitenverhältnis
		beibehalten wird */
    		    margin: 0 auto;
    		    image-rendering: -webkit-optimize-contrast;  /* Verbesserung für Chrome */
   	 	    image-rendering: crisp-edges;  /* Allgemeine Verbesserung */
                }}
                
                /* Admin-Badge */
                .admin-badge {{
                    position: absolute;
                    top: 10px;
                    right: 10px;
                    background-color: var(--admin-color);
                    color: white;
                    padding: var(--space-xs) var(--space-md);
                    border-radius: var(--border-radius-md);
                    font-size: 0.875rem;
                    font-weight: 500;
                }}
                
                /* Bedienleiste */
                .toolbar {{
                    background-color: var(--bg-card);
                    border-radius: var(--border-radius-lg);
                    box-shadow: var(--shadow-sm);
                    padding: var(--space-lg);
                    margin-bottom: var(--space-xl);
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    flex-wrap: wrap;
                    gap: var(--space-md);
                }}
                
                /* Suche */
                .search-container {{
                    flex: 1;
                    max-width: 600px;
                    position: relative;
                }}
                
                .search-input {{
                    width: 100%;
                    padding: var(--space-md) var(--space-lg);
                    padding-left: calc(var(--space-lg) + 20px);
                    border: 1px solid var(--border-color);
                    border-radius: var(--border-radius-md);
                    font-size: 1rem;
                    transition: all 0.2s ease;
                }}
                
                .search-input:focus {{
                    outline: none;
                    border-color: var(--admin-color);
                    box-shadow: 0 0 0 3px rgba(126, 34, 206, 0.1);
                }}
                
                .search-icon {{
                    position: absolute;
                    left: var(--space-md);
                    top: 50%;
                    transform: translateY(-50%);
                    color: var(--text-muted);
                }}
                
                /* Schaltflächen */
                .btn {{
                    display: inline-flex;
                    align-items: center;
                    justify-content: center;
                    gap: var(--space-sm);
                    padding: var(--space-sm) var(--space-lg);
                    border-radius: var(--border-radius-md);
                    font-weight: 500;
                    font-size: 1rem;
                    cursor: pointer;
                    transition: all 0.3s ease;
                    border: none;
                    outline: none;
                    text-decoration: none;
                    white-space: nowrap;
                }}
                
                .btn-primary {{
                    background-color: var(--primary-color);
                    color: white;
                }}
                
                .btn-primary:hover, .btn-primary:focus {{
                    background-color: var(--primary-dark);
                    box-shadow: 0 4px 12px rgba(30, 58, 138, 0.3);
                    transform: translateY(-2px);
                }}
                
                .btn-admin {{
                    background-color: var(--admin-color);
                    color: white;
                }}
                
                .btn-admin:hover, .btn-admin:focus {{
                    background-color: var(--admin-dark);
                    box-shadow: 0 4px 12px rgba(126, 34, 206, 0.3);
                    transform: translateY(-2px);
                }}
                
                .btn-accent {{
                    background-color: var(--accent-color);
                    color: white;
                }}
                
                .btn-accent:hover, .btn-accent:focus {{
                    background-color: var(--accent-dark);
                    box-shadow: 0 4px 12px rgba(14, 165, 233, 0.3);
                    transform: translateY(-2px);
                }}
                
                .btn-outline {{
                    background-color: transparent;
                    color: var(--primary-color);
                    border: 1px solid var(--primary-color);
                }}
                
                .btn-outline:hover, .btn-outline:focus {{
                    background-color: var(--primary-color);
                    color: white;
                    transform: translateY(-2px);
                }}
                
                .btn-danger {{
                    background-color: var(--danger-color);
                    color: white;
                }}
                
                .btn-danger:hover, .btn-danger:focus {{
                    background-color: #dc2626;
                    box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
                    transform: translateY(-2px);
                }}
                
                /* Dateibereich */
                .files-section {{
                    background-color: var(--bg-card);
                    border-radius: var(--border-radius-lg);
                    box-shadow: var(--shadow-md);
                    padding: var(--space-xl);
                    margin-bottom: var(--space-2xl);
                }}
                
                .section-title {{
                    color: var(--admin-color);
                    font-size: 1.5rem;
                    font-weight: 600;
                    margin-bottom: var(--space-lg);
                    position: relative;
                    padding-bottom: var(--space-sm);
                }}
                
                .section-title::after {{
                    content: '';
                    position: absolute;
                    bottom: 0;
                    left: 0;
                    width: 50px;
                    height: 3px;
                    background-color: var(--admin-color);
                    border-radius: 3px;
                }}
                
                /* Spinner für Laden */
                .loading {{
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    padding: var(--space-2xl);
                }}
                
                .spinner {{
                    width: 40px;
                    height: 40px;
                    border: 3px solid rgba(126, 34, 206, 0.2);
                    border-radius: 50%;
                    border-top-color: var(--admin-color);
                    animation: spinner 1s linear infinite;
                }}
                
                @keyframes spinner {{
                    to {{ transform: rotate(360deg); }}
                }}
                
                /* Dateiliste */
                .file-row {{
                    background-color: var(--bg-card);
                    border-left: 3px solid transparent;
                    padding: var(--space-md) var(--space-lg);
                    margin-bottom: var(--space-md);
                    box-shadow: var(--shadow-sm);
                    display: flex;
                    align-items: center;
                    border-radius: var(--border-radius-md);
                    transition: all 0.3s ease;
                }}
                
                .file-row:hover {{
                    background-color: var(--bg-hover);
                    border-left-color: var(--admin-color);
                    transform: translateX(5px);
                }}
                
                .file-row-icon {{
                    flex: 0 0 40px;
                    font-size: 1.5rem;
                    color: var(--admin-color);
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }}
                
                .file-row-content {{
                    flex: 1;
                    min-width: 0;
                    padding: 0 var(--space-lg);
                }}
                
                .file-row-name {{
                    font-weight: 500;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                }}
                
                .file-row-meta {{
                    color: var(--text-muted);
                    font-size: 0.875rem;
                }}
                
                .file-row-actions {{
                    display: flex;
                    gap: var(--space-sm);
                }}
                
                .action-btn {{
                    background-color: var(--bg-hover);
                    color: var(--text-color);
                    border: none;
                    padding: var(--space-sm) var(--space-md);
                    border-radius: var(--border-radius-md);
                    font-size: 0.875rem;
                    cursor: pointer;
                    transition: all 0.2s ease;
                    display: flex;
                    align-items: center;
                    gap: var(--space-xs);
                }}
                
                .action-btn:hover {{
                    background-color: var(--admin-color);
                    color: white;
                }}
                
                .action-btn.view-btn:hover {{
                    background-color: var(--accent-color);
                }}
                
                .action-btn.delete-btn:hover {{
                    background-color: var(--danger-color);
                }}
                
                /* Keine Dateien Zustand */
                .empty-state {{
                    text-align: center;
                    padding: var(--space-2xl);
                    color: var(--text-muted);
                }}
                
                .empty-icon {{
                    font-size: 3rem;
                    color: var(--admin-light);
                    margin-bottom: var(--space-lg);
                }}
                
                .empty-title {{
                    font-size: 1.25rem;
                    margin-bottom: var(--space-md);
                }}
                
                .empty-message {{
                    margin-bottom: var(--space-lg);
                }}
                
                /* Paginierung */
                .pagination {{
                    display: flex;
                    justify-content: center;
                    gap: var(--space-sm);
                    margin-top: var(--space-xl);
                }}
                
                .pagination-btn {{
                    width: 40px;
                    height: 40px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    border-radius: var(--border-radius-md);
                    transition: all 0.2s ease;
                    cursor: pointer;
                    font-weight: 500;
                    border: 1px solid var(--border-color);
                    background-color: var(--bg-card);
                }}
                
                .pagination-btn.active {{
                    background-color: var(--admin-color);
                    color: white;
                    border-color: var(--admin-color);
                }}
                
                .pagination-btn:hover:not(.active):not(.disabled) {{
                    background-color: var(--bg-hover);
                    border-color: var(--admin-light);
                }}
                
                .pagination-btn.disabled {{
                    opacity: 0.5;
                    cursor: not-allowed;
                }}
                
                /* Benachrichtigungen */
                .alert {{
                    padding: var(--space-lg);
                    border-radius: var(--border-radius-md);
                    margin-bottom: var(--space-lg);
                    font-weight: 500;
                    display: flex;
                    align-items: center;
                    gap: var(--space-md);
                    opacity: 0;
                    transform: translateY(-10px);
                    transition: all 0.3s ease;
                    position: fixed;
                    top: var(--space-lg);
                    right: var(--space-lg);
                    z-index: 1000;
                    max-width: 400px;
                    box-shadow: var(--shadow-lg);
                }}
                
                .alert.show {{
                    opacity: 1;
                    transform: translateY(0);
                }}
                
                .alert-success {{
                    background-color: var(--success-light);
                    color: var(--success-color);
                }}
                
                .alert-error {{
                    background-color: var(--danger-light);
                    color: var(--danger-color);
                }}
                
                .alert-icon {{
                    font-size: 1.25rem;
                }}
                
                .alert-close {{
                    margin-left: auto;
                    cursor: pointer;
                    opacity: 0.7;
                    transition: opacity 0.2s ease;
                }}
                
                .alert-close:hover {{
                    opacity: 1;
                }}
                
                /* Modal-Fenster */
                .modal {{
                    display: none;
                    position: fixed;
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100%;
                    background-color: rgba(15, 23, 42, 0.8);
                    z-index: 1000;
                    padding: var(--space-md);
                    overflow-y: auto;
                }}
                
                .modal-content {{
                    background-color: var(--bg-card);
                    border-radius: var(--border-radius-lg);
                    box-shadow: var(--shadow-lg);
                    width: 100%;
                    max-width: 800px;
                    margin: 5vh auto;
                    animation: modalEnter 0.3s ease;
                    overflow: hidden;
                    display: flex;
                    flex-direction: column;
                    max-height: 90vh;
                }}
                
                @keyframes modalEnter {{
                    from {{ opacity: 0; transform: scale(0.9); }}
                    to {{ opacity: 1; transform: scale(1); }}
                }}
                
                .modal-header {{
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    padding: var(--space-lg);
                    border-bottom: 1px solid var(--border-color);
                }}
                
                .modal-title {{
                    font-weight: 600;
                    color: var(--admin-color);
                    font-size: 1.25rem;
                }}
                
                .modal-close {{
                    background: none;
                    border: none;
                    font-size: 1.5rem;
                    color: var(--text-muted);
                    cursor: pointer;
                    transition: color 0.2s ease;
                }}
                
                .modal-close:hover {{
                    color: var(--danger-color);
                }}
                
                .modal-body {{
                    padding: var(--space-lg);
                    overflow-y: auto;
                    flex: 1;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                }}
                
                .modal-body img {{
                    max-width: 100%;
                    max-height: 70vh;
                    object-fit: contain;
                }}
                
                .modal-body video,
                .modal-body audio {{
                    width: 100%;
                }}
                
                .modal-footer {{
                    padding: var(--space-lg);
                    border-top: 1px solid var(--border-color);
                    display: flex;
                    justify-content: flex-end;
                    gap: var(--space-md);
                }}
                
                /* Bestätigungs-Dialog */
                .confirm-modal-content {{
                    max-width: 500px;
                }}
                
                .file-info-box {{
                    background-color: var(--bg-hover);
                    padding: var(--space-md);
                    border-radius: var(--border-radius-md);
                    margin: var(--space-md) 0;
                    font-family: monospace;
                    word-break: break-all;
                }}
                
                .warning-text {{
                    color: var(--danger-color);
                    font-weight: 500;
                }}
                
                /* Toast (Kopieren) */
                .toast {{
                    position: fixed;
                    left: 50%;
                    transform: translateX(-50%);
                    bottom: var(--space-xl);
                    background-color: var(--admin-color);
                    color: white;
                    padding: var(--space-md) var(--space-xl);
                    border-radius: var(--border-radius-md);
                    box-shadow: var(--shadow-lg);
                    display: flex;
                    align-items: center;
                    gap: var(--space-md);
                    opacity: 0;
                    transition: all 0.3s ease;
                    z-index: 1001;
                }}
                
                .toast.show {{
                    opacity: 1;
                    transform: translate(-50%, -20px);
                }}
                
                /* Footer */
                .footer {{
                    background-color: var(--bg-card);
                    box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.05);
                    padding: var(--space-xl) 0;
                    text-align: center;
                    color: var(--text-muted);
                    margin-top: var(--space-2xl);
                }}
                
                .footer-content {{
                    max-width: 600px;
                    margin: 0 auto;
                }}
                
                /* Responsive Design */
                @media (max-width: 768px) {{
                    .container {{
                        padding: var(--space-md);
                    }}
                    
                    .files-section {{
                        padding: var(--space-lg);
                    }}
                    
                    .toolbar {{
                        flex-direction: column;
                        align-items: flex-start;
                    }}
                    
                    .search-container {{
                        width: 100%;
                        max-width: none;
                    }}
                    
                    .file-row {{
                        flex-direction: column;
                        align-items: flex-start;
                    }}
                    
                    .file-row-icon {{
                        margin-bottom: var(--space-sm);
                    }}
                    
                    .file-row-content {{
                        padding: var(--space-sm) 0;
                        width: 100%;
                    }}
                    
                    .file-row-actions {{
                        width: 100%;
                        justify-content: space-between;
                        margin-top: var(--space-sm);
                    }}
                    
                    .modal-content {{
                        margin: 0;
                        max-height: 100vh;
                        height: 100%;
                        border-radius: 0;
                    }}
                }}
            </style>
        </head>
        <body>
            <!-- Header mit Logo -->
            <header class="header">
                <div class="container">
                    <img src="{banner_url}" alt="Vantastic Uploads" class="header-banner">
                    <div class="admin-badge">Verwaltungsbereich</div>
                </div>
            </header>
            
            <div class="container">
                <!-- Toolbar mit Suche und Aktionsbuttons -->
                <div class="toolbar">
                    <a href="/" class="btn btn-primary">
                        <i class="fas fa-arrow-left"></i> Zurück zur Startseite
                    </a>
                    
                    <div class="search-container">
                        <i class="fas fa-search search-icon"></i>
                        <input type="text" id="searchInput" class="search-input" placeholder="Dateien suchen...">
                    </div>
                    
                    <button id="refreshBtn" class="btn btn-outline">
                        <i class="fas fa-sync-alt"></i> Aktualisieren
                    </button>
                </div>
                
                <!-- Hauptbereich: Dateiverwaltung -->
                <section class="files-section">
                    <h2 class="section-title">Dateiverwaltung</h2>
                    
                    <!-- Ladeanimation -->
                    <div id="loading" class="loading">
                        <div class="spinner"></div>
                    </div>
                    
                    <!-- Dateiliste (wird dynamisch befüllt) -->
                    <div id="filesList"></div>
                    
                    <!-- Paginierung (wird dynamisch befüllt) -->
                    <div id="pagination" class="pagination"></div>
                </section>
            </div>
            
            <!-- Erfolgsmeldung -->
            <div id="successAlert" class="alert alert-success">
                <div class="alert-icon"><i class="fas fa-check-circle"></i></div>
                <div class="alert-message">Datei erfolgreich gelöscht!</div>
                <div class="alert-close"><i class="fas fa-times"></i></div>
            </div>
            
            <!-- Fehlermeldung -->
            <div id="errorAlert" class="alert alert-error">
                <div class="alert-icon"><i class="fas fa-exclamation-circle"></i></div>
                <div class="alert-message">Fehler beim Löschen der Datei.</div>
                <div class="alert-close"><i class="fas fa-times"></i></div>
            </div>
            
            <!-- Toast Benachrichtigung (Kopieren) -->
            <div id="copyToast" class="toast">
                <i class="fas fa-check-circle"></i>
                <span>Link in Zwischenablage kopiert!</span>
            </div>
            
            <!-- Modal-Fenster für Dateivorschau -->
            <div id="fileViewerModal" class="modal">
                <div class="modal-content">
                    <div class="modal-header">
                        <h3 id="modalTitle" class="modal-title">Dateiname</h3>
                        <button class="modal-close" onclick="closeModal()">×</button>
                    </div>
                    <div id="modalBody" class="modal-body">
                        <!-- Hier wird der Inhalt dynamisch eingefügt -->
                    </div>
                    <div class="modal-footer">
                        <a id="modalDownloadLink" href="#" class="btn btn-accent">
                            <i class="fas fa-download"></i> Herunterladen
                        </a>
                    </div>
                </div>
            </div>
            
            <!-- Bestätigungsdialog für Löschen -->
            <div id="confirmationModal" class="modal">
                <div class="modal-content confirm-modal-content">
                    <div class="modal-header">
                        <h3 class="modal-title">Datei löschen</h3>
                        <button class="modal-close" onclick="closeConfirmModal()">×</button>
                    </div>
                    <div class="modal-body" style="display: block; text-align: left;">
                        <p>Sind Sie sicher, dass Sie die folgende Datei löschen möchten?</p>
                        <div id="fileToDelete" class="file-info-box"></div>
                        <p class="warning-text">Diese Aktion kann nicht rückgängig gemacht werden.</p>
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-outline" onclick="closeConfirmModal()">Abbrechen</button>
                        <button id="confirmDeleteBtn" class="btn btn-danger">
                            <i class="fas fa-trash-alt"></i> Löschen
                        </button>
                    </div>
                </div>
            </div>
            
            <!-- Footer -->
            <footer class="footer">
                <div class="footer-content">
                    <p>&copy; {current_year} Vantastic Uploads. Alle Rechte vorbehalten.</p>
                </div>
            </footer>
            
            <script>
                // DOM-Elemente
                const loading = document.getElementById('loading');
                const filesList = document.getElementById('filesList');
                const pagination = document.getElementById('pagination');
                const searchInput = document.getElementById('searchInput');
                const refreshBtn = document.getElementById('refreshBtn');
                const confirmationModal = document.getElementById('confirmationModal');
                const fileToDeleteElem = document.getElementById('fileToDelete');
                const confirmDeleteBtn = document.getElementById('confirmDeleteBtn');
                const successAlert = document.getElementById('successAlert');
                const errorAlert = document.getElementById('errorAlert');
                const copyToast = document.getElementById('copyToast');
                const fileViewerModal = document.getElementById('fileViewerModal');
                const modalTitle = document.getElementById('modalTitle');
                const modalBody = document.getElementById('modalBody');
                const modalDownloadLink = document.getElementById('modalDownloadLink');
                
                // Status-Variablen
                let allFiles = [];
                let filteredFiles = [];
                let currentPage = 1;
                const filesPerPage = 10;
                let fileToDelete = '';
                
                // Event-Listener
                searchInput.addEventListener('input', debounce(filterFiles, 300));
                
                
		// Debounce-Funktion, um zu häufige Aufrufe zu vermeiden
                function debounce(func, delay) {{
                    let timeout;
                    return function() {{
                        const context = this;
                        const args = arguments;
                        clearTimeout(timeout);
                        timeout = setTimeout(() => func.apply(context, args), delay);
                    }};
                }}
                
                // Alert-Schließen-Buttons
                document.querySelectorAll('.alert-close').forEach(closeBtn => {{
                    closeBtn.addEventListener('click', (e) => {{
                        const alert = e.target.closest('.alert');
                        alert.classList.remove('show');
                    }});
                }});
                
                // Benachrichtigung anzeigen
                function showAlert(alert, message) {{
                    const messageEl = alert.querySelector('.alert-message');
                    messageEl.textContent = message;
                    
                    alert.classList.add('show');
                    
                    // Nach 5 Sekunden ausblenden
                    setTimeout(() => {{
                        alert.classList.remove('show');
                    }}, 5000);
                }}

                // Dateien laden
                function loadFiles() {{
                    loading.style.display = 'flex';
                    filesList.innerHTML = '';
                    pagination.innerHTML = '';
                    
                    // Cache für die API-Antwort verwenden, wenn verfügbar
                    const cachedFiles = sessionStorage.getItem('adminFileListCache');
                    const cacheTimestamp = sessionStorage.getItem('adminFileListCacheTime');
                    const now = Date.now();
                    
                    // Cache verwenden, wenn er nicht älter als 30 Sekunden ist
                    if (cachedFiles && cacheTimestamp && (now - parseInt(cacheTimestamp)) < 30000) {{
                        try {{
                            const files = JSON.parse(cachedFiles);
                            processFiles(files);
                            return;
                        }} catch (e) {{
                            console.error('Fehler beim Verarbeiten des Admin-Cache:', e);
                        }}
                    }}
                    
                    fetch('/list-files')
                        .then(response => response.json())
                        .then(files => {{
                            // Ergebnis im Cache speichern
                            sessionStorage.setItem('adminFileListCache', JSON.stringify(files));
                            sessionStorage.setItem('adminFileListCacheTime', Date.now().toString());
                            
                            processFiles(files);
                        }})
                        .catch(error => {{
                            loading.style.display = 'none';
                            
                            // Leerer Zustand anzeigen
                            filesList.innerHTML = `
                                <div class="empty-state">
                                    <div class="empty-icon">
                                        <i class="fas fa-exclamation-circle"></i>
                                    </div>
                                    <div class="empty-title">Fehler beim Laden der Dateien</div>
                                    <div class="empty-message">${{error.message}}</div>
                                    <button class="btn btn-admin" onclick="loadFiles()">
                                        <i class="fas fa-sync-alt"></i> Erneut versuchen
                                    </button>
                                </div>
                            `;
                        }});
                }}
                
                // Verarbeitet die geladenen Dateien
                function processFiles(files) {{
                    loading.style.display = 'none';
                    
                    // Dateien nach Datum sortieren (neueste zuerst)
                    files.sort((a, b) => b.timestamp - a.timestamp);
                    
                    allFiles = files;
                    filteredFiles = [...files];
                    
                    if (files.length === 0) {{
                        // Leerer Zustand anzeigen
                        filesList.innerHTML = `
                            <div class="empty-state">
                                <div class="empty-icon">
                                    <i class="fas fa-folder-open"></i>
                                </div>
                                <div class="empty-title">Keine Dateien vorhanden</div>
                                <div class="empty-message">Es wurden noch keine Dateien hochgeladen.</div>
                                <a href="/" class="btn btn-admin">
                                    <i class="fas fa-upload"></i> Zum Upload-Bereich
                                </a>
                            </div>
                        `;
                        return;
                    }}
                    
                    displayFiles();
                }}
                
                // Filtert die Dateien basierend auf dem Suchbegriff
                function filterFiles() {{
                    const searchTerm = searchInput.value.trim().toLowerCase();
                    
                    if (searchTerm === '') {{
                        filteredFiles = [...allFiles];
                    }} else {{
                        filteredFiles = allFiles.filter(file => 
                            file.name.toLowerCase().includes(searchTerm)
                        );
                    }}
                    
                    currentPage = 1;
                    displayFiles();
                }}
                
                // Zeigt die gefilterten Dateien an
                function displayFiles() {{
                    filesList.innerHTML = '';
                    
                    // Keine Dateien gefunden
                    if (filteredFiles.length === 0) {{
                        filesList.innerHTML = `
                            <div class="empty-state">
                                <div class="empty-icon">
                                    <i class="fas fa-search"></i>
                                </div>
                                <div class="empty-title">Keine Dateien gefunden</div>
                                <div class="empty-message">Keine Dateien entsprechen Ihren Suchkriterien.</div>
                                <button class="btn btn-outline" onclick="resetSearch()">
                                    <i class="fas fa-times"></i> Suche zurücksetzen
                                </button>
                            </div>
                        `;
                        pagination.innerHTML = '';
                        return;
                    }}
                    
                    // Paginierung berechnen
                    const totalPages = Math.ceil(filteredFiles.length / filesPerPage);
                    const startIndex = (currentPage - 1) * filesPerPage;
                    const endIndex = Math.min(startIndex + filesPerPage, filteredFiles.length);
                    
                    // Aktuell angezeigte Dateien
                    const currentFiles = filteredFiles.slice(startIndex, endIndex);
                    
                    // Dateien anzeigen
                    currentFiles.forEach(file => {{
                        const fileRow = document.createElement('div');
                        fileRow.className = 'file-row';
                        
                        const fileRowIcon = document.createElement('div');
                        fileRowIcon.className = 'file-row-icon';
                        fileRowIcon.innerHTML = getFileTypeIcon(file.name);
                        
                        const fileRowContent = document.createElement('div');
                        fileRowContent.className = 'file-row-content';
                        
                        const fileRowName = document.createElement('div');
                        fileRowName.className = 'file-row-name';
                        fileRowName.textContent = file.name;
                        fileRowContent.appendChild(fileRowName);
                        
                        const fileRowMeta = document.createElement('div');
                        fileRowMeta.className = 'file-row-meta';
                        fileRowMeta.textContent = `${{formatFileSize(file.size)}} • Hochgeladen am ${{formatDate(file.timestamp)}}`;
                        fileRowContent.appendChild(fileRowMeta);
                        
                        const fileRowActions = document.createElement('div');
                        fileRowActions.className = 'file-row-actions';
                        
                        // Prüfen, ob die Datei im Browser angezeigt werden kann
                        const isViewable = isViewableInBrowser(file.name);
                        
                        if (isViewable) {{
                            const viewButton = document.createElement('button');
                            viewButton.className = 'action-btn view-btn';
                            viewButton.innerHTML = '<i class="fas fa-eye"></i> Anzeigen';
                            viewButton.onclick = function() {{
                                showFileInModal(file);
                            }};
                            fileRowActions.appendChild(viewButton);
                        }}
                        
                        const downloadLink = document.createElement('a');
                        downloadLink.href = file.download_url;
                        downloadLink.className = 'action-btn';
                        downloadLink.innerHTML = '<i class="fas fa-download"></i> Download';
                        downloadLink.setAttribute('download', '');
                        fileRowActions.appendChild(downloadLink);
                        
                        const copyLinkBtn = document.createElement('button');
                        copyLinkBtn.className = 'action-btn';
                        copyLinkBtn.innerHTML = '<i class="fas fa-link"></i> Link kopieren';
                        copyLinkBtn.onclick = function() {{
                            copyToClipboard(file.full_url);
                            showCopyToast();
                        }};
                        fileRowActions.appendChild(copyLinkBtn);
                        
                        const deleteBtn = document.createElement('button');
                        deleteBtn.className = 'action-btn delete-btn';
                        deleteBtn.innerHTML = '<i class="fas fa-trash-alt"></i> Löschen';
                        deleteBtn.onclick = function() {{
                            showDeleteConfirmation(file.name);
                        }};
                        fileRowActions.appendChild(deleteBtn);
                        
                        fileRow.appendChild(fileRowIcon);
                        fileRow.appendChild(fileRowContent);
                        fileRow.appendChild(fileRowActions);
                        
                        filesList.appendChild(fileRow);
                    }});
                    
                    // Paginierung anzeigen
                    updatePagination(totalPages);
                }}
                
                // Aktualisiert die Paginierungssteuerung
                function updatePagination(totalPages) {{
                    pagination.innerHTML = '';
                    
                    if (totalPages <= 1) return;
                    
                    // Zurück-Button
                    const prevBtn = document.createElement('button');
                    prevBtn.className = 'pagination-btn' + (currentPage === 1 ? ' disabled' : '');
                    prevBtn.innerHTML = '<i class="fas fa-chevron-left"></i>';
                    prevBtn.disabled = currentPage === 1;
                    
                    if (currentPage > 1) {{
                        prevBtn.onclick = () => {{
                            currentPage--;
                            displayFiles();
                            // Nach oben scrollen
                            window.scrollTo({{ top: document.querySelector('.files-section').offsetTop - 20, behavior: 'smooth' }});
                        }};
                    }}
                    
                    pagination.appendChild(prevBtn);
                    
                    // Seitenzahlen
                    const maxVisiblePages = 5;
                    let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
                    let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);
                    
                    if (endPage - startPage + 1 < maxVisiblePages) {{
                        startPage = Math.max(1, endPage - maxVisiblePages + 1);
                    }}
                    
                    for (let i = startPage; i <= endPage; i++) {{
                        const pageBtn = document.createElement('button');
                        pageBtn.className = 'pagination-btn' + (i === currentPage ? ' active' : '');
                        pageBtn.textContent = i;
                        
                        if (i !== currentPage) {{
                            pageBtn.onclick = () => {{
                                currentPage = i;
                                displayFiles();
                                // Nach oben scrollen
                                window.scrollTo({{ top: document.querySelector('.files-section').offsetTop - 20, behavior: 'smooth' }});
                            }};
                        }}
                        
                        pagination.appendChild(pageBtn);
                    }}
                    
                    // Weiter-Button
                    const nextBtn = document.createElement('button');
                    nextBtn.className = 'pagination-btn' + (currentPage === totalPages ? ' disabled' : '');
                    nextBtn.innerHTML = '<i class="fas fa-chevron-right"></i>';
                    nextBtn.disabled = currentPage === totalPages;
                    
                    if (currentPage < totalPages) {{
                        nextBtn.onclick = () => {{
                            currentPage++;
                            displayFiles();
                            // Nach oben scrollen
                            window.scrollTo({{ top: document.querySelector('.files-section').offsetTop - 20, behavior: 'smooth' }});
                        }};
                    }}
                    
                    pagination.appendChild(nextBtn);
                }}
                
                // Prüft, ob eine Datei direkt im Browser angezeigt werden kann
                function isViewableInBrowser(filename) {{
                    const extension = filename.split('.').pop().toLowerCase();
                    const viewableExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'mp3', 'mp4', 'webm', 'ogg', 'pdf', 'txt'];
                    return viewableExtensions.includes(extension);
                }}
                
                // Modal öffnen und Datei anzeigen
                function showFileInModal(file) {{
                    // Modal-Titel setzen
                    modalTitle.textContent = file.name;
                    
                    // Download-Link setzen
                    modalDownloadLink.href = file.download_url;
                    
                    // Modal-Inhalt leeren
                    modalBody.innerHTML = '';
                    
                    // Dateityp bestimmen und entsprechenden Inhalt laden
                    const fileExtension = file.name.split('.').pop().toLowerCase();
                    
                    if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'].includes(fileExtension)) {{
                        // Bild anzeigen
                        const img = document.createElement('img');
                        img.src = file.download_url + '?view=true';
                        img.alt = file.name;
                        modalBody.appendChild(img);
                    }} else if (['mp4', 'webm', 'ogg'].includes(fileExtension)) {{
                        // Video anzeigen
                        const video = document.createElement('video');
                        video.controls = true;
                        video.autoplay = false;
                        const source = document.createElement('source');
                        source.src = file.download_url + '?view=true';
                        source.type = `video/${{fileExtension}}`;
                        video.appendChild(source);
                        modalBody.appendChild(video);
                    }} else if (['mp3', 'wav'].includes(fileExtension)) {{
                        // Audio anzeigen
                        const audio = document.createElement('audio');
                        audio.controls = true;
                        audio.autoplay = false;
                        const source = document.createElement('source');
                        source.src = file.download_url + '?view=true';
                        source.type = `audio/${{fileExtension === 'mp3' ? 'mpeg' : fileExtension}}`;
                        audio.appendChild(source);
                        modalBody.appendChild(audio);
                    }} else if (fileExtension === 'pdf') {{
                        // PDF anzeigen
                        const iframe = document.createElement('iframe');
                        iframe.src = file.download_url + '?view=true';
                        iframe.width = '100%';
                        iframe.height = '70vh';
                        iframe.style.border = 'none';
                        modalBody.appendChild(iframe);
                    }} else if (fileExtension === 'txt') {{
                        // Text anzeigen mit Ladeanimation
                        const loadingSpinner = document.createElement('div');
                        loadingSpinner.className = 'spinner';
                        modalBody.appendChild(loadingSpinner);
                        
                        fetch(file.download_url + '?view=true')
                            .then(response => response.text())
                            .then(text => {{
                                modalBody.innerHTML = '';  // Spinner entfernen
                                const pre = document.createElement('pre');
                                pre.style.textAlign = 'left';
                                pre.style.overflow = 'auto';
                                pre.style.padding = 'var(--space-md)';
                                pre.style.whiteSpace = 'pre-wrap';
                                pre.style.wordBreak = 'break-word';
                                pre.style.maxHeight = '70vh';
                                pre.style.background = '#f8f9fa';
                                pre.style.borderRadius = 'var(--border-radius-sm)';
                                pre.textContent = text;
                                modalBody.appendChild(pre);
                            }})
                            .catch(error => {{
                                modalBody.innerHTML = '';
                                modalBody.textContent = 'Fehler beim Laden der Textdatei: ' + error.message;
                            }});
                    }} else {{
                        // Nicht anzeigbarer Dateityp
                        const notViewableMessage = document.createElement('div');
                        notViewableMessage.style.textAlign = 'center';
                        notViewableMessage.style.padding = 'var(--space-2xl)';
                        
                        const icon = document.createElement('div');
                        icon.innerHTML = '<i class="fas fa-file-download"></i>';
                        icon.style.fontSize = '4rem';
                        icon.style.color = 'var(--admin-color)';
                        icon.style.marginBottom = 'var(--space-lg)';
                        
                        const message = document.createElement('p');
                        message.textContent = 'Dieser Dateityp kann nicht direkt angezeigt werden.';
                        message.style.marginBottom = 'var(--space-md)';
                        
                        const downloadHint = document.createElement('p');
                        downloadHint.textContent = 'Bitte laden Sie die Datei herunter, um sie zu öffnen.';
                        downloadHint.style.color = 'var(--text-muted)';
                        
                        notViewableMessage.appendChild(icon);
                        notViewableMessage.appendChild(message);
                        notViewableMessage.appendChild(downloadHint);
                        
                        modalBody.appendChild(notViewableMessage);
                    }}
                    
                    // Modal anzeigen mit Animation
                    fileViewerModal.style.display = 'block';
                    document.body.style.overflow = 'hidden'; // Scroll verhindern
                    
                    // Bei Klick außerhalb des Modals schließen
                    fileViewerModal.addEventListener('click', function(event) {{
                        if (event.target === fileViewerModal) {{
                            closeModal();
                        }}
                    }});
                    
                    // ESC-Taste zum Schließen
                    document.addEventListener('keydown', closeModalOnEscape);
                }}
                
                // Schließen mit ESC-Taste
                function closeModalOnEscape(e) {{
                    if (e.key === 'Escape') {{
                        closeModal();
                    }}
                }}
                
                // Modal schließen
                function closeModal() {{
                    fileViewerModal.style.display = 'none';
                    document.body.style.overflow = ''; // Scroll wiederherstellen
                    modalBody.innerHTML = '';  // Inhalte entfernen
                    document.removeEventListener('keydown', closeModalOnEscape);
                }}
                
                // Lösch-Bestätigungsdialog anzeigen
                function showDeleteConfirmation(filename) {{
                    fileToDelete = filename;
                    fileToDeleteElem.textContent = filename;
                    confirmationModal.style.display = 'block';
                    document.body.style.overflow = 'hidden'; // Scroll verhindern
                    
                    confirmDeleteBtn.onclick = function() {{
                        deleteFile(filename);
                    }};
                    
                    // ESC-Taste zum Schließen
                    document.addEventListener('keydown', closeConfirmModalOnEscape);
                    
                    // Bei Klick außerhalb des Modals schließen
                    confirmationModal.addEventListener('click', function(event) {{
                        if (event.target === confirmationModal) {{
                            closeConfirmModal();
                        }}
                    }});
                }}
                
                // Schließen mit ESC-Taste
                function closeConfirmModalOnEscape(e) {{
                    if (e.key === 'Escape') {{
                        closeConfirmModal();
                    }}
                }}
                
                // Bestätigungsmodal schließen
                function closeConfirmModal() {{
                    confirmationModal.style.display = 'none';
                    document.body.style.overflow = ''; // Scroll wiederherstellen
                    document.removeEventListener('keydown', closeConfirmModalOnEscape);
                }}
                
                // Zeigt den Copy-Toast an
                function showCopyToast() {{
                    copyToast.classList.add('show');
                    setTimeout(() => {{
                        copyToast.classList.remove('show');
                    }}, 2000);
                }}
                
                // Datei löschen
                function deleteFile(filename) {{
                    loading.style.display = 'flex';
                    
                    fetch('/delete-file', {{
                        method: 'POST',
                        headers: {{
                            'Content-Type': 'application/json'
                        }},
                        body: JSON.stringify({{ filename: filename }})
                    }})
                    .then(response => {{
                        if (!response.ok) {{
                            throw new Error('Server-Fehler: ' + response.status);
                        }}
                        return response.json();
                    }})
                    .then(data => {{
                        loading.style.display = 'none';
                        closeConfirmModal();
                        
                        if (data.success) {{
                            showAlert(successAlert, `Die Datei "${{filename}}" wurde erfolgreich gelöscht.`);
                            
                            // Cache leeren
                            sessionStorage.removeItem('adminFileListCache');
                            sessionStorage.removeItem('fileListCache');
                            
                            // Dateien neu laden
                            loadFiles();
                        }} else {{
                            showAlert(errorAlert, `Fehler: ${{data.error || 'Unbekannter Fehler'}}`);
                        }}
                    }})
                    .catch(error => {{
                        loading.style.display = 'none';
                        closeConfirmModal();
                        showAlert(errorAlert, `Fehler: ${{error.message}}`);
                    }});
                }}
                
                // Suche zurücksetzen
                function resetSearch() {{
                    searchInput.value = '';
                    filteredFiles = [...allFiles];
                    currentPage = 1;
                    displayFiles();
                }}
                
                // Hilfsfunktionen
                function formatFileSize(bytes) {{
                    if (bytes < 1024) return bytes + ' Bytes';
                    else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
                    else if (bytes < 1073741824) return (bytes / 1048576).toFixed(1) + ' MB';
                    else return (bytes / 1073741824).toFixed(1) + ' GB';
                }}
                
                function formatDate(timestamp) {{
                    const date = new Date(timestamp * 1000);
                    const options = {{ 
                        day: '2-digit', 
                        month: '2-digit', 
                        year: 'numeric',
                        hour: '2-digit',
                        minute: '2-digit'
                    }};
                    return new Intl.DateTimeFormat('de-DE', options).format(date);
                }}
                
                // Liefert ein Icon basierend auf dem Dateityp
                function getFileTypeIcon(filename) {{
                    const ext = filename.split('.').pop().toLowerCase();
                    
                    // Dateityp Icon Mapping
                    const iconMap = {{
                        // Dokumente
                        'pdf': '<i class="fas fa-file-pdf"></i>',
                        'doc': '<i class="fas fa-file-word"></i>',
                        'docx': '<i class="fas fa-file-word"></i>',
                        'xls': '<i class="fas fa-file-excel"></i>',
                        'xlsx': '<i class="fas fa-file-excel"></i>',
                        'ppt': '<i class="fas fa-file-powerpoint"></i>',
                        'pptx': '<i class="fas fa-file-powerpoint"></i>',
                        'txt': '<i class="fas fa-file-alt"></i>',
                        
                        // Bilder
                        'jpg': '<i class="fas fa-file-image"></i>',
                        'jpeg': '<i class="fas fa-file-image"></i>',
                        'png': '<i class="fas fa-file-image"></i>',
                        'gif': '<i class="fas fa-file-image"></i>',
                        'svg': '<i class="fas fa-file-image"></i>',
                        'webp': '<i class="fas fa-file-image"></i>',
                        'bmp': '<i class="fas fa-file-image"></i>',
                        
                        // Audio & Video
                        'mp3': '<i class="fas fa-file-audio"></i>',
                        'wav': '<i class="fas fa-file-audio"></i>',
                        'ogg': '<i class="fas fa-file-audio"></i>',
                        'mp4': '<i class="fas fa-file-video"></i>',
                        'webm': '<i class="fas fa-file-video"></i>',
                        'avi': '<i class="fas fa-file-video"></i>',
                        'mov': '<i class="fas fa-file-video"></i>',
                        
                        // Archive
                        'zip': '<i class="fas fa-file-archive"></i>',
                        'rar': '<i class="fas fa-file-archive"></i>',
                        '7z': '<i class="fas fa-file-archive"></i>',
                        'tar': '<i class="fas fa-file-archive"></i>',
                        'gz': '<i class="fas fa-file-archive"></i>',
                        
                        // Code
                        'html': '<i class="fas fa-file-code"></i>',
                        'css': '<i class="fas fa-file-code"></i>',
                        'js': '<i class="fas fa-file-code"></i>',
                        'php': '<i class="fas fa-file-code"></i>',
                        'py': '<i class="fas fa-file-code"></i>',
                        'json': '<i class="fas fa-file-code"></i>',
                        'xml': '<i class="fas fa-file-code"></i>',
                        
                        // Sonstige
                        'exe': '<i class="fas fa-cog"></i>',
                    }};
                    
                    return iconMap[ext] || '<i class="fas fa-file"></i>';
                }}
                
                // In die Zwischenablage kopieren
                function copyToClipboard(text) {{
                    if (navigator.clipboard && navigator.clipboard.writeText) {{
                        navigator.clipboard.writeText(text)
                            .catch(err => {{
                                console.error('Fehler beim Kopieren: ', err);
                                fallbackCopyTextToClipboard(text);
                            }});
                    }} else {{
                        fallbackCopyTextToClipboard(text);
                    }}
                }}
                
                // Fallback für ältere Browser
                function fallbackCopyTextToClipboard(text) {{
                    const textArea = document.createElement('textarea');
                    textArea.value = text;
                    textArea.style.position = 'fixed';
                    textArea.style.left = '-9999px';
                    textArea.style.top = '-9999px';
                    document.body.appendChild(textArea);
                    textArea.focus();
                    textArea.select();
                    
                    try {{
                        document.execCommand('copy');
                    }} catch (err) {{
                        console.error('Fallback Fehler beim Kopieren: ', err);
                    }}
                    
                    document.body.removeChild(textArea);
                }}
                
                // Aktualisierungsbutton
                refreshBtn.addEventListener('click', function() {{
                    // Cache leeren, um frische Daten zu bekommen
                    sessionStorage.removeItem('adminFileListCache');
                    // Animation für Refresh-Button
                    this.classList.add('rotating');
                    setTimeout(() => {{
                        this.classList.remove('rotating');
                    }}, 500);
                    // Dateien neu laden
                    loadFiles();
                }});
                
                // Initialisieren
                document.addEventListener('DOMContentLoaded', function() {{
                    // Dateien mit leichter Verzögerung für bessere Benutzererfahrung laden
                    setTimeout(loadFiles, 100);
                    
                    // Style für die Rotation des Refresh-Buttons hinzufügen
                    const style = document.createElement('style');
                    style.textContent = `
                        @keyframes rotation {{
                            from {{ transform: rotate(0deg); }}
                            to {{ transform: rotate(360deg); }}
                        }}
                        .rotating i {{
                            animation: rotation 0.5s linear;
                        }}
                    `;
                    document.head.appendChild(style);
                }});
            </script>
        </body>
        </html>
        """
    
    def do_GET(self):
        try:
            path = urllib.parse.urlparse(self.path).path
            query_params = urllib.parse.parse_qs(urllib.parse.urlparse(self.path).query)
            
            # Health-Check Endpunkt für Client-Reconnect
            if path == '/health-check':
                self.send_response(200)
                self.send_header('Content-Type', 'application/json')
                self.end_headers()
                self.wfile.write(json.dumps({'status': 'ok'}).encode('utf-8'))
                return
            
            # Hauptseite
            if path == '/':
                self.send_html_response(self.generate_main_page())
                return
            
            # Admin-Bereich
            if path == '/admin':
                if not self.check_admin_auth():
                    self.request_admin_auth()
                    return
                
                self.send_html_response(self.generate_admin_page())
                return
            
            # Liste der Dateien abfragen
            if path == '/list-files':
                with file_list_lock:
                    current_time = time.time()
                    
                    # Cache verwenden, wenn noch gültig
                    if current_time - file_list_cache["timestamp"] < FILE_CACHE_TIMEOUT:
                        self.send_json_response(file_list_cache["data"])
                        return
                    
                    file_list = []
                    
                    try:
                        for filename in os.listdir(UPLOAD_DIR):
                            file_path = os.path.join(UPLOAD_DIR, filename)
                            if os.path.isfile(file_path):
                                file_size = os.path.getsize(file_path)
                                file_mtime = os.path.getmtime(file_path)
                                
                                file_info = {
                                    'name': filename,
                                    'size': file_size,
                                    'timestamp': int(file_mtime),
                                    'download_url': f'/uploads/{filename}',
                                    'full_url': f'http://{SERVER_ADDRESS}/uploads/{filename}'
                                }
                                
                                file_list.append(file_info)
                        
                        # Cache aktualisieren
                        file_list_cache["timestamp"] = current_time
                        file_list_cache["data"] = file_list
                        
                    except Exception as e:
                        log_message(f"Fehler beim Lesen des Upload-Verzeichnisses: {str(e)}", "ERROR")
                
                self.send_json_response(file_list)
                return
            
            # Datei herunterladen oder anzeigen
            if path.startswith('/uploads/'):
                filename = path.split('/')[-1]
                file_path = os.path.join(UPLOAD_DIR, filename)
                
                if os.path.exists(file_path) and os.path.isfile(file_path):
                    try:
                        # Dateigröße
                        file_size = os.path.getsize(file_path)
                        
                        # MIME-Typ bestimmen - Performance-Optimierung für große Dateien
                        if file_size > 100 * 1024 * 1024:  # 100 MB
                            content_type = 'application/octet-stream'  # Standardwert für große Dateien
                        else:
                            content_type, _ = mimetypes.guess_type(file_path)
                            if not content_type:
                                content_type = 'application/octet-stream'
                        
                        # Prüfen auf den view-Parameter
                        view_mode = 'view' in query_params and query_params['view'][0] == 'true'
                        
                        # Prüfen, ob die Datei angezeigt werden kann
                        extension = filename.split('.')[-1].lower() if '.' in filename else ''
                        viewable_extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'mp3', 'mp4', 'webm', 'ogg', 'pdf', 'txt']
                        can_view = extension in viewable_extensions
                        
                        # Im View-Modus und bei anzeigbaren Dateien als Inline anzeigen
                        if view_mode and can_view:
                            self.send_response(200)
                            self.send_header('Content-Type', content_type)
                            self.send_header('Content-Length', str(file_size))
                            # Inline-Anzeige erzwingen
                            self.send_header('Content-Disposition', f'inline; filename="{filename}"')
                            self.end_headers()
                        else:
                            # Zum Download anbieten
                            self.send_response(200)
                            self.send_header('Content-Type', content_type)
                            self.send_header('Content-Length', str(file_size))
                            self.send_header('Content-Disposition', f'attachment; filename="{filename}"')
                            self.end_headers()
                        
                        # Datei in Chunks lesen und senden, um Speicherverbrauch zu reduzieren
                        with open(file_path, 'rb') as f:
                            chunk_size = 8192  # 8K Chunks
                            while True:
                                chunk = f.read(chunk_size)
                                if not chunk:
                                    break
                                try:
                                    self.wfile.write(chunk)
                                except (BrokenPipeError, ConnectionResetError):
                                    log_message(f"Client hat die Verbindung beim Herunterladen von {filename} abgebrochen", "WARNING")
                                    break
                        
                        log_message(f"Datei {filename} wurde {'angezeigt' if view_mode and can_view else 'heruntergeladen'}", "INFO")
                        return
                    except Exception as e:
                        log_message(f"Fehler beim Senden der Datei {filename}: {str(e)}", "ERROR")
                        self.send_error_response(f"Fehler beim Herunterladen der Datei: {str(e)}")
                        return
                else:
                    self.send_error_response('Die angeforderte Datei wurde nicht gefunden.', 404)
                    return
            
            # Standardmäßig 404
            self.send_error_response('Die angeforderte Seite wurde nicht gefunden.', 404)
        
        except Exception as e:
            log_message(f"Fehler beim Verarbeiten der GET-Anfrage: {str(e)}", "ERROR")
            traceback.print_exc()
            try:
                self.send_error_response(f"Ein Fehler ist aufgetreten: {str(e)}")
            except:
                pass
    
    def do_POST(self):
        try:
            path = urllib.parse.urlparse(self.path).path
            
            # Datei hochladen
            if path == '/upload':
                try:
                    content_type = self.headers.get('Content-Type', '')
                    
                    # Content-Type überprüfen
                    if not content_type.startswith('multipart/form-data'):
                        self.send_json_response({'success': False, 'error': 'Ungültiger Content-Type'}, 400)
                        return
                    
                    # Boundary aus dem Content-Type extrahieren
                    boundary = content_type.split('=')[1].strip()
                    
                    # Content-Length überprüfen
                    content_length = int(self.headers.get('Content-Length', 0))
                    if content_length <= 0:
                        self.send_json_response({'success': False, 'error': 'Keine Daten gesendet'}, 400)
                        return
                    
                    # Daten lesen
                    post_data = self.rfile.read(content_length)
                    
                    # Multipart-Daten verarbeiten
                    boundary_bytes = f'--{boundary}'.encode()
                    parts = post_data.split(boundary_bytes)
                    
                    # Datei aus den Multipart-Daten extrahieren
                    file_data = None
                    file_name = None
                    
                    for part in parts:
                        # Nach Content-Disposition und Dateinamen suchen
                        match = re.search(b'Content-Disposition: form-data; name="file"; filename="(.*?)"', part)
                        if match:
                            file_name = match.group(1).decode('utf-8', 'replace')
                            
                            # Header vom Inhalt trennen
                            header_end = part.find(b'\r\n\r\n')
                            if header_end > 0:
                                file_data = part[header_end + 4:]
                                # Abschließenden Zeilenumbruch entfernen
                                if file_data.endswith(b'\r\n'):
                                    file_data = file_data[:-2]
                            break

                    if not file_data or not file_name:
                        self.send_json_response({'success': False, 'error': 'Keine Datei gefunden'}, 400)
                        return

                    # Eindeutigen Dateinamen erstellen
                    safe_filename = self.get_safe_filename(file_name)
                    timestamp = int(time.time())
                    unique_filename = safe_filename
                    file_path = os.path.join(UPLOAD_DIR, unique_filename)

                    # Datei speichern
                    with open(file_path, 'wb') as f:
                        f.write(file_data)

                    log_message(f"Datei {unique_filename} wurde hochgeladen", "INFO")
                    
                    # Cache invalidieren
                    with file_list_lock:
                        file_list_cache["timestamp"] = 0
                    
                    # Erfolgreiche Antwort senden
                    self.send_json_response({
                        'success': True,
                        'filename': safe_filename,
                        'stored_as': unique_filename,
                        'size': len(file_data),
                        'timestamp': timestamp,
                        'download_url': f'/uploads/{unique_filename}',
                        'full_url': f'http://{SERVER_ADDRESS}/uploads/{unique_filename}'
                    })
                    return
                except Exception as e:
                    log_message(f"Fehler beim Hochladen der Datei: {str(e)}", "ERROR")
                    traceback.print_exc()
                    self.send_json_response({'success': False, 'error': f'Fehler beim Hochladen: {str(e)}'}, 500)
                    return
            
            # Datei löschen
            if path == '/delete-file':
                try:
                    # Admin-Berechtigungen prüfen
                    if not self.check_admin_auth():
                        self.send_json_response({'success': False, 'error': 'Nicht autorisiert'}, 401)
                        return
                    
                    # Content-Type überprüfen
                    content_type = self.headers.get('Content-Type', '')
                    if content_type != 'application/json':
                        self.send_json_response({'success': False, 'error': 'Ungültiger Content-Type'}, 400)
                        return
                    
                    # Content-Length überprüfen
                    content_length = int(self.headers.get('Content-Length', 0))
                    if content_length <= 0:
                        self.send_json_response({'success': False, 'error': 'Keine Daten gesendet'}, 400)
                        return
                    
                    # Daten lesen und parsen
                    post_data = self.rfile.read(content_length).decode('utf-8')
                    try:
                        data = json.loads(post_data)
                    except json.JSONDecodeError:
                        self.send_json_response({'success': False, 'error': 'Ungültiges JSON'}, 400)
                        return
                    
                    # Dateinamen überprüfen
                    filename = data.get('filename')
                    if not filename:
                        self.send_json_response({'success': False, 'error': 'Kein Dateiname angegeben'}, 400)
                        return
                    
                    # Pfadmanipulation verhindern
                    if '..' in filename or filename.startswith('/'):
                        self.send_json_response({'success': False, 'error': 'Ungültiger Dateiname'}, 400)
                        return
                    
                    # Datei löschen
                    file_path = os.path.join(UPLOAD_DIR, filename)
                    if os.path.exists(file_path) and os.path.isfile(file_path):
                        try:
                            os.remove(file_path)
                            log_message(f"Datei {filename} wurde gelöscht", "INFO")
                            
                            # Cache invalidieren
                            with file_list_lock:
                                file_list_cache["timestamp"] = 0
                                
                            self.send_json_response({'success': True, 'message': f'Datei {filename} wurde gelöscht'})
                        except Exception as e:
                            log_message(f"Fehler beim Löschen der Datei {filename}: {str(e)}", "ERROR")
                            self.send_json_response({'success': False, 'error': f'Fehler beim Löschen: {str(e)}'}, 500)
                    else:
                        self.send_json_response({'success': False, 'error': 'Datei nicht gefunden'}, 404)
                    
                    return
                except Exception as e:
                    log_message(f"Fehler beim Löschen der Datei: {str(e)}", "ERROR")
                    traceback.print_exc()
                    self.send_json_response({'success': False, 'error': f'Ein Fehler ist aufgetreten: {str(e)}'}, 500)
                    return
            
            # Unbekannter Pfad
            self.send_json_response({'success': False, 'error': 'Unbekannter Endpunkt'}, 404)
        
        except Exception as e:
            log_message(f"Fehler beim Verarbeiten der POST-Anfrage: {str(e)}", "ERROR")
            traceback.print_exc()
            try:
                self.send_json_response({'success': False, 'error': f'Ein Fehler ist aufgetreten: {str(e)}'}, 500)
            except:
                pass
    
    def get_safe_filename(self, filename):
        """Erstellt einen sicheren Dateinamen"""
        # Ersetzt ungültige Zeichen mit Unterstrichen
        safe_name = re.sub(r'[^\w\.-]', '_', filename)
        return safe_name

class ThreadedHTTPServer(HTTPServer):
    """Handle requests in a separate thread."""
    def __init__(self, server_address, RequestHandlerClass):
        HTTPServer.__init__(self, server_address, RequestHandlerClass)
        self.daemon_threads = True
        self.request_queue_size = 10  # Maximale Anzahl gleichzeitiger Anfragen
        
        # Timeouts setzen
        self.socket.settimeout(5)  # 5 Sekunden Socket-Timeout
        
        # Socket-Optionen für bessere Stabilität
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        
        # TCP Keep-Alive aktivieren
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
        
        # Zusätzliche TCP Keep-Alive Parameter, wenn verfügbar
        try:
            TCP_KEEPIDLE = getattr(socket, 'TCP_KEEPIDLE', None)
            if TCP_KEEPIDLE:
                self.socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPIDLE, 60)  # Beginne nach 60s
            
            TCP_KEEPINTVL = getattr(socket, 'TCP_KEEPINTVL', None)
            if TCP_KEEPINTVL:
                self.socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPINTVL, 10)  # 10s Intervall
            
            TCP_KEEPCNT = getattr(socket, 'TCP_KEEPCNT', None)
            if TCP_KEEPCNT:
                self.socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPCNT, 5)  # 5 Versuche
        except (AttributeError, OSError) as e:
            log_message(f"TCP Keep-Alive Einstellungen nicht verfügbar: {str(e)}", "WARNING")

# In das Skriptverzeichnis wechseln
script_dir = os.path.dirname(os.path.abspath(__file__))
if script_dir:
    os.chdir(script_dir)

# Server starten
log_message(f"Server startet auf http://{SERVER_ADDRESS}:{PORT}", "INFO")
log_message(f"Upload-Verzeichnis: {os.path.abspath(UPLOAD_DIR)}", "INFO")
log_message(f"Admin-Bereich: http://{SERVER_ADDRESS}/admin", "INFO")
log_message(f"Admin-Benutzername: {ADMIN_USERNAME}", "INFO")
log_message(f"Upload-Passwort: {UPLOAD_PASSWORD}", "INFO")
log_message(f"Log-Datei: {os.path.abspath(LOG_FILE)}", "INFO")

try:
    # Verbesserte Server-Klasse verwenden
    httpd = ThreadedHTTPServer(('0.0.0.0', PORT), FileServerHandler)
    httpd.serve_forever()
except KeyboardInterrupt:
    log_message("Server wird durch Benutzer beendet...", "INFO")
except Exception as e:
    log_message(f"Kritischer Fehler beim Starten des Servers: {str(e)}", "ERROR")
    traceback.print_exc()



