<?php
session_start();

// ----------------- CONFIG -----------------
$USERNAME = "admin";      // Dein Benutzername
$PASSWORD = "yuona$!§12";          // Dein Passwort
$targetDir = 'yuona';     // Zielordner für Patchlist
// Default – may be overridden by saved webhook config file
$discordWebhook = "https://discord.com/api/webhooks/1428252648183959648/b3jNI8_KZrt-GtxM3-aCAHYgNJQESTPY_VcgosB8vJkHDsksMfwhdrejUXpP2RCpv2P5"; // Optional
// Layout file path
$layoutFile = __DIR__ . DIRECTORY_SEPARATOR . 'dashboard-layout.json';
$sname ='';
// Users DB path (SQLite) in a writable subfolder
$userDbFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'users.db';
// Session registry to track active sessions and force logout on role change
$sessionRegistryFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'sessions.json';
// ------------------------------------------

// --- User database helpers (SQLite) ---
function ensureDbDir($path){
    $dir = dirname($path);
    if(!is_dir($dir)){@mkdir($dir, 0777, true);} 
    if(!is_writable($dir)){@chmod($dir, 0777);} 
}
function getUserDb($path){
    if(!in_array('sqlite', PDO::getAvailableDrivers())){
        throw new Exception('SQLite driver not available');
    }
    ensureDbDir($path);
    
    // Create a persistent connection with optimized settings
    $pdo = new PDO('sqlite:' . $path, null, null, [
        PDO::ATTR_TIMEOUT => 30,
        PDO::ATTR_PERSISTENT => false
    ]);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // Enable WAL mode for better concurrency (only needs to be set once, but safe to repeat)
    try {
        $pdo->exec('PRAGMA journal_mode=WAL');
        $pdo->exec('PRAGMA synchronous=NORMAL');
        $pdo->exec('PRAGMA busy_timeout=30000');
        $pdo->exec('PRAGMA cache_size=10000');
        $pdo->exec('PRAGMA temp_store=MEMORY');
    } catch(Exception $e){
        // WAL mode might fail on some systems, continue anyway
    }
    
    return $pdo;
}

function executeWithRetry($pdo, callable $callback, $maxRetries = 5){
    $attempt = 0;
    $lastError = null;
    
    while($attempt < $maxRetries){
        try{
            return $callback($pdo);
        } catch(Exception $e){
            $lastError = $e;
            $attempt++;
            
            // Only retry on database locked errors
            if(strpos($e->getMessage(), 'database is locked') !== false && $attempt < $maxRetries){
                usleep(50000 * $attempt); // Exponential backoff: 50ms, 100ms, 150ms, etc.
                continue;
            }
            
            throw $e;
        }
    }
    
    throw $lastError;
}
function initUserDb($pdo, $defaultUser, $defaultPass){
    $pdo->exec('CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        username TEXT UNIQUE NOT NULL,
        password_hash TEXT NOT NULL,
        role INTEGER NOT NULL DEFAULT 0,
        created_at INTEGER NOT NULL
    )');
    // Seed default admin if table empty
    $cnt = (int)$pdo->query('SELECT COUNT(*) AS c FROM users')->fetch(PDO::FETCH_ASSOC)['c'];
    if($cnt === 0){
        $stmt = $pdo->prepare('INSERT INTO users (username, password_hash, role, created_at) VALUES (:u, :ph, :r, :ts)');
        $stmt->execute([
            ':u' => $defaultUser,
            ':ph' => password_hash($defaultPass, PASSWORD_DEFAULT),
            ':r' => 0,
            ':ts' => time()
        ]);
    }
}

// Load saved settings early (webhook-config.json) to override defaults
$cfgFile = __DIR__ . DIRECTORY_SEPARATOR . 'webhook-config.json';
$cacheVersion = 1; // Default cache version
$logoRound = false; // Default logo round
if(file_exists($cfgFile)){
    $raw = @file_get_contents($cfgFile);
    $j = $raw ? json_decode($raw, true) : null;
    if(is_array($j)){
         if(isset($j['sname']) && $j['sname'] !== ''){
            $sname = $j['sname'];
        }
        if(isset($j['targetDir']) && $j['targetDir'] !== ''){
            $targetDir = $j['targetDir'];
        }
        if(isset($j['logoRound'])){
            $logoRound = (bool)$j['logoRound'];
        }
        if(isset($j['webhook']) && $j['webhook'] !== ''){
            $discordWebhook = $j['webhook'];
        }
        if(isset($j['cacheVersion']) && is_numeric($j['cacheVersion'])){
            $cacheVersion = (int)$j['cacheVersion'];
        }
    }
}

// Increment cache version to force reload
$cacheVersion = time(); // Use timestamp to always force fresh cache

// Compute absolute target path now and keep it in `$targetPath`
$targetPath = realpath($targetDir);
if($targetPath === false){ $targetPath = __DIR__ . DIRECTORY_SEPARATOR . $targetDir; }

// Simple authentication handling (login/logout)
if(isset($_POST['login'])){
    $u = isset($_POST['user']) ? trim($_POST['user']) : '';
    $p = isset($_POST['pass']) ? trim($_POST['pass']) : '';
    try{
        $pdo = getUserDb($userDbFile);
        initUserDb($pdo, $USERNAME, $PASSWORD);
        $stmt = $pdo->prepare('SELECT id, username, password_hash, role FROM users WHERE username = :u');
        $stmt->execute([':u'=>$u]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if($row && password_verify($p, $row['password_hash'])){
            $_SESSION['loggedin'] = true;
            $_SESSION['user'] = $row['username'];
            $_SESSION['role'] = (int)$row['role'];
            header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
            exit;
        } else {
            $error = 'Ungültige Zugangsdaten';
        }
    } catch(Exception $e){
        // Fallback to static credentials if DB not available
        if($u === $USERNAME && $p === $PASSWORD){
            $_SESSION['loggedin'] = true;
            $_SESSION['user'] = $USERNAME;
            $_SESSION['role'] = 1;
            header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
            exit;
        } else { $error = 'Ungültige Zugangsdaten'; }
    }
}

if(isset($_GET['logout'])){
    session_unset(); session_destroy();
    header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
    exit;
}

$error = "";

// Convenience: current user role (default 1 if not logged in yet)
$currentRole = isset($_SESSION['role']) ? (int)$_SESSION['role'] : 1;

// Check if user's role changed in DB or session was killed -> force re-login
// Run this check on all requests (including navigation/AJAX) to immediately enforce role changes
if(isset($_SESSION['loggedin']) && $_SESSION['loggedin'] && isset($_SESSION['user'])){
    try{
        $pdo = getUserDb($userDbFile);
        initUserDb($pdo, $USERNAME, $PASSWORD);
        $stmt = $pdo->prepare('SELECT role FROM users WHERE username = :u');
        $stmt->execute([':u'=>$_SESSION['user']]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if(!$row || (int)$row['role'] !== (int)$_SESSION['role']){
            // Role changed or user deleted -> logout immediately
            session_unset(); session_destroy();
            // For AJAX/action requests, return 403
            if(isset($_GET['action'])){
                http_response_code(403);
                if(strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'application/json') !== false){
                    header('Content-Type: application/json');
                    echo json_encode(['success'=>false,'error'=>'Session expired - role changed']);
                } else {
                    echo "Session expired - role changed";
                }
                exit;
            }
            // For page requests, redirect to login
            header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
            exit;
        }
    } catch(Exception $e){}
}

// Layout file handlers
if(isset($_GET['action']) && $_GET['action']=="clearLayout"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(file_exists($layoutFile)){
        if(@unlink($layoutFile)) echo json_encode(['success'=>true]); else echo json_encode(['success'=>false,'error'=>'Cannot delete file']);
    } else { echo json_encode(['success'=>false,'error'=>'No layout file']); }
    exit;
}

// Save layout
if(isset($_GET['action']) && $_GET['action']=="saveLayout"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    if(!is_array($data) || !isset($data['order']) || !is_array($data['order'])){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    // Save sectionOrder and customSections if present
    $layout = [
        'order' => $data['order'],
        'sectionOrder' => isset($data['sectionOrder']) && is_array($data['sectionOrder']) ? $data['sectionOrder'] : [],
        'customSections' => isset($data['customSections']) && is_array($data['customSections']) ? $data['customSections'] : []
    ];
    if(@file_put_contents($layoutFile, json_encode($layout, JSON_PRETTY_PRINT)) === false){ echo json_encode(['success'=>false,'error'=>'Could not write file']); exit; }
    chmod($layoutFile, 0666);
    echo json_encode(['success'=>true]);
    exit;
}

// Load layout
if(isset($_GET['action']) && $_GET['action']=="loadLayout"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!file_exists($layoutFile)){ echo json_encode(['success'=>true,'order'=>[],'sectionOrder'=>[],'customSections'=>[]]); exit; }
    $raw = file_get_contents($layoutFile);
    $j = json_decode($raw, true);
    if(!is_array($j) || !isset($j['order'])){ echo json_encode(['success'=>false,'error'=>'Invalid layout file']); exit; }
    // Always return all fields, fallback to empty if missing
    echo json_encode([
        'success' => true,
        'order' => $j['order'],
        'sectionOrder' => isset($j['sectionOrder']) ? $j['sectionOrder'] : [],
        'customSections' => isset($j['customSections']) ? $j['customSections'] : []
    ]);
    exit;
}

// Clear JS cache by incrementing version
if(isset($_GET['action']) && $_GET['action']=="clearCache"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $cfgFile = __DIR__ . DIRECTORY_SEPARATOR . 'webhook-config.json';
    $cfg = ['webhook'=>'','enabled'=>false,'targetDir'=>$targetDir,'sname'=>$sname,'cacheVersion'=>1,'logoRound'=>false];
    if(file_exists($cfgFile)){
        $raw = file_get_contents($cfgFile);
        $j = json_decode($raw, true);
        if(is_array($j)){ $cfg = array_merge($cfg, $j); }
    }
    $cfg['cacheVersion'] = isset($cfg['cacheVersion']) ? ((int)$cfg['cacheVersion'] + 1) : 2;
    if(@file_put_contents($cfgFile, json_encode($cfg, JSON_PRETTY_PRINT)) === false){ echo json_encode(['success'=>false,'error'=>'Could not write file']); exit; }
    chmod($cfgFile, 0666);
    echo json_encode(['success'=>true,'cacheVersion'=>$cfg['cacheVersion']]);
    exit;
}

// Webhook settings
if(isset($_GET['action']) && $_GET['action']=="getWebhookConfig"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $cfgFile = __DIR__ . DIRECTORY_SEPARATOR . 'webhook-config.json';
    $cfg = ['webhook'=>null,'enabled'=>false, 'targetDir' => $targetDir, 'sname' => $sname, 'cacheVersion' => 1, 'logoRound' => false];
    if(file_exists($cfgFile)){
        $raw = file_get_contents($cfgFile);
        $j = json_decode($raw, true);
        if(is_array($j)){
            $cfg = array_merge($cfg, $j);
        }
    }
    // try to fetch webhook name if webhook configured
    if(!empty($cfg['webhook'])){
        $name = null;
        try{
            $ch = curl_init($cfg['webhook']);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 3);
            $resp = curl_exec($ch);
            $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            if($resp !== false && $status>=200 && $status<300){
                $j = json_decode($resp, true);
                if(is_array($j) && isset($j['name'])) $name = $j['name'];
            }
        } catch(Exception $e){}
        $cfg['name'] = $name;
    }
    echo json_encode(['success'=>true,'config'=>$cfg]);
    exit;
}

// Save webhook config
if(isset($_GET['action']) && $_GET['action']=="saveWebhookConfig"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    // Allow partial updates (logoRound only or full config)
    $cfgFile = __DIR__ . DIRECTORY_SEPARATOR . 'webhook-config.json';
    
    // Read existing config
    $cfg = ['webhook'=>'','enabled'=>false, 'targetDir' => $targetDir, 'sname' => $sname, 'logoRound' => false];
    if(file_exists($cfgFile)){
        $raw = file_get_contents($cfgFile);
        $j = json_decode($raw, true);
        if(is_array($j)){ $cfg = array_merge($cfg, $j); }
    }
    
    // Update fields if provided
    if(isset($data['webhook'])) $cfg['webhook'] = $data['webhook'];
    if(array_key_exists('enabled', $data)) $cfg['enabled'] = !!$data['enabled'];
    if(isset($data['targetDir'])) $cfg['targetDir'] = $data['targetDir'];
    if(isset($data['sname'])) $cfg['sname'] = $data['sname'];
    if(array_key_exists('logoRound', $data)) $cfg['logoRound'] = !!$data['logoRound'];
    
    // validate targetDir
    $cfgPath = realpath($cfg['targetDir']); if($cfgPath === false) $cfgPath = __DIR__ . DIRECTORY_SEPARATOR . $cfg['targetDir'];
    $cfg['targetDirValid'] = is_dir($cfgPath);
    if(@file_put_contents($cfgFile, json_encode($cfg, JSON_PRETTY_PRINT)) === false){ echo json_encode(['success'=>false,'error'=>'Could not write file']); exit; }
    chmod($cfgFile, 0666);
    echo json_encode(['success'=>true,'config'=>$cfg]);
    exit;
}

// --- Multi-Webhook Management ---
// Get all webhooks
if(isset($_GET['action']) && $_GET['action']=="getWebhooks"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1, 2])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $webhooksFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'webhooks.json';
    $webhooks = [];
    if(file_exists($webhooksFile)){
        $raw = @file_get_contents($webhooksFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)) $webhooks = $j;
    }
    echo json_encode(['success'=>true,'webhooks'=>$webhooks]);
    exit;
}

// Check webhook status
if(isset($_GET['action']) && $_GET['action']=="checkWebhookStatus"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $webhooksFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'webhooks.json';
    $webhooks = [];
    if(file_exists($webhooksFile)){
        $raw = @file_get_contents($webhooksFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)) $webhooks = $j;
    }
    
    $results = [];
    foreach($webhooks as $wh){
        if(!$wh['enabled']) continue;
        
        $status = 'offline';
        $responseTime = 0;
        $startTime = microtime(true);
        
        // Simple HEAD request to check if webhook is reachable
        $ch = curl_init($wh['url']);
        curl_setopt($ch, CURLOPT_NOBODY, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        $responseTime = round((microtime(true) - $startTime) * 1000);
        
        // Discord webhooks return 405 for HEAD requests, which is expected
        if($httpCode === 200 || $httpCode === 405 || $httpCode === 204){
            $status = 'online';
        }
        
        $results[] = [
            'id' => $wh['id'],
            'name' => $wh['name'],
            'status' => $status,
            'responseTime' => $responseTime,
            'httpCode' => $httpCode
        ];
    }
    
    echo json_encode(['success'=>true,'results'=>$results]);
    exit;
}

// Save/Update webhook
if(isset($_GET['action']) && $_GET['action']=="saveWebhook"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1, 2])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    if(!is_array($data) || !isset($data['name']) || !isset($data['url'])){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    
    $webhooksFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'webhooks.json';
    ensureDbDir($webhooksFile);
    $webhooks = [];
    if(file_exists($webhooksFile)){
        $raw = @file_get_contents($webhooksFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)) $webhooks = $j;
    }
    
    $id = isset($data['id']) ? $data['id'] : uniqid('wh_', true);
    $enabled = isset($data['enabled']) ? !!$data['enabled'] : true;
    
    // Find and update or add new
    $found = false;
    foreach($webhooks as &$wh){
        if($wh['id'] === $id){
            $wh['name'] = trim($data['name']);
            $wh['url'] = trim($data['url']);
            $wh['enabled'] = $enabled;
            $found = true;
            break;
        }
    }
    
    if(!$found){
        $webhooks[] = ['id'=>$id, 'name'=>trim($data['name']), 'url'=>trim($data['url']), 'enabled'=>$enabled];
    }
    
    if(@file_put_contents($webhooksFile, json_encode($webhooks, JSON_PRETTY_PRINT)) === false){ 
        echo json_encode(['success'=>false,'error'=>'Could not write file']); 
        exit; 
    }
    @chmod($webhooksFile, 0666);
    echo json_encode(['success'=>true,'webhook'=>['id'=>$id, 'name'=>trim($data['name']), 'url'=>trim($data['url']), 'enabled'=>$enabled]]);
    exit;
}

// Delete webhook
if(isset($_GET['action']) && $_GET['action']=="deleteWebhook"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1, 2])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    if(!is_array($data) || !isset($data['id'])){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    
    $webhooksFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'webhooks.json';
    ensureDbDir($webhooksFile);
    $webhooks = [];
    if(file_exists($webhooksFile)){
        $raw = @file_get_contents($webhooksFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)) $webhooks = $j;
    }
    
    $webhooks = array_filter($webhooks, function($wh) use ($data){ return $wh['id'] !== $data['id']; });
    $webhooks = array_values($webhooks); // reindex
    
    if(@file_put_contents($webhooksFile, json_encode($webhooks, JSON_PRETTY_PRINT)) === false){ 
        echo json_encode(['success'=>false,'error'=>'Could not write file']); 
        exit; 
    }
    @chmod($webhooksFile, 0666);
    echo json_encode(['success'=>true]);
    exit;
}

// Save scheduled message
if(isset($_GET['action']) && $_GET['action']=="saveScheduledMessage"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1, 2])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    if(!is_array($data) || !isset($data['message']) || !isset($data['webhookId']) || !isset($data['scheduleTime'])){ 
        echo json_encode(['success'=>false,'error'=>'Invalid payload']); 
        exit; 
    }
    
    $scheduledFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'scheduled.json';
    ensureDbDir($scheduledFile);
    $scheduled = [];
    if(file_exists($scheduledFile)){
        $raw = @file_get_contents($scheduledFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)) $scheduled = $j;
    }
    
    $id = 'sched_' . time() . '_' . rand(1000, 9999);
    $scheduled[] = [
        'id' => $id,
        'message' => $data['message'],
        'webhookId' => $data['webhookId'],
        'scheduleTime' => $data['scheduleTime'],
        'created' => date('Y-m-d H:i:s'),
        'createdBy' => $_SESSION['username'] ?? 'Unknown',
        'status' => 'pending'
    ];
    
    if(@file_put_contents($scheduledFile, json_encode($scheduled, JSON_PRETTY_PRINT)) === false){ 
        echo json_encode(['success'=>false,'error'=>'Could not write file']); 
        exit; 
    }
    @chmod($scheduledFile, 0666);
    echo json_encode(['success'=>true,'id'=>$id]);
    exit;
}

// Get scheduled messages
if(isset($_GET['action']) && $_GET['action']=="getScheduledMessages"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1, 2])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    
    $scheduledFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'scheduled.json';
    $scheduled = [];
    if(file_exists($scheduledFile)){
        $raw = @file_get_contents($scheduledFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)) $scheduled = $j;
    }
    
    echo json_encode(['success'=>true,'scheduled'=>$scheduled]);
    exit;
}

// Cancel scheduled message
if(isset($_GET['action']) && $_GET['action']=="cancelScheduledMessage"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1, 2])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    if(!is_array($data) || !isset($data['id'])){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    
    $scheduledFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'scheduled.json';
    $scheduled = [];
    if(file_exists($scheduledFile)){
        $raw = @file_get_contents($scheduledFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)) $scheduled = $j;
    }
    
    $scheduled = array_filter($scheduled, function($item) use ($data){
        return $item['id'] !== $data['id'];
    });
    $scheduled = array_values($scheduled);
    
    if(@file_put_contents($scheduledFile, json_encode($scheduled, JSON_PRETTY_PRINT)) === false){ 
        echo json_encode(['success'=>false,'error'=>'Could not write file']); 
        exit; 
    }
    @chmod($scheduledFile, 0666);
    echo json_encode(['success'=>true]);
    exit;
}

// Check and execute scheduled messages
if(isset($_GET['action']) && $_GET['action']=="checkScheduledMessages"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $scheduledFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'scheduled.json';
    $webhooksFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'webhooks.json';
    
    $scheduled = [];
    if(file_exists($scheduledFile)){
        $raw = @file_get_contents($scheduledFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)) $scheduled = $j;
    }
    
    $webhooks = [];
    if(file_exists($webhooksFile)){
        $raw = @file_get_contents($webhooksFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)) $webhooks = $j;
    }
    
    $now = time();
    $executed = [];
    $remaining = [];
    
    foreach($scheduled as $item){
        $scheduleTimestamp = strtotime($item['scheduleTime']);
        
        if($scheduleTimestamp <= $now && $item['status'] === 'pending'){
            // Execute this message
            $webhook = null;
            foreach($webhooks as $wh){
                if($wh['id'] === $item['webhookId']){
                    $webhook = $wh;
                    break;
                }
            }
            
            if($webhook && !empty($webhook['url'])){
                $ch = curl_init($webhook['url']);
                curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $item['message']);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_TIMEOUT, 10);
                $response = curl_exec($ch);
                $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                curl_close($ch);
                
                if($httpCode >= 200 && $httpCode < 300){
                    $item['status'] = 'sent';
                    $item['sentAt'] = date('Y-m-d H:i:s');
                    $executed[] = $item['id'];
                } else {
                    $item['status'] = 'failed';
                    $item['error'] = 'HTTP ' . $httpCode;
                }
            } else {
                $item['status'] = 'failed';
                $item['error'] = 'Webhook not found';
            }
        }
        
        $remaining[] = $item;
    }
    
    if(@file_put_contents($scheduledFile, json_encode($remaining, JSON_PRETTY_PRINT)) !== false){
        @chmod($scheduledFile, 0666);
    }
    
    echo json_encode(['success'=>true,'executed'=>$executed,'count'=>count($executed)]);
    exit;
}

// Upload server logo (GIF)
if(isset($_GET['action']) && $_GET['action']=="uploadLogo"){
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ http_response_code(403); echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ http_response_code(403); echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    header('Content-Type: application/json');
    if(!isset($_FILES['logo']) || !is_array($_FILES['logo'])){ echo json_encode(['success'=>false,'error'=>'No file']); exit; }
    $f = $_FILES['logo'];
    if($f['error'] !== UPLOAD_ERR_OK){ echo json_encode(['success'=>false,'error'=>'Upload error','code'=>$f['error']]); exit; }
    // Check file size (30MB max)
    $maxSize = 30 * 1024 * 1024; // 30MB in bytes
    if($f['size'] > $maxSize){ echo json_encode(['success'=>false,'error'=>'File too large (max 30MB)']); exit; }
    // basic validation: image mime (gif/png/jpeg)
    $tmp = $f['tmp_name'];
    $mime = function_exists('mime_content_type') ? mime_content_type($tmp) : '';
    $allowed = ['image/gif'=>'gif','image/png'=>'png','image/jpeg'=>'jpg'];
    $ext = '';
    if($mime && isset($allowed[$mime])){ $ext = $allowed[$mime]; }
    else {
        // try derive from original name
        $orig = isset($f['name']) ? strtolower($f['name']) : '';
        if(preg_match('/\.(gif|png|jpe?g)$/i', $orig, $m)){
            $ext = strtolower($m[1] === 'jpeg' ? 'jpg' : $m[1]);
        }
    }
    if(!$ext || !in_array($ext, ['gif','png','jpg'])){ echo json_encode(['success'=>false,'error'=>'Only GIF/PNG/JPG allowed']); exit; }
    // ensure assets dir exists and is writable
    $assetsDir = __DIR__ . DIRECTORY_SEPARATOR . 'assets';
    if(!is_dir($assetsDir)){
        if(!@mkdir($assetsDir, 0777, true)){
            echo json_encode(['success'=>false,'error'=>'Unable to create assets directory','detail'=>$assetsDir]); exit;
        }
    }
    if(!is_writable($assetsDir)){
        // try to chmod; if still not writable, report
        @chmod($assetsDir, 0777);
        if(!is_writable($assetsDir)){
            echo json_encode(['success'=>false,'error'=>'Assets directory not writable','detail'=>$assetsDir]); exit;
        }
    }
    // remove other logo variants to keep single active file
    foreach(['gif','png','jpg','jpeg'] as $e){ $p = $assetsDir . DIRECTORY_SEPARATOR . 'logo.' . $e; if(file_exists($p)) @unlink($p); }
    $dest = $assetsDir . DIRECTORY_SEPARATOR . 'logo.' . $ext;
    // try move_uploaded_file, then fall back to rename/copy if needed (Windows/IIS quirks)
    $moved = move_uploaded_file($tmp, $dest);
    if(!$moved){
        // Some environments require is_uploaded_file check and rename
        if(is_uploaded_file($tmp)){
            $moved = rename($tmp, $dest);
            if(!$moved){
                // final fallback: copy then unlink
                $moved = copy($tmp, $dest);
                if($moved){ @unlink($tmp); }
            }
        }
    }
    if(!$moved){
        $lastErr = function_exists('error_get_last') ? error_get_last() : null;
        echo json_encode(['success'=>false,'error'=>'Save failed','detail'=>$lastErr]); exit;
    }
    @chmod($dest, 0666);
    echo json_encode(['success'=>true,'path'=>'assets/logo.' . $ext]);
    exit;
}

// Delete server logo (GIF)
if(isset($_GET['action']) && $_GET['action']=="deleteLogo"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ http_response_code(403); echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ http_response_code(403); echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $assetsDir = __DIR__ . DIRECTORY_SEPARATOR . 'assets';
    $deleted = false;
    foreach(['gif','png','jpg','jpeg'] as $e){ $p = $assetsDir . DIRECTORY_SEPARATOR . 'logo.' . $e; if(file_exists($p) && @unlink($p)) $deleted = true; }
    echo json_encode(['success'=>$deleted, 'error'=> $deleted ? null : 'No logo']);
    exit;
}

// Upload files to target directory
if(isset($_GET['action']) && $_GET['action']=="uploadFiles"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ http_response_code(403); echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(isset($_SESSION['role']) && (int)$_SESSION['role'] === 3){ http_response_code(403); echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    
    $subPath = isset($_POST['subPath']) ? trim($_POST['subPath']) : '';
    if($subPath && (strpos($subPath, '..') !== false || strpos($subPath, ':') !== false)){ echo json_encode(['success'=>false,'error'=>'Invalid path']); exit; }
    
    $targetPath = realpath($targetDir);
    if($targetPath === false){ $targetPath = __DIR__ . DIRECTORY_SEPARATOR . $targetDir; }
    if(!is_dir($targetPath)){ echo json_encode(['success'=>false,'error'=>'Target directory not found']); exit; }
    
    $uploadPath = $targetPath;
    if($subPath !== ''){ 
        $uploadPath = $targetPath . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $subPath);
        if(!is_dir($uploadPath)){
            if(!@mkdir($uploadPath, 0777, true)){ echo json_encode(['success'=>false,'error'=>'Cannot create subdirectory']); exit; }
        }
    }
    
    if(!isset($_FILES['files']) || !is_array($_FILES['files'])){ echo json_encode(['success'=>false,'error'=>'No files']); exit; }
    
    $uploaded = [];
    $errors = [];
    
    $fileCount = count($_FILES['files']['name']);
    for($i = 0; $i < $fileCount; $i++){
        if($_FILES['files']['error'][$i] !== UPLOAD_ERR_OK){ $errors[] = $_FILES['files']['name'][$i] . ': Upload error'; continue; }
        
        $fileName = basename($_FILES['files']['name'][$i]);
        $tmpName = $_FILES['files']['tmp_name'][$i];
        $dest = $uploadPath . DIRECTORY_SEPARATOR . $fileName;
        
        $moved = move_uploaded_file($tmpName, $dest);
        if(!$moved){
            if(is_uploaded_file($tmpName)){
                $moved = rename($tmpName, $dest);
                if(!$moved){ $moved = copy($tmpName, $dest); if($moved){ @unlink($tmpName); } }
            }
        }
        
        if($moved){ 
            @chmod($dest, 0666); 
            $uploaded[] = $fileName; 
        } else { 
            $errors[] = $fileName . ': Save failed'; 
        }
    }
    
    echo json_encode(['success'=>true, 'uploaded'=>$uploaded, 'errors'=>$errors]);
    exit;
}

// List subdirectories in target directory
if(isset($_GET['action']) && $_GET['action']=="listSubdirs"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(isset($_SESSION['role']) && (int)$_SESSION['role'] === 3){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    
    $targetPath = realpath($targetDir);
    if($targetPath === false){ $targetPath = __DIR__ . DIRECTORY_SEPARATOR . $targetDir; }
    if(!is_dir($targetPath)){ echo json_encode(['success'=>false,'error'=>'Target directory not found']); exit; }
    
    $dirs = ['/' => 'Root'];
    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($targetPath, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
    foreach($iterator as $file){
        if($file->isDir()){
            $relative = str_replace($targetPath . DIRECTORY_SEPARATOR, '', $file->getPathname());
            $relative = str_replace(DIRECTORY_SEPARATOR, '/', $relative);
            $dirs[$relative] = $relative;
        }
    }
    
    echo json_encode(['success'=>true, 'dirs'=>$dirs]);
    exit;
}

// Browse files in directory
if(isset($_GET['action']) && $_GET['action']=="browseFiles"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    
    $subPath = isset($_GET['path']) ? trim($_GET['path']) : '';
    if($subPath && (strpos($subPath, '..') !== false || strpos($subPath, ':') !== false)){ echo json_encode(['success'=>false,'error'=>'Invalid path']); exit; }
    
    $targetPath = realpath($targetDir);
    if($targetPath === false){ $targetPath = __DIR__ . DIRECTORY_SEPARATOR . $targetDir; }
    if(!is_dir($targetPath)){ echo json_encode(['success'=>false,'error'=>'Target directory not found']); exit; }
    
    $browsePath = $targetPath;
    if($subPath !== ''){ 
        $browsePath = $targetPath . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $subPath);
    }
    
    if(!is_dir($browsePath)){ echo json_encode(['success'=>false,'error'=>'Directory not found']); exit; }
    
    $items = [];
    $iterator = new DirectoryIterator($browsePath);
    foreach($iterator as $file){
        if($file->isDot()) continue;
        
        $filename = $file->getFilename();
        
        // Patchlist ausblenden (case-insensitive)
        $lowerName = strtolower($filename);
        if($lowerName === 'patchlist' || strpos($lowerName, 'patchlist') === 0) continue;
        
        $relativePath = $subPath ? $subPath . '/' . $filename : $filename;
        
        $items[] = [
            'name' => $filename,
            'path' => $relativePath,
            'type' => $file->isDir() ? 'dir' : 'file',
            'size' => $file->isFile() ? $file->getSize() : 0,
            'modified' => $file->getMTime()
        ];
    }
    
    // Sort: directories first, then by name
    usort($items, function($a, $b){
        if($a['type'] !== $b['type']){ return $a['type'] === 'dir' ? -1 : 1; }
        return strcasecmp($a['name'], $b['name']);
    });
    
    echo json_encode(['success'=>true, 'items'=>$items, 'currentPath'=>$subPath]);
    exit;
}

// Delete file or directory
if(isset($_GET['action']) && $_GET['action']=="deleteFile"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    
    $raw = file_get_contents('php://input');
    $data = $raw ? json_decode($raw, true) : null;
    $filePath = isset($data['path']) ? trim($data['path']) : '';
    
    if($filePath === '' || strpos($filePath, '..') !== false || strpos($filePath, ':') !== false){ echo json_encode(['success'=>false,'error'=>'Invalid path']); exit; }
    
    $targetPath = realpath($targetDir);
    if($targetPath === false){ $targetPath = __DIR__ . DIRECTORY_SEPARATOR . $targetDir; }
    
    $fullPath = $targetPath . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $filePath);
    
    if(!file_exists($fullPath)){ echo json_encode(['success'=>false,'error'=>'File not found']); exit; }
    
    // Patchlist darf nicht gelöscht werden
    $filename = basename($fullPath);
    $lowerName = strtolower($filename);
    if($lowerName === 'patchlist' || strpos($lowerName, 'patchlist') === 0){
        echo json_encode(['success'=>false,'error'=>'Patchlist kann nicht gelöscht werden']);
        exit;
    }
    
    // Auch Pfade checken, die patchlist enthalten
    $lowerPath = strtolower($filePath);
    if(strpos($lowerPath, 'patchlist') !== false){
        echo json_encode(['success'=>false,'error'=>'Patchlist kann nicht gelöscht werden']);
        exit;
    }
    
    // Recursive delete function
    function deleteRecursive($path){
        if(is_dir($path)){
            $items = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
                RecursiveIteratorIterator::CHILD_FIRST
            );
            foreach($items as $item){
                $item->isDir() ? @rmdir($item->getRealPath()) : @unlink($item->getRealPath());
            }
            return @rmdir($path);
        } else {
            return @unlink($path);
        }
    }
    
    $deleted = deleteRecursive($fullPath);
    echo json_encode(['success'=>$deleted, 'error'=>$deleted ? null : 'Delete failed']);
    exit;
}

// Create new folder
if(isset($_GET['action']) && $_GET['action']=="createFolder"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    
    $raw = file_get_contents('php://input');
    $data = $raw ? json_decode($raw, true) : null;
    $folderPath = isset($data['path']) ? trim($data['path']) : '';
    $folderName = isset($data['name']) ? trim($data['name']) : '';
    
    if($folderName === '' || strpos($folderName, '..') !== false || strpos($folderName, ':') !== false || strpos($folderName, '/') !== false || strpos($folderName, '\\') !== false){ 
        echo json_encode(['success'=>false,'error'=>'Invalid folder name']); 
        exit; 
    }
    
    $targetPath = realpath($targetDir);
    if($targetPath === false){ $targetPath = __DIR__ . DIRECTORY_SEPARATOR . $targetDir; }
    
    $basePath = $targetPath;
    if($folderPath !== ''){ 
        if(strpos($folderPath, '..') !== false || strpos($folderPath, ':') !== false){ 
            echo json_encode(['success'=>false,'error'=>'Invalid path']); 
            exit; 
        }
        $basePath = $targetPath . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $folderPath);
    }
    
    if(!is_dir($basePath)){ echo json_encode(['success'=>false,'error'=>'Base directory not found']); exit; }
    
    $newFolderPath = $basePath . DIRECTORY_SEPARATOR . $folderName;
    
    if(file_exists($newFolderPath)){ echo json_encode(['success'=>false,'error'=>'Folder already exists']); exit; }
    
    $created = @mkdir($newFolderPath, 0777, true);
    if($created){
        @chmod($newFolderPath, 0777);
        echo json_encode(['success'=>true]);
    } else {
        echo json_encode(['success'=>false,'error'=>'Could not create folder']);
    }
    exit;
}

// Load discord patch content
if(isset($_GET['action']) && $_GET['action']=="loadDiscordPatch"){
    header('Content-Type: text/plain');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ http_response_code(403); echo "Not authenticated"; exit; }
    $id = isset($_GET['id']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['id']) : 'default';
    $file = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'patchlogs' . DIRECTORY_SEPARATOR . $id . '.txt';
    if(!file_exists($file)) { echo ""; exit; }
    $content = @file_get_contents($file);
    if($content === false) { http_response_code(500); echo "Error reading file"; exit; }
    echo $content;
    exit;
}

// Save patchlog content
// Activity logging helper
function logActivity($action, $target, $user, $meta = []){
    $logDir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'activity';
    if(!is_dir($logDir)){ mkdir($logDir, 0755, true); }
    
    $logFile = $logDir . DIRECTORY_SEPARATOR . 'activity.json';
    $logs = [];
    if(file_exists($logFile)){
        $raw = @file_get_contents($logFile);
        $logs = $raw ? json_decode($raw, true) : [];
        if(!is_array($logs)) $logs = [];
    }
    
    $entry = [
        'id' => uniqid('act_', true),
        'timestamp' => date('Y-m-d H:i:s'),
        'action' => $action,
        'target' => $target,
        'user' => $user,
        'meta' => $meta
    ];
    
    array_unshift($logs, $entry); // Add to beginning
    
    // Keep only last 500 entries
    if(count($logs) > 500){
        $logs = array_slice($logs, 0, 500);
    }
    
    @file_put_contents($logFile, json_encode($logs, JSON_PRETTY_PRINT));
    chmod($logFile, 0666);
}

// Get activity log
if(isset($_GET['action']) && $_GET['action']=="getActivityLog"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $logFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'activity' . DIRECTORY_SEPARATOR . 'activity.json';
    $logs = [];
    if(file_exists($logFile)){
        $raw = @file_get_contents($logFile);
        $logs = $raw ? json_decode($raw, true) : [];
        if(!is_array($logs)) $logs = [];
    }
    
    // Get last N entries
    $limit = isset($_GET['limit']) ? intval($_GET['limit']) : 50;
    $logs = array_slice($logs, 0, $limit);
    
    echo json_encode(['success'=>true,'logs'=>$logs]);
    exit;
}

if(isset($_GET['action']) && $_GET['action']=="savePatchlog"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    // Nur Rang 0 und 1 dürfen Patchlogs speichern
    $userRole = isset($_SESSION['role']) ? (int)$_SESSION['role'] : 1;
    if($userRole !== 0 && $userRole !== 1){
        echo json_encode(['success'=>false,'error'=>'Keine Berechtigung']);
        exit;
    }
    $content = isset($_POST['content']) ? $_POST['content'] : '';
    $name = isset($_POST['name']) ? trim($_POST['name']) : 'Unbenannt';
    $webhookId = isset($_POST['webhookId']) ? trim($_POST['webhookId']) : '';
    $id = isset($_POST['id']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['id']) : uniqid('patch_');
    
    $dir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'patchlogs';
    if(!is_dir($dir)){ mkdir($dir, 0755, true); }
    
    $file = $dir . DIRECTORY_SEPARATOR . $id . '.txt';
    
    // Save version history if file already exists
    if(file_exists($file)){
        $versionDir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'versions' . DIRECTORY_SEPARATOR . $id;
        if(!is_dir($versionDir)){ mkdir($versionDir, 0755, true); }
        
        $timestamp = time();
        $versionFile = $versionDir . DIRECTORY_SEPARATOR . 'v_' . $timestamp . '.txt';
        $oldContent = @file_get_contents($file);
        if($oldContent !== false){
            @file_put_contents($versionFile, $oldContent);
            chmod($versionFile, 0666);
            
            // Save version metadata
            $versionMetaFile = $versionDir . DIRECTORY_SEPARATOR . 'versions.json';
            $versionMeta = [];
            if(file_exists($versionMetaFile)){
                $raw = @file_get_contents($versionMetaFile);
                $versionMeta = $raw ? json_decode($raw, true) : [];
                if(!is_array($versionMeta)) $versionMeta = [];
            }
            $versionMeta[] = [
                'timestamp' => $timestamp,
                'date' => date('Y-m-d H:i:s', $timestamp),
                'user' => $_SESSION['username'] ?? 'Unknown',
                'file' => 'v_' . $timestamp . '.txt'
            ];
            @file_put_contents($versionMetaFile, json_encode($versionMeta, JSON_PRETTY_PRINT));
            chmod($versionMetaFile, 0666);
        }
    }
    
    if(@file_put_contents($file, $content) === false){ echo json_encode(['success'=>false,'error'=>'Could not write file']); exit; }
    chmod($file, 0666);
    
    // Save metadata
    $metaFile = $dir . DIRECTORY_SEPARATOR . 'meta.json';
    $meta = [];
    if(file_exists($metaFile)){
        $raw = @file_get_contents($metaFile);
        $meta = $raw ? json_decode($raw, true) : [];
        if(!is_array($meta)) $meta = [];
    }
    // Preserve pinned status if it exists
    $pinned = isset($meta[$id]['pinned']) ? $meta[$id]['pinned'] : false;
    $meta[$id] = ['name'=>$name, 'modified'=>date('Y-m-d H:i:s'), 'webhookId'=>$webhookId, 'pinned'=>$pinned];
    @file_put_contents($metaFile, json_encode($meta, JSON_PRETTY_PRINT));
    chmod($metaFile, 0666);
    
    // Log activity
    logActivity('patchlog_saved', $name, $_SESSION['username'] ?? 'Unknown', ['id'=>$id]);
    
    echo json_encode(['success'=>true,'id'=>$id]);
    exit;
}

// Get version history for a patchlog
if(isset($_GET['action']) && $_GET['action']=="getVersions"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $id = isset($_GET['id']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['id']) : '';
    if(empty($id)){ echo json_encode(['success'=>false,'error'=>'No ID provided']); exit; }
    
    $versionDir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'versions' . DIRECTORY_SEPARATOR . $id;
    $versionMetaFile = $versionDir . DIRECTORY_SEPARATOR . 'versions.json';
    
    if(!file_exists($versionMetaFile)){
        echo json_encode(['success'=>true,'versions'=>[]]);
        exit;
    }
    
    $raw = @file_get_contents($versionMetaFile);
    $versions = $raw ? json_decode($raw, true) : [];
    if(!is_array($versions)) $versions = [];
    
    // Sort by timestamp descending (newest first)
    usort($versions, function($a, $b){ return $b['timestamp'] - $a['timestamp']; });
    
    echo json_encode(['success'=>true,'versions'=>$versions]);
    exit;
}

// Restore a specific version
if(isset($_POST['action']) && $_POST['action']=="restoreVersion"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    // Rolle 3 darf wiederherstellen
    
    $id = isset($_POST['id']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['id']) : '';
    $timestamp = isset($_POST['timestamp']) ? intval($_POST['timestamp']) : 0;
    
    if(empty($id) || $timestamp <= 0){ echo json_encode(['success'=>false,'error'=>'Invalid parameters']); exit; }
    
    $versionDir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'versions' . DIRECTORY_SEPARATOR . $id;
    $versionFile = $versionDir . DIRECTORY_SEPARATOR . 'v_' . $timestamp . '.txt';
    
    if(!file_exists($versionFile)){ echo json_encode(['success'=>false,'error'=>'Version not found']); exit; }
    
    $versionContent = @file_get_contents($versionFile);
    if($versionContent === false){ echo json_encode(['success'=>false,'error'=>'Could not read version']); exit; }
    
    // Get patchlog name from meta
    $dir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'patchlogs';
    $metaFile = $dir . DIRECTORY_SEPARATOR . 'meta.json';
    $meta = [];
    if(file_exists($metaFile)){
        $raw = @file_get_contents($metaFile);
        $meta = $raw ? json_decode($raw, true) : [];
        if(!is_array($meta)) $meta = [];
    }
    $patchlogName = isset($meta[$id]['name']) ? $meta[$id]['name'] : $id;
    
    // Log activity before restoring
    logActivity('patchlog_restored', $patchlogName, $_SESSION['username'] ?? 'Unknown', ['id'=>$id, 'version'=>date('Y-m-d H:i:s', $timestamp)]);
    
    echo json_encode(['success'=>true,'content'=>$versionContent]);
    exit;
}

// Save embed template
if(isset($_POST['action']) && $_POST['action']=="saveEmbedTemplate"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $name = isset($_POST['name']) ? trim($_POST['name']) : '';
    $embedData = isset($_POST['embedData']) ? trim($_POST['embedData']) : '';
    
    if(empty($name) || empty($embedData)){ echo json_encode(['success'=>false,'error'=>'Name and embed data required']); exit; }
    
    $embedDir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'embeds';
    if(!is_dir($embedDir)){ mkdir($embedDir, 0755, true); }
    
    $embedFile = $embedDir . DIRECTORY_SEPARATOR . 'templates.json';
    $templates = [];
    if(file_exists($embedFile)){
        $raw = @file_get_contents($embedFile);
        $templates = $raw ? json_decode($raw, true) : [];
        if(!is_array($templates)) $templates = [];
    }
    
    $id = 'embed_' . time();
    $templates[$id] = [
        'name' => $name,
        'data' => json_decode($embedData, true),
        'created' => date('Y-m-d H:i:s'),
        'user' => $_SESSION['username'] ?? 'Unknown'
    ];
    
    @file_put_contents($embedFile, json_encode($templates, JSON_PRETTY_PRINT));
    chmod($embedFile, 0666);
    
    echo json_encode(['success'=>true,'id'=>$id]);
    exit;
}

// Get embed templates
if(isset($_GET['action']) && $_GET['action']=="getEmbedTemplates"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $embedFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'embeds' . DIRECTORY_SEPARATOR . 'templates.json';
    
    if(!file_exists($embedFile)){
        echo json_encode(['success'=>true,'templates'=>[]]);
        exit;
    }
    
    $raw = @file_get_contents($embedFile);
    $templates = $raw ? json_decode($raw, true) : [];
    if(!is_array($templates)) $templates = [];
    
    echo json_encode(['success'=>true,'templates'=>$templates]);
    exit;
}

// Delete embed template
if(isset($_POST['action']) && $_POST['action']=="deleteEmbedTemplate"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $id = isset($_POST['id']) ? trim($_POST['id']) : '';
    if(empty($id)){ echo json_encode(['success'=>false,'error'=>'ID required']); exit; }
    
    $embedFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'embeds' . DIRECTORY_SEPARATOR . 'templates.json';
    
    if(!file_exists($embedFile)){
        echo json_encode(['success'=>false,'error'=>'No templates found']);
        exit;
    }
    
    $raw = @file_get_contents($embedFile);
    $templates = $raw ? json_decode($raw, true) : [];
    if(!is_array($templates)) $templates = [];
    
    if(!isset($templates[$id])){
        echo json_encode(['success'=>false,'error'=>'Template not found']);
        exit;
    }
    
    unset($templates[$id]);
    @file_put_contents($embedFile, json_encode($templates, JSON_PRETTY_PRINT));
    
    echo json_encode(['success'=>true]);
    exit;
}

// Upload embed images
if(isset($_GET['action']) && $_GET['action']=="uploadEmbedImages"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $uploadDir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'uploads';
    if(!is_dir($uploadDir)){
        @mkdir($uploadDir, 0755, true);
    }
    
    $uploadedFiles = [];
    $errors = [];
    
    if(!isset($_FILES['images'])){
        echo json_encode(['success'=>false,'error'=>'No files uploaded']);
        exit;
    }
    
    $files = $_FILES['images'];
    $fileCount = is_array($files['name']) ? count($files['name']) : 1;
    
    for($i = 0; $i < $fileCount; $i++){
        $fileName = is_array($files['name']) ? $files['name'][$i] : $files['name'];
        $fileTmp = is_array($files['tmp_name']) ? $files['tmp_name'][$i] : $files['tmp_name'];
        $fileError = is_array($files['error']) ? $files['error'][$i] : $files['error'];
        $fileSize = is_array($files['size']) ? $files['size'][$i] : $files['size'];
        
        if($fileError !== UPLOAD_ERR_OK){
            $errors[] = $fileName . ': Upload error';
            continue;
        }
        
        // Validate file type
        $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
        if(!in_array($ext, ['jpg','jpeg','png','gif'])){
            $errors[] = $fileName . ': Invalid file type (only JPG, PNG, GIF allowed)';
            continue;
        }
        
        // Validate file size (max 10MB)
        if($fileSize > 10 * 1024 * 1024){
            $errors[] = $fileName . ': File too large (max 10MB)';
            continue;
        }
        
        // Generate unique filename
        $baseName = pathinfo($fileName, PATHINFO_FILENAME);
        $baseName = preg_replace('/[^a-zA-Z0-9_-]/', '_', $baseName);
        $newFileName = $baseName . '_' . time() . '_' . rand(1000,9999) . '.' . $ext;
        $targetPath = $uploadDir . DIRECTORY_SEPARATOR . $newFileName;
        
        if(move_uploaded_file($fileTmp, $targetPath)){
            $uploadedFiles[] = [
                'name' => $newFileName,
                'url' => 'data/uploads/' . $newFileName,
                'size' => $fileSize
            ];
        } else {
            $errors[] = $fileName . ': Failed to save file';
        }
    }
    
    echo json_encode([
        'success' => true,
        'uploaded' => $uploadedFiles,
        'errors' => $errors
    ]);
    exit;
}

// Delete embed image
if(isset($_GET['action']) && $_GET['action']=="deleteEmbedImage"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $fileName = $_POST['fileName'] ?? '';
    if(empty($fileName)){
        echo json_encode(['success'=>false,'error'=>'No filename provided']);
        exit;
    }
    
    // Security: prevent directory traversal
    $fileName = basename($fileName);
    
    $uploadDir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'uploads';
    $filePath = $uploadDir . DIRECTORY_SEPARATOR . $fileName;
    
    if(!file_exists($filePath)){
        echo json_encode(['success'=>false,'error'=>'File not found']);
        exit;
    }
    
    if(@unlink($filePath)){
        echo json_encode(['success'=>true]);
    } else {
        echo json_encode(['success'=>false,'error'=>'Failed to delete file']);
    }
    exit;
}

// Get uploaded images
if(isset($_GET['action']) && $_GET['action']=="getUploadedImages"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $uploadDir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'uploads';
    $images = [];
    
    if(is_dir($uploadDir)){
        $files = scandir($uploadDir);
        foreach($files as $file){
            if($file === '.' || $file === '..') continue;
            $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
            if(in_array($ext, ['jpg','jpeg','png','gif','webp','bmp'])){
                $images[] = [
                    'name' => $file,
                    'url' => 'data/uploads/' . $file,
                    'size' => filesize($uploadDir . DIRECTORY_SEPARATOR . $file)
                ];
            }
        }
    }
    
    echo json_encode(['success'=>true,'images'=>$images]);
    exit;
}

// Get all patchlogs
if(isset($_GET['action']) && $_GET['action']=="getPatchlogs"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $dir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'patchlogs';
    $metaFile = $dir . DIRECTORY_SEPARATOR . 'meta.json';
    
    $meta = [];
    if(file_exists($metaFile)){
        $raw = @file_get_contents($metaFile);
        $meta = $raw ? json_decode($raw, true) : [];
        if(!is_array($meta)) $meta = [];
    }
    
    $logs = [];
    foreach($meta as $id => $data){
        $file = $dir . DIRECTORY_SEPARATOR . $id . '.txt';
        if(file_exists($file)){
            $logs[] = [
                'id'=>$id, 
                'name'=>$data['name'], 
                'modified'=>$data['modified'],
                'webhookId'=>isset($data['webhookId']) ? $data['webhookId'] : '',
                'pinned'=>isset($data['pinned']) ? $data['pinned'] : false
            ];
        }
    }
    
    // Load custom order if exists
    $orderFile = $dir . DIRECTORY_SEPARATOR . 'order.json';
    $customOrder = [];
    if(file_exists($orderFile)){
        $raw = @file_get_contents($orderFile);
        $customOrder = $raw ? json_decode($raw, true) : [];
        if(!is_array($customOrder)) $customOrder = [];
    }
    
    // Sort by custom order if available, otherwise by modified date DESC
    if(!empty($customOrder)){
        usort($logs, function($a, $b) use ($customOrder){
            $posA = array_search($a['id'], $customOrder);
            $posB = array_search($b['id'], $customOrder);
            if($posA === false && $posB === false) return strcmp($b['modified'], $a['modified']);
            if($posA === false) return 1;
            if($posB === false) return -1;
            return $posA - $posB;
        });
    } else {
        usort($logs, function($a, $b){ return strcmp($b['modified'], $a['modified']); });
    }
    
    echo json_encode(['success'=>true,'logs'=>$logs]);
    exit;
}

// Delete patchlog
if(isset($_GET['action']) && $_GET['action']=="deletePatchlog"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $id = isset($_POST['id']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['id']) : '';
    if($id === ''){ echo json_encode(['success'=>false,'error'=>'Invalid ID']); exit; }
    
    // Get name for logging
    $dir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'patchlogs';
    $metaFile = $dir . DIRECTORY_SEPARATOR . 'meta.json';
    $patchlogName = 'Unknown';
    if(file_exists($metaFile)){
        $raw = @file_get_contents($metaFile);
        $meta = $raw ? json_decode($raw, true) : [];
        if(is_array($meta) && isset($meta[$id]['name'])){
            $patchlogName = $meta[$id]['name'];
        }
    }
    
    $dir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'patchlogs';
    $file = $dir . DIRECTORY_SEPARATOR . $id . '.txt';
    
    if(file_exists($file)){ @unlink($file); }
    
    // Remove from metadata
    $metaFile = $dir . DIRECTORY_SEPARATOR . 'meta.json';
    if(file_exists($metaFile)){
        $raw = @file_get_contents($metaFile);
        $meta = $raw ? json_decode($raw, true) : [];
        if(is_array($meta) && isset($meta[$id])){
            unset($meta[$id]);
            @file_put_contents($metaFile, json_encode($meta, JSON_PRETTY_PRINT));
        }
    }
    
    // Log activity
    logActivity('patchlog_deleted', $patchlogName, $_SESSION['username'] ?? 'Unknown', ['id'=>$id]);
    
    echo json_encode(['success'=>true]);
    exit;
}

// Toggle pin status
if(isset($_GET['action']) && $_GET['action']=="togglePinPatchlog"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $rawData = file_get_contents('php://input');
    $data = json_decode($rawData, true);
    $id = isset($data['id']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $data['id']) : '';
    
    if($id === ''){ echo json_encode(['success'=>false,'error'=>'Invalid ID']); exit; }
    
    $dir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'patchlogs';
    $metaFile = $dir . DIRECTORY_SEPARATOR . 'meta.json';
    
    $meta = [];
    if(file_exists($metaFile)){
        $raw = @file_get_contents($metaFile);
        $meta = $raw ? json_decode($raw, true) : [];
        if(!is_array($meta)) $meta = [];
    }
    
    if(!isset($meta[$id])){ echo json_encode(['success'=>false,'error'=>'Patchlog not found']); exit; }
    
    // Toggle pinned status
    $meta[$id]['pinned'] = !isset($meta[$id]['pinned']) || !$meta[$id]['pinned'];
    
    $saved = @file_put_contents($metaFile, json_encode($meta, JSON_PRETTY_PRINT));
    if($saved === false){ echo json_encode(['success'=>false,'error'=>'Could not save meta']); exit; }
    chmod($metaFile, 0666);
    
    echo json_encode(['success'=>true,'pinned'=>$meta[$id]['pinned']]);
    exit;
}

// Save patchlog order
if(isset($_GET['action']) && $_GET['action']=="savePatchlogOrder"){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    $order = isset($data['order']) && is_array($data['order']) ? $data['order'] : [];
    
    if(empty($order)){ echo json_encode(['success'=>false,'error'=>'Empty order']); exit; }
    
    $dir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'patchlogs';
    if(!is_dir($dir)){ @mkdir($dir, 0777, true); }
    
    $orderFile = $dir . DIRECTORY_SEPARATOR . 'order.json';
    $saved = @file_put_contents($orderFile, json_encode($order, JSON_PRETTY_PRINT));
    
    if($saved === false){
        echo json_encode(['success'=>false,'error'=>'Failed to save order']);
    } else {
        echo json_encode(['success'=>true]);
    }
    exit;
}

// Upload image for patchlog
if(isset($_GET['action']) && $_GET['action']=="uploadPatchlogImage"){
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ http_response_code(403); echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    header('Content-Type: application/json');
    if(!isset($_FILES['image']) || !is_array($_FILES['image'])){ echo json_encode(['success'=>false,'error'=>'No file']); exit; }
    $f = $_FILES['image'];
    if($f['error'] !== UPLOAD_ERR_OK){ echo json_encode(['success'=>false,'error'=>'Upload error','code'=>$f['error']]); exit; }
    
    // Check file size (10MB max)
    $maxSize = 10 * 1024 * 1024;
    if($f['size'] > $maxSize){ echo json_encode(['success'=>false,'error'=>'File too large (max 10MB)']); exit; }
    
    // Validate image mime
    $tmp = $f['tmp_name'];
    $mime = function_exists('mime_content_type') ? mime_content_type($tmp) : '';
    $allowed = ['image/gif'=>'gif','image/png'=>'png','image/jpeg'=>'jpg','image/webp'=>'webp'];
    $ext = '';
    if($mime && isset($allowed[$mime])){ $ext = $allowed[$mime]; }
    else {
        $orig = isset($f['name']) ? strtolower($f['name']) : '';
        if(preg_match('/\.(gif|png|jpe?g|webp)$/i', $orig, $m)){
            $ext = strtolower($m[1] === 'jpeg' ? 'jpg' : $m[1]);
        }
    }
    if(!$ext || !in_array($ext, ['gif','png','jpg','webp'])){ echo json_encode(['success'=>false,'error'=>'Only GIF/PNG/JPG/WEBP allowed']); exit; }
    
    // Create uploads directory
    $uploadsDir = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'uploads';
    if(!is_dir($uploadsDir)){
        if(!@mkdir($uploadsDir, 0777, true)){
            echo json_encode(['success'=>false,'error'=>'Unable to create uploads directory']); exit;
        }
    }
    
    // Generate unique filename
    $filename = uniqid('img_') . '.' . $ext;
    $dest = $uploadsDir . DIRECTORY_SEPARATOR . $filename;
    
    $moved = move_uploaded_file($tmp, $dest);
    if(!$moved){
        if(file_exists($tmp)){
            $moved = @rename($tmp, $dest) || @copy($tmp, $dest);
        }
    }
    
    if(!$moved || !file_exists($dest)){
        echo json_encode(['success'=>false,'error'=>'Failed to save file']); exit;
    }
    
    // Return relative URL
    $url = 'data/uploads/' . $filename;
    echo json_encode(['success'=>true,'url'=>$url,'filename'=>$filename]);
    exit;
}

// Send Discord patch (post a message to the configured webhook)
if(isset($_GET['action']) && $_GET['action']=="sendDiscordPatch"){
    header('Content-Type: text/plain');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ http_response_code(403); echo "Not authenticated"; exit; }
    // Rolle 3 darf Patchlogs senden
    $content = isset($_POST['message']) ? trim($_POST['message']) : '';
    if($content === ''){ http_response_code(400); echo "Empty message"; exit; }
    
    $webhookId = isset($_POST['webhookId']) ? trim($_POST['webhookId']) : '';
    
    // Load from multi-webhook system
    $webhooksFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'webhooks.json';
    $webhook = null;
    $enabled = false;
    
    if(!empty($webhookId) && file_exists($webhooksFile)){
        $raw = @file_get_contents($webhooksFile);
        $webhooks = $raw ? json_decode($raw, true) : null;
        if(is_array($webhooks)){
            foreach($webhooks as $wh){
                if($wh['id'] === $webhookId && !empty($wh['url'])){
                    $webhook = $wh['url'];
                    $enabled = !empty($wh['enabled']);
                    break;
                }
            }
        }
    }
    
    // Fallback to old single webhook config
    if(empty($webhook)){
        $cfgFile = __DIR__ . DIRECTORY_SEPARATOR . 'webhook-config.json';
        $webhook = $discordWebhook; $enabled = true;
        if(file_exists($cfgFile)){
            $raw = @file_get_contents($cfgFile);
            $j = $raw ? json_decode($raw, true) : null;
            if(is_array($j)){
                if(!empty($j['webhook'])) $webhook = $j['webhook'];
                $enabled = !empty($j['enabled']);
            }
        }
    }
    
    if(empty($webhook) || !$enabled){ http_response_code(400); echo "Webhook not configured or disabled"; exit; }
    
    // Build payload with optional embed support
    $payloadData = [];
    if(!empty($content)){
        $payloadData["content"] = $content;
    }
    
    // Check for embed data (fix: use embedJson as sent by JS)
    $embedJsonRaw = isset($_POST['embedJson']) ? trim($_POST['embedJson']) : '';
    if(!empty($embedJsonRaw)){
        $embedJson = @json_decode($embedJsonRaw, true);
        if($embedJson && isset($embedJson['embeds']) && is_array($embedJson['embeds'])){
            $payloadData['embeds'] = $embedJson['embeds'];
        }
    }
    
    // If only embed and no content, remove content field (Discord allows embed-only messages)
    if(empty($content) && !empty($payloadData['embeds'])){
        unset($payloadData['content']);
    }
    
    $payload = json_encode($payloadData);
    $ch = curl_init($webhook);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $resp = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if($resp === false || $status < 200 || $status >= 300){
        http_response_code(500);
        echo "Send failed (" . ($status ?: 'no status') . ")";
    } else {
        // Log activity
        $webhookName = 'Unknown';
        if(file_exists($webhooksFile)){
            $raw = @file_get_contents($webhooksFile);
            $webhooks = $raw ? json_decode($raw, true) : null;
            if(is_array($webhooks)){
                foreach($webhooks as $wh){
                    if($wh['id'] === $webhookId){
                        $webhookName = $wh['name'];
                        break;
                    }
                }
            }
        }
        $messagePreview = substr($content, 0, 50) . (strlen($content) > 50 ? '...' : '');
        logActivity('patchlog_sent', $webhookName, $_SESSION['username'] ?? 'Unknown', ['webhookId'=>$webhookId, 'preview'=>$messagePreview]);
        
        echo "Gesendet";
    }
    exit;
}

// --- User management endpoints (role 1 only) ---
if(isset($_GET['action']) && $_GET['action']==='listUsers'){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    try{
        $pdo = getUserDb($userDbFile);
        initUserDb($pdo, $USERNAME, $PASSWORD);
        $currentRole = (int)$_SESSION['role'];
        // Rolle 1 sieht keine Super-Admins (Rolle 0)
        if($currentRole === 1){
            $rows = $pdo->query('SELECT id, username, role, created_at FROM users WHERE role != 0 ORDER BY id ASC')->fetchAll(PDO::FETCH_ASSOC);
        } else {
            $rows = $pdo->query('SELECT id, username, role, created_at FROM users ORDER BY id ASC')->fetchAll(PDO::FETCH_ASSOC);
        }
        foreach($rows as &$r){ $r['created_at_readable'] = date('d.m.Y H:i', (int)$r['created_at']); }
        echo json_encode(['success'=>true,'users'=>$rows]);
    } catch(Exception $e){ echo json_encode(['success'=>false,'error'=>'DB error: '.$e->getMessage()]); }
    exit;
}
if(isset($_GET['action']) && $_GET['action']==='createUser'){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $raw = file_get_contents('php://input');
    $data = $raw ? json_decode($raw, true) : null;
    $username = isset($data['username']) ? trim($data['username']) : '';
    $password = isset($data['password']) ? (string)$data['password'] : '';
    $role = isset($data['role']) ? (int)$data['role'] : 2;
    if($username === '' || $password === '' || !in_array($role, [0,1,2,3])){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    try{
        $pdo = getUserDb($userDbFile);
        initUserDb($pdo, $USERNAME, $PASSWORD);
        $stmt = $pdo->prepare('INSERT INTO users (username, password_hash, role, created_at) VALUES (:u, :ph, :r, :ts)');
        $stmt->execute([':u'=>$username, ':ph'=>password_hash($password, PASSWORD_DEFAULT), ':r'=>$role, ':ts'=>time()]);
        echo json_encode(['success'=>true]);
    } catch(PDOException $e){
        $msg = strpos($e->getMessage(), 'UNIQUE') !== false ? 'Username existiert bereits' : ('DB error: '.$e->getMessage());
        echo json_encode(['success'=>false,'error'=>$msg]);
    } catch(Exception $e){ echo json_encode(['success'=>false,'error'=>'DB error: '.$e->getMessage()]); }
    exit;
}
if(isset($_GET['action']) && $_GET['action']==='updateUserRole'){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $raw = file_get_contents('php://input');
    $data = $raw ? json_decode($raw, true) : null;
    $username = isset($data['username']) ? trim($data['username']) : '';
    $role = isset($data['role']) ? (int)$data['role'] : 0;
    if($username === '' || !in_array($role, [0,1,2,3])){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    try{
        $pdo = getUserDb($userDbFile);
        initUserDb($pdo, $USERNAME, $PASSWORD);
        $stmt = $pdo->prepare('SELECT role FROM users WHERE username = :u');
        $stmt->execute([':u'=>$username]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if(!$row){ echo json_encode(['success'=>false,'error'=>'User not found']); exit; }
        if((int)$row['role'] === 0 && $role !== 0){
            echo json_encode(['success'=>false,'error'=>'Super-Admin (Rolle 0) kann nicht herabgestuft werden']); exit;
        }
        if((int)$row['role'] === 1 && $role !== 1){
            $cntAdmins = (int)$pdo->query('SELECT COUNT(*) AS c FROM users WHERE role IN (0, 1)')->fetch(PDO::FETCH_ASSOC)['c'];
            if($cntAdmins <= 1){ echo json_encode(['success'=>false,'error'=>'Letzter Admin kann nicht herabgestuft werden']); exit; }
        }
        $upd = $pdo->prepare('UPDATE users SET role = :r WHERE username = :u');
        $upd->execute([':r'=>$role, ':u'=>$username]);
        echo json_encode(['success'=>true]);
    } catch(Exception $e){ echo json_encode(['success'=>false,'error'=>'DB error: '.$e->getMessage()]); }
    exit;
}
if(isset($_GET['action']) && $_GET['action']==='resetUserPassword'){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $raw = file_get_contents('php://input');
    $data = $raw ? json_decode($raw, true) : null;
    $username = isset($data['username']) ? trim($data['username']) : '';
    $password = isset($data['password']) ? (string)$data['password'] : '';
    if($username === '' || $password === ''){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    try{
        $pdo = getUserDb($userDbFile);
        initUserDb($pdo, $USERNAME, $PASSWORD);
        $upd = $pdo->prepare('UPDATE users SET password_hash = :ph WHERE username = :u');
        $upd->execute([':ph'=>password_hash($password, PASSWORD_DEFAULT), ':u'=>$username]);
        echo json_encode(['success'=>true]);
    } catch(Exception $e){ echo json_encode(['success'=>false,'error'=>'DB error: '.$e->getMessage()]); }
    exit;
}
if(isset($_GET['action']) && $_GET['action']==='renameUser'){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $raw = file_get_contents('php://input');
    $data = $raw ? json_decode($raw, true) : null;
    $oldUsername = isset($data['oldUsername']) ? trim($data['oldUsername']) : '';
    $newUsername = isset($data['newUsername']) ? trim($data['newUsername']) : '';
    if($oldUsername === '' || $newUsername === ''){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    if($oldUsername === $newUsername){ echo json_encode(['success'=>false,'error'=>'Neuer Name ist identisch']); exit; }
    
    try{
        $pdo = getUserDb($userDbFile);
        initUserDb($pdo, $USERNAME, $PASSWORD);
        
        $result = executeWithRetry($pdo, function($pdo) use ($newUsername, $oldUsername){
            $pdo->exec('BEGIN IMMEDIATE');
            
            try{
                // Check if new username already exists
                $check = $pdo->prepare('SELECT COUNT(*) AS c FROM users WHERE username = :u');
                $check->execute([':u'=>$newUsername]);
                if((int)$check->fetch(PDO::FETCH_ASSOC)['c'] > 0){
                    $pdo->exec('ROLLBACK');
                    return ['success'=>false,'error'=>'Benutzername bereits vergeben'];
                }
                
                // Update username
                $upd = $pdo->prepare('UPDATE users SET username = :new WHERE username = :old');
                $upd->execute([':new'=>$newUsername, ':old'=>$oldUsername]);
                
                $pdo->exec('COMMIT');
                return ['success'=>true];
                
            } catch(Exception $e){
                $pdo->exec('ROLLBACK');
                throw $e;
            }
        });
        
        // If renaming own account, update session
        if($result['success'] && isset($_SESSION['user']) && $_SESSION['user'] === $oldUsername){
            $_SESSION['user'] = $newUsername;
        }
        
        echo json_encode($result);
        
    } catch(Exception $e){
        echo json_encode(['success'=>false,'error'=>'DB error: '.$e->getMessage()]);
    }
    exit;
}
if(isset($_GET['action']) && $_GET['action']==='deleteUser'){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || !in_array((int)$_SESSION['role'], [0, 1])){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $raw = file_get_contents('php://input');
    $data = $raw ? json_decode($raw, true) : null;
    $username = isset($data['username']) ? trim($data['username']) : '';
    if($username === ''){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    try{
        $pdo = getUserDb($userDbFile);
        initUserDb($pdo, $USERNAME, $PASSWORD);
        $stmt = $pdo->prepare('SELECT role FROM users WHERE username = :u');
        $stmt->execute([':u'=>$username]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if(!$row){ echo json_encode(['success'=>false,'error'=>'User not found']); exit; }
        // Super-Admin (Rolle 0) kann sich selbst löschen
        $currentRole = (int)$_SESSION['role'];
        $currentUser = isset($_SESSION['user']) ? $_SESSION['user'] : '';
        $targetRole = (int)$row['role'];
        // Wenn target Rolle 0 ist und aktueller User NICHT Rolle 0, dann verbieten
        if($targetRole === 0 && $currentRole !== 0){
            echo json_encode(['success'=>false,'error'=>'Super-Admin kann nur von Super-Admin gelöscht werden']); exit;
        }
        if((int)$row['role'] === 1){
            $cntAdmins = (int)$pdo->query('SELECT COUNT(*) AS c FROM users WHERE role = 1')->fetch(PDO::FETCH_ASSOC)['c'];
            if($cntAdmins <= 1){ echo json_encode(['success'=>false,'error'=>'Letzter Admin kann nicht gelöscht werden']); exit; }
        }
        $del = $pdo->prepare('DELETE FROM users WHERE username = :u');
        $del->execute([':u'=>$username]);
        echo json_encode(['success'=>true]);
    } catch(Exception $e){ echo json_encode(['success'=>false,'error'=>'DB error: '.$e->getMessage()]); }
    exit;
}

// ---------- COLOR SETTINGS (Rolle 0 only) ----------
if(isset($_GET['action']) && $_GET['action']==='getColorSettings'){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || (int)$_SESSION['role'] !== 0){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $colorFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'color-settings.json';
    $defaults = [
        'accent'=>'#ffb300',
        'glow1'=>'255,179,0',
        'glow2'=>'255,179,0',
        'cardHeading'=>'#e6eef9',
        'cardValue'=>'#ffffff',
        'ctaButton'=>'#ffb300',
        'headerBrand'=>'#ffb300',
        'primaryButton'=>'#4caf50',
        'icons'=>'#ffb300',
        'cardShadow'=>'0,0,0',
        'buttonShadow'=>'255,179,0',
        'iconShadow'=>'255,179,0',
        'sidebarBorder'=>'255,179,0',
        'sidebarBg'=>'17,19,23',
        'cardBg'=>'255,255,255',
        'cardBgOpacity'=>'0.02',
        'settingsBg'=>'255,255,255',
        'settingsBgOpacity'=>'0.02',
        'tableHeader'=>'255,179,0',
        'tableHover'=>'255,179,0'
    ];
    if(file_exists($colorFile)){
        $raw = @file_get_contents($colorFile);
        $j = $raw ? json_decode($raw, true) : null;
        if(is_array($j)){ $colors = array_merge($defaults, $j); } else { $colors = $defaults; }
    } else { $colors = $defaults; }
    echo json_encode(['success'=>true,'colors'=>$colors]);
    exit;
}
if(isset($_GET['action']) && $_GET['action']==='saveColorSettings'){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || (int)$_SESSION['role'] !== 0){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $raw = file_get_contents('php://input');
    $data = $raw ? json_decode($raw, true) : null;
    if(!is_array($data)){ echo json_encode(['success'=>false,'error'=>'Invalid payload']); exit; }
    $colorFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'color-settings.json';
    ensureDbDir($colorFile);
    if(@file_put_contents($colorFile, json_encode($data, JSON_PRETTY_PRINT)) === false){ echo json_encode(['success'=>false,'error'=>'Could not write file']); exit; }
    @chmod($colorFile, 0666);
    echo json_encode(['success'=>true,'colors'=>$data]);
    exit;
}
if(isset($_GET['action']) && $_GET['action']==='resetColorSettings'){
    header('Content-Type: application/json');
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ echo json_encode(['success'=>false,'error'=>'Not authenticated']); exit; }
    if(!isset($_SESSION['role']) || (int)$_SESSION['role'] !== 0){ echo json_encode(['success'=>false,'error'=>'Forbidden']); exit; }
    $colorFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'color-settings.json';
    if(file_exists($colorFile)){ @unlink($colorFile); }
    $defaults = [
        'accent'=>'#ffb300',
        'glow1'=>'255,179,0',
        'glow2'=>'255,179,0',
        'cardHeading'=>'#e6eef9',
        'cardValue'=>'#ffffff',
        'ctaButton'=>'#ffb300',
        'headerBrand'=>'#ffb300',
        'primaryButton'=>'#4caf50',
        'icons'=>'#ffb300',
        'cardShadow'=>'0,0,0',
        'buttonShadow'=>'255,179,0',
        'iconShadow'=>'255,179,0',
        'sidebarBorder'=>'255,179,0',
        'sidebarBg'=>'17,19,23',
        'cardBg'=>'255,255,255',
        'cardBgOpacity'=>'0.02',
        'settingsBg'=>'255,255,255',
        'settingsBgOpacity'=>'0.02',
        'tableHeader'=>'255,179,0',
        'tableHover'=>'255,179,0'
    ];
    echo json_encode(['success'=>true,'colors'=>$defaults]);
    exit;
}
// ---------- PATCHLIST GENERATOR (from user snippet) ----------
if(isset($_GET['action']) && $_GET['action']=="generate"){
    if(!isset($_SESSION['loggedin']) || !$_SESSION['loggedin']){ http_response_code(403); echo "Not authenticated"; exit; }
    if(isset($_SESSION['role']) && (int)$_SESSION['role'] === 3){ http_response_code(403); echo "Forbidden"; exit; }
    if(!is_dir($targetPath)){
        echo "Directory not found: $targetPath\n";
        exit;
    }

    header('Content-Type: text/plain');
    ob_implicit_flush(true);
    while (@ob_end_flush());

    function hashFileXxh32(string $filePath): string {
        $handle = fopen($filePath, 'rb');
        if (!$handle) throw new Exception("Cannot open file: $filePath");

        // Use xxh32 if available, otherwise fall back to md5 for compatibility
        $algo = in_array('xxh32', hash_algos()) ? 'xxh32' : 'md5';
        $hashContext = hash_init($algo);
        while (!feof($handle)) {
            $chunk = fread($handle, 64 * 1024);
            if ($chunk === false) throw new Exception("Failed to read file: $filePath");
            hash_update($hashContext, $chunk);
        }

        fclose($handle);
        return hash_final($hashContext);
    }

    $patchFile = $targetPath . DIRECTORY_SEPARATOR . 'patchlist';
    $oldHashes = [];
    if (file_exists($patchFile)) {
        $lines = file($patchFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        foreach ($lines as $line) {
            [$file, $hash] = explode('::', $line);
            $oldHashes[$file] = $hash;
        }
    }

    $files = [];
    $ignoreList = ['patchlist', 'patchlist1'];
    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($targetPath, RecursiveDirectoryIterator::SKIP_DOTS));
    foreach ($iterator as $file) {
        if ($file->isFile()) {
            $filePath = $file->getPathname();
            $skip = false;
            foreach ($ignoreList as $ignore) {
                if (stripos($filePath, $ignore) !== false) { $skip = true; break; }
            }
            if ($skip) continue;
            $files[] = $filePath;
        }
    }

    $totalFiles = count($files);
    echo "TOTAL::$totalFiles\n";
    flush();

    $patchlist = '';
    $fileIndex = 0;
    $changedFiles = [];

    foreach($files as $filePath){
        $fileIndex++;
        $relative = ltrim(str_replace(realpath($targetPath), '', realpath($filePath)), DIRECTORY_SEPARATOR);
        $relativeBackslash = str_replace('/', '\\', $relative);

        $hash = hashFileXxh32($filePath);
        $decimalHash = hexdec(substr($hash, 0, 8));
        $patchlist .= $relativeBackslash . '::' . $decimalHash . "\n";

        if (!isset($oldHashes[$relativeBackslash]) || $oldHashes[$relativeBackslash] != $decimalHash) {
            $changedFiles[] = $relativeBackslash;
            echo "PROGRESS::$fileIndex::$relativeBackslash::CHANGED\n";
        } else {
            echo "PROGRESS::$fileIndex::$relativeBackslash\n";
        }
        flush();
    }

    $lines = array_filter(array_map('trim', explode("\n", $patchlist)));
    $patchlistWin = implode("\r\n", $lines);
    file_put_contents($patchFile, $patchlistWin);
    chmod($patchFile, 0777);
    echo "DONE\n";
    flush();

    if(!empty($discordWebhook)){
        $embeds = [];
        if (!empty($changedFiles)) {
            $embeds[] = ["title"=>"Patchlist Completed ✅","description"=>implode("\n",$changedFiles),"color"=>3066993];
        } else {
            $embeds[] = ["title"=>"Patchlist Completed ✅","description"=>"No files changed.","color"=>15105570];
        }
        $payload = json_encode(["embeds"=>$embeds]);
        $ch = curl_init($discordWebhook);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_exec($ch);
        curl_close($ch);
    }

    exit;
}
// Patchlist generator (handled by GET action)
$getDiscordWebhookName = function($url){
    if(empty($url)) return null;
    $name = null;
    try{
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 3);
        $resp = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if($resp !== false && $status>=200 && $status<300){
            $j = json_decode($resp, true);
            if(is_array($j) && isset($j['name'])) $name = $j['name'];
        }
    } catch(Exception $e){}
    return $name;
};

// Compute dashboard stats used in template
$patchStats = ['exists'=>false, 'lines'=>0, 'size'=>0, 'mtime'=>0];
$totalFilesCount = 0;
$lastPatchLog = '';
// If a webhook config file exists, prefer it over default variable
$cfgFile = __DIR__ . DIRECTORY_SEPARATOR . 'webhook-config.json';
if(file_exists($cfgFile)){
    $raw = file_get_contents($cfgFile);
    $j = json_decode($raw, true);
    if(is_array($j) && isset($j['webhook'])){ $discordWebhook = $j['webhook']; $discordConfigured = !empty($j['enabled']); } else { $discordConfigured = !empty($discordWebhook); }
} else { $discordConfigured = !empty($discordWebhook); }

$discordWebhookName = null;
if($discordConfigured && !empty($discordWebhook)){
    $discordWebhookName = $getDiscordWebhookName($discordWebhook);
}

// compute total files in target directory (excluding patchlist files)
// Prefer script-relative path if realpath fails for relative $targetDir
$targetPath = realpath($targetDir);
if($targetPath === false){ $targetPath = __DIR__ . DIRECTORY_SEPARATOR . $targetDir; }
if($targetPath && is_dir($targetPath)){
    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($targetPath, RecursiveDirectoryIterator::SKIP_DOTS));
    foreach($it as $f){ if($f->isFile()){ $fname = $f->getFilename(); if(in_array($fname, ['patchlist','patchlist1'])) continue; $totalFilesCount++; } }
}

// compute patchlist stats if file exists
$patchFilePath = $targetPath . DIRECTORY_SEPARATOR . 'patchlist';
if(file_exists($patchFilePath)){
    $patchStats['exists'] = true;
    $lines = file($patchFilePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    $patchStats['lines'] = count($lines);
    $patchStats['size'] = filesize($patchFilePath);
    $patchStats['mtime'] = filemtime($patchFilePath);
}

// last patch log
$patchLogFile = __DIR__ . DIRECTORY_SEPARATOR . 'patchlog.txt';
if(file_exists($patchLogFile)){
    $lastPatchLog = @file_get_contents($patchLogFile);
}

// Load color settings if exists
$colorFile = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'color-settings.json';
$customColors = [
    'accent'=>'#ffb300',
    'glow1'=>'255,179,0',
    'glow2'=>'255,179,0',
    'cardHeading'=>'#e6eef9',
    'cardValue'=>'#ffffff',
    'ctaButton'=>'#ffb300',
    'headerBrand'=>'#ffb300',
    'primaryButton'=>'#4caf50',
    'icons'=>'#ffb300',
    'cardShadow'=>'0,0,0',
    'buttonShadow'=>'255,179,0',
    'iconShadow'=>'255,179,0',
    'sidebarBorder'=>'255,179,0',
    'sidebarBg'=>'17,19,23',
    'cardBg'=>'255,255,255',
    'cardBgOpacity'=>'0.02',
    'settingsBg'=>'255,255,255',
    'settingsBgOpacity'=>'0.02',
    'tableHeader'=>'255,179,0',
    'tableHover'=>'255,179,0'
];
if(file_exists($colorFile)){
    $raw = @file_get_contents($colorFile);
    $j = $raw ? json_decode($raw, true) : null;
    if(is_array($j)){ $customColors = array_merge($customColors, $j); }
}

?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Admin</title>
<link rel="icon" type="image/gif" href="assets/logo.gif">
<!-- Site CSS -->
<!-- EasyMDE CSS (editor styling) -->
<link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css">
<!-- Font Awesome (Used by EasyMDE toolbar) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
<link rel="stylesheet" href="assets/admin.css">
<!-- Custom Color Variables -->
<style>
:root {
    --accent: <?= htmlspecialchars($customColors['accent']) ?> !important;
    --glow-rgb-1: <?= htmlspecialchars($customColors['glow1']) ?>;
    --glow-rgb-2: <?= htmlspecialchars($customColors['glow2']) ?>;
    --card-heading-color: <?= htmlspecialchars($customColors['cardHeading']) ?>;
    --card-value-color: <?= htmlspecialchars($customColors['cardValue']) ?>;
    --cta-button-color: <?= htmlspecialchars($customColors['ctaButton']) ?>;
    --header-brand-color: <?= htmlspecialchars($customColors['headerBrand']) ?>;
    --primary-button-color: <?= htmlspecialchars($customColors['primaryButton']) ?>;
    --icons-color: <?= htmlspecialchars($customColors['icons']) ?>;
    --card-shadow-rgb: <?= htmlspecialchars($customColors['cardShadow']) ?>;
    --button-shadow-rgb: <?= htmlspecialchars($customColors['buttonShadow']) ?>;
    --icon-shadow-rgb: <?= htmlspecialchars($customColors['iconShadow']) ?>;
    --sidebar-border-rgb: <?= htmlspecialchars($customColors['sidebarBorder']) ?>;
    --sidebar-bg-rgb: <?= htmlspecialchars($customColors['sidebarBg']) ?>;
    --card-bg-rgb: <?= htmlspecialchars($customColors['cardBg']) ?>;
    --card-bg-opacity: <?= htmlspecialchars($customColors['cardBgOpacity']) ?>;
    --settings-bg-rgb: <?= htmlspecialchars($customColors['settingsBg']) ?>;
    --settings-bg-opacity: <?= htmlspecialchars($customColors['settingsBgOpacity']) ?>;
    --table-header-rgb: <?= htmlspecialchars($customColors['tableHeader']) ?>;
    --table-hover-rgb: <?= htmlspecialchars($customColors['tableHover']) ?>;
}
/* Card Styling */
.card h3 { color: var(--card-heading-color) !important; }
.card .value { color: var(--card-value-color) !important; }
.card { 
    background: linear-gradient(180deg, rgba(var(--card-bg-rgb), var(--card-bg-opacity)), rgba(var(--card-bg-rgb), calc(var(--card-bg-opacity) * 0.5))) !important;
    box-shadow: 0 6px 18px rgba(var(--card-shadow-rgb), 0.6) !important; 
}
.card:hover { box-shadow: 0 8px 24px rgba(var(--card-shadow-rgb), 0.8) !important; }
/* Settings Card Styling */
.settings-card {
    background: linear-gradient(180deg, rgba(var(--settings-bg-rgb), var(--settings-bg-opacity)), rgba(var(--settings-bg-rgb), calc(var(--settings-bg-opacity) * 0.5))) !important;
}
.settings-card-header {
    background: linear-gradient(90deg, rgba(var(--glow-rgb-1), 0.08), rgba(var(--glow-rgb-1), 0.02)) !important;
}
/* Header Brand */
.header .brand span { color: var(--header-brand-color) !important; }
/* Sidebar */
.sidebar { 
    border-right: 1px solid rgba(var(--sidebar-border-rgb), 0.15) !important;
    background: linear-gradient(165deg, rgba(var(--sidebar-bg-rgb), 0.98), rgba(var(--sidebar-bg-rgb), 0.98)) !important;
    box-shadow: 4px 0 32px rgba(0,0,0,0.5), inset -1px 0 2px rgba(var(--sidebar-border-rgb), 0.05) !important;
}
.sidebar::before{
    background: radial-gradient(ellipse at top, rgba(var(--sidebar-border-rgb), 0.08), transparent) !important;
}
.sidebar .brand { 
    background: linear-gradient(135deg, rgba(var(--sidebar-border-rgb), 0.12), rgba(var(--sidebar-border-rgb), 0.04)) !important;
    border-bottom: 1px solid rgba(var(--sidebar-border-rgb), 0.15) !important;
    box-shadow: 0 4px 16px rgba(0,0,0,0.3) !important;
}
.sidebar .brand::after {
    background: linear-gradient(90deg, transparent, rgba(var(--sidebar-border-rgb), 0.4), transparent) !important;
}
.sidebar .brand > div:first-child { 
    background: linear-gradient(135deg, rgba(var(--sidebar-border-rgb), 0.15), rgba(var(--sidebar-border-rgb), 0.05)) !important;
    border: 1px solid rgba(var(--sidebar-border-rgb), 0.2) !important;
    box-shadow: 0 4px 12px rgba(var(--sidebar-border-rgb), 0.2), inset 0 1px 0 rgba(255,255,255,0.1) !important;
}
.sidebar .brand > div:first-child img { 
    filter: drop-shadow(0 2px 8px rgba(var(--icon-shadow-rgb), 0.6)) !important; 
}
.sidebar .brand > div:last-child > div { 
    color: var(--accent) !important;
    text-shadow: 0 2px 12px rgba(var(--icon-shadow-rgb), 0.5) !important; 
}
.sidebar .brand small {
    color: rgba(var(--sidebar-border-rgb), 0.5) !important;
}
/* Icon Shadows */
.sidebar .menu .btn i,
.header i,
.card i,
button i {
    filter: drop-shadow(0 2px 6px rgba(var(--icon-shadow-rgb), 0.5)) !important;
}
/* Card Titles and Values with Text Shadow */
.card h3 {
    text-shadow: 0 2px 6px rgba(var(--icon-shadow-rgb), 0.3) !important;
}
.card .value {
    text-shadow: 0 2px 8px rgba(var(--icon-shadow-rgb), 0.2) !important;
}
.sidebar .menu .btn:hover { 
    background: linear-gradient(90deg, rgba(var(--sidebar-border-rgb), 0.12), rgba(var(--sidebar-border-rgb), 0.06)) !important;
    border-color: rgba(var(--sidebar-border-rgb), 0.25) !important;
    box-shadow: 0 6px 20px rgba(var(--sidebar-border-rgb), 0.15), inset 0 1px 0 rgba(255,255,255,0.05) !important;
}
.sidebar .menu .btn:hover i {
    filter: drop-shadow(0 3px 12px rgba(var(--icon-shadow-rgb), 0.8)) !important;
}
.sidebar .kicker { 
    color: rgba(var(--sidebar-border-rgb), 0.5) !important; 
}
.sidebar hr { 
    border-top: 1px solid rgba(var(--sidebar-border-rgb), 0.1) !important; 
    box-shadow: 0 1px 0 rgba(var(--sidebar-border-rgb), 0.05) !important;
}
.sidebar #changedFilesList {
    background: linear-gradient(135deg, rgba(0,0,0,0.3), rgba(0,0,0,0.2)) !important;
    border: 1px solid rgba(var(--sidebar-border-rgb), 0.08) !important;
}
.sidebar #changedFilesList::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(var(--sidebar-border-rgb), 0.4), rgba(var(--sidebar-border-rgb), 0.2)) !important;
}
.sidebar #changedFilesList::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, rgba(var(--sidebar-border-rgb), 0.6), rgba(var(--sidebar-border-rgb), 0.3)) !important;
}
</style>
<!-- Inline progress bar styles (fallback if assets css is missing) -->
<style>
/* Progress bar container */
#progress-container{ width:100%; background:rgba(255,255,255,0.04); border-radius:8px; padding:3px; box-sizing:border-box; height:28px; margin:6px 0 14px; }
/* Actual progress fill */
#progress-bar{ display:block; height:100%; width:0%; background:linear-gradient(90deg,#28a745,#17a2b8); color:#ffffff; font-weight:700; padding:4px 8px; box-sizing:border-box; border-radius:6px; text-align:center; transition: width 250ms ease; white-space:nowrap; overflow:hidden; }
/* Small devices */
@media (max-width:640px){ #progress-container{height:22px;} #progress-bar{font-size:12px;padding:2px 6px;} }
</style>
</head>
<body>

<?php if(!isset($_SESSION['loggedin'])): ?>
<h2 style="text-align:center;">Login</h2>
<form method="post" class="login-form">
    <?php if($error): ?><div class="error"><?=$error?></div><?php endif; ?>
    <label for="user">Benutzername</label>
    <input type="text" id="user" name="user" placeholder="Benutzername" required style="width:100%; padding:10px; margin:6px 0; border-radius:6px; border:1px solid #444; background:#111; color:#e0e0e0;" />
    <label for="pass">Passwort</label>
    <input type="password" id="pass" name="pass" placeholder="Passwort" required style="width:100%; padding:10px; margin:6px 0; border-radius:6px; border:1px solid #444; background:#111; color:#e0e0e0;" />
    <div style="margin-top:8px;text-align:center;"><button type="submit" name="login" class="btn primary"><i class="fa fa-sign-in-alt" aria-hidden="true"></i> Login</button></div>
    </form>
<?php else: ?>

<div class="app">
    <aside class="sidebar" role="navigation">
        <div class="brand">
            <?php
                $sidebarLogoRel = '';
                foreach(['gif','png','jpg','jpeg'] as $e){
                    $p = __DIR__ . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'logo.' . $e;
                    if(file_exists($p)){ $sidebarLogoRel = 'assets/logo.' . $e; break; }
                }
            ?>
            <div>
                <?php if($sidebarLogoRel): ?>
                    <img id="sidebarLogo" src="<?= htmlspecialchars($sidebarLogoRel) ?>" alt="Logo" style="height:32px; width:auto; filter: drop-shadow(0 2px 8px rgba(var(--icon-shadow-rgb, 255,179,0),0.5));" />
                <?php else: ?>
                    🌐
                <?php endif; ?>
            </div>
            <div>
                <div>Admin</div>
                <small>Dashboard</small>
            </div>
        </div>
        <nav class="menu" aria-label="Main">
            <button class="btn ghost" onclick="showDashboard()"><i class="fa fa-home" aria-hidden="true"></i> Dashboard</button>
            <?php $userRole = isset($_SESSION['role']) ? (int)$_SESSION['role'] : 1; ?>
            <?php if($userRole === 0 || $userRole === 1): ?>
            <button class="btn ghost" onclick="showPatchlist()"><i class="fa fa-list" aria-hidden="true"></i> Patchlist</button>
            <button class="btn ghost" onclick="showFileBrowser()"><i class="fa fa-folder-open" aria-hidden="true"></i> Datei Browser</button>
            <?php endif; ?>
            <?php if($userRole !== 3): ?>
            <button class="btn ghost" onclick="showDiscordPatchLogs()"><i class="fa fa-comments" aria-hidden="true"></i> Discord Patch Logs</button>
            <button class="btn ghost" onclick="showSettings()"><i class="fa fa-cog" aria-hidden="true"></i> Einstellungen</button>
            <?php endif; ?>
        </nav>
        <hr style="border-color:rgba(255,255,255,0.03);margin:12px 0">
        <div class="kicker">Geänderte Dateien</div>
        <ul id="changedFilesList" style="list-style:none;padding-left:8px;color:var(--muted);max-height:300px;overflow-y:auto;margin-top:8px"></ul>
    </aside>

    <main class="content" id="main">
        <div class="header">
            <div class="brand">
                <?php
                    $logoFileRel = '';
                    foreach(['gif','png','jpg','jpeg'] as $e){
                        $p = __DIR__ . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR . 'logo.' . $e;
                        if(file_exists($p)){ $logoFileRel = 'assets/logo.' . $e; break; }
                    }
                ?>
                <img id="brandLogo" src="<?= $logoFileRel ? htmlspecialchars($logoFileRel) : 'assets/logo.gif' ?>" alt="Logo" style="height:24px; vertical-align:middle; margin-right:8px; display:<?= $logoFileRel ? 'inline' : 'none' ?>;" />
                <span style="font-weight:900"><?=$sname?></span>
                <small class="muted">Admin-Panel</small>
            </div>
            <div class="flex">
                <?php if($userRole === 0 || $userRole === 1 || $userRole === 2): ?>
                <button class="btn ghost" onclick="showSettings()"><i class="fa fa-cog" aria-hidden="true"></i> Einstellungen</button>
                <?php endif; ?>
                <?php if($userRole === 0): ?>
                <button id="clearCacheBtnHeader" class="btn ghost"><i class="fa fa-sync-alt" aria-hidden="true"></i> Cache leeren</button>
                <?php endif; ?>
                <form method="get" style="margin:0"><button class="btn warn" type="submit" name="logout"><i class="fa fa-sign-out-alt" aria-hidden="true"></i> Logout</button></form>
            </div>
        </div>

    <!-- Dashboard -->
    <div id="dashboard">
        <h1>Dashboard</h1>
        <p class="kicker">Willkommen im Adminbereich!</p>
        
        <!-- Cards Toolbox Toggle Button -->
        <div id="toolboxToggle" style="position:fixed;top:50%;right:0;transform:translateY(-50%);width:50px;height:80px;background:linear-gradient(90deg, rgba(var(--glow-rgb-1, 255,179,0),0.15), rgba(var(--glow-rgb-1, 255,179,0),0.25));border:1px solid rgba(var(--glow-rgb-1, 255,179,0),0.3);border-right:none;border-radius:12px 0 0 12px;box-shadow:-4px 0 20px rgba(0,0,0,0.4);z-index:1000;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all 0.3s ease;backdrop-filter:blur(10px);" onmouseenter="this.style.boxShadow='-6px 0 30px rgba(var(--glow-rgb-1, 255,179,0),0.5)';this.querySelector('i').style.transform='scale(1.1)'" onmouseleave="this.style.boxShadow='-4px 0 20px rgba(0,0,0,0.4)';this.querySelector('i').style.transform='scale(1)'">
            <i class="fa fa-box" style="color:var(--accent);font-size:24px;filter:drop-shadow(0 2px 8px rgba(var(--icon-shadow-rgb, 255,179,0),0.6));transition:transform 0.3s ease;"></i>
        </div>
        
        <!-- Cards Toolbox -->
        <div id="cardsToolbox" style="position:fixed;top:80px;right:-300px;width:280px;max-height:calc(100vh - 120px);background:linear-gradient(135deg, rgba(255,255,255,0.05), rgba(255,255,255,0.02));border:1px solid rgba(var(--glow-rgb-1, 255,179,0),0.25);border-radius:16px 0 0 16px;box-shadow:-8px 0 32px rgba(0,0,0,0.6);z-index:999;overflow:visible;backdrop-filter:blur(10px);transition:right 0.4s cubic-bezier(0.4, 0, 0.2, 1);pointer-events:all;">
            <div style="background:linear-gradient(135deg, rgba(var(--glow-rgb-1, 255,179,0),0.2), rgba(var(--glow-rgb-1, 255,179,0),0.1));padding:14px 18px;border-bottom:1px solid rgba(var(--glow-rgb-1, 255,179,0),0.3);display:flex;justify-content:space-between;align-items:center;">
                <div style="display:flex;align-items:center;gap:10px;">
                    <i class="fa fa-box" style="color:var(--accent);font-size:18px;filter:drop-shadow(0 2px 6px rgba(var(--icon-shadow-rgb, 255,179,0),0.6));"></i>
                    <span style="font-weight:800;font-size:15px;color:var(--text);letter-spacing:0.5px;">Cards Box</span>
                </div>
                <button onclick="closeToolbox()" style="background:transparent;border:1px solid rgba(255,255,255,0.1);color:var(--text);padding:4px 8px;border-radius:6px;cursor:pointer;font-size:12px;transition:all 0.2s;"><i class="fa fa-times"></i></button>
            </div>
            <div id="toolboxCards" class="toolbox-content cards" style="padding:12px;display:grid;grid-template-columns:1fr;gap:8px;max-height:calc(100vh - 200px);overflow-y:auto;overflow-x:visible;min-height:100px;position:relative;pointer-events:all;">
                <div class="card klein" data-card-id="files-card">
                <div class="card-actions"><div class="drag-handle" draggable="true" role="button" aria-label="Verschiebe Karte" tabindex="0" title="Verschiebe Karte">⠿</div></div>
                <h3>📁 Dateien im Zielordner</h3>
                <div class="value"><?=number_format($totalFilesCount, 0, ',', '.')?></div>
                <div class="meta">Zielordner: <code><?=$targetDir?></code></div>
                <small>Anzahl der gefundenen Dateien (ohne Patchlist)</small>
            </div>
            <?php if($userRole === 0 || $userRole === 1): ?>
            <div class="card mittel" data-card-id="patchlist-card">
                <div class="card-actions"><div class="drag-handle" draggable="true" role="button" aria-label="Verschiebe Karte" tabindex="0" title="Verschiebe Karte">⠿</div></div>
                <h3>📝 Patchlist</h3>
                <?php if($patchStats['exists']): ?>
                    <div class="value"><?=number_format($patchStats['lines'], 0, ',', '.')?> Einträge</div>
                    <div class="meta">Größe: <?=round($patchStats['size']/1024, 2)?> KB</div>
                    <div class="meta">Letzte Aktualisierung: <?=date('d.m.Y H:i', $patchStats['mtime'])?></div>
                <?php else: ?>
                    <div class="value">—</div>
                    <div class="meta">Keine Patchlist gefunden</div>
                <?php endif; ?>
                <button class="cta secondary" onclick="showPatchlist();"><i class="fa fa-list" aria-hidden="true"></i> Patchlist anzeigen</button>
            </div>
            <?php endif; ?>
            <!-- Large card (Gross) should be directly here so first row becomes Klein, Mittel, Gross -->
            <?php if($userRole === 0 || $userRole === 1): ?>
            <div class="card groß gross large" data-card-id="lastlog-large-card">
                <div class="card-actions"><div class="drag-handle" draggable="true" role="button" aria-label="Verschiebe Karte" tabindex="0" title="Verschiebe Karte">⠿</div></div>
                <h3>📣 Letzter Patch Log</h3>
                <?php if($lastPatchLog): ?>
                    <div class="value" style="font-size:14px; font-weight:600; color:#cfd8dc; white-space:pre-line; max-height:58px; overflow:hidden;"><?=nl2br(htmlspecialchars($lastPatchLog))?></div>
                <?php else: ?>
                    <div class="value">—</div>
                    <div class="meta">"Yang ->"</div>
                <?php endif; ?>
                <button class="cta" onclick="showPatchlist(); startPatchFromDashboard();"><i class="fa fa-plus-circle" aria-hidden="true"></i> Patch erstellen</button>
            </div>
            <?php endif; ?>
            <!-- Second row: other small cards -->
            <div class="card klein" data-card-id="discord-card">
                <div class="card-actions"><div class="drag-handle" draggable="true" role="button" aria-label="Verschiebe Karte" tabindex="0" title="Verschiebe Karte">⠿</div></div>
                <h3>🔔 Discord Webhooks</h3>
                <div id="webhookStatusContainer" style="display:flex;flex-direction:column;gap:6px;">
                    <div style="text-align:center;padding:12px;color:var(--muted);font-size:12px;">
                        <i class="fa fa-spinner fa-spin"></i> Prüfe Status...
                    </div>
                </div>
                <button class="cta" onclick="checkWebhookStatus(true);" style="margin-top:8px;"><i class="fa fa-sync" aria-hidden="true"></i> Status prüfen</button>
            </div>
            <?php if($userRole === 0 || $userRole === 1): ?>
            <div class="card klein" data-card-id="lastlog-card">
                <div class="card-actions"><div class="drag-handle" draggable="true" role="button" aria-label="Verschiebe Karte" tabindex="0" title="Verschiebe Karte">⠿</div></div>
                <h3>📣 Letzter Patch Log</h3>
                <?php if($lastPatchLog): ?>
                    <div class="value" style="font-size:14px; font-weight:600; color:#cfd8dc; white-space:pre-line; max-height:58px; overflow:hidden;"><?=nl2br(htmlspecialchars($lastPatchLog))?></div>
                <?php else: ?>
                    <div class="value">—</div>
                    <div class="meta">Keine letzten Log-Einträge</div>
                <?php endif; ?>
                <button class="cta" onclick="showPatchlist(); startPatchFromDashboard();"><i class="fa fa-plus-circle" aria-hidden="true"></i> Patch erstellen</button>
            </div>
            <?php endif; ?>
            <!-- Quick Actions Card -->
            <div class="card mittel" data-card-id="quick-actions-card" id="quickActionsCard">
                <div class="card-actions"><div class="drag-handle" draggable="true" role="button" aria-label="Verschiebe Karte" tabindex="0" title="Verschiebe Karte">⠿</div></div>
                <h3>⚡ Quick Actions</h3>
                <div id="quickActionsContent" style="display:flex;flex-direction:column;gap:8px;">
                    <div style="text-align:center;padding:20px;color:var(--muted);font-size:12px;">
                        <i class="fa fa-spinner fa-spin"></i> Lade...
                    </div>
                </div>
            </div>
            <!-- Removed duplicate stray elements -->
            <!-- Removed duplicate small 'LAST' card (redundant). -->
            </div>
        </div>
        
        <!-- Dashboard Container (for sections) -->
        <div id="dashboardContainer">

        <!-- Statistics Section -->
        <div class="dashboard-section statistics-section" data-section-id="statistics-section" style="margin-top:48px;">
            <hr style="border:none;border-top:1px solid rgba(255,255,255,0.05);margin:32px 0;">
            <div class="section-header" style="display:flex;align-items:center;justify-content:space-between;margin-bottom:24px;cursor:pointer;user-select:none;" onclick="toggleStatisticsSection()">
                <h2 style="font-size:32px;font-weight:800;color:var(--accent);margin:0;text-shadow:0 2px 8px rgba(var(--icon-shadow-rgb, 255,179,0),0.3);">
                    <i class="fa fa-chart-bar" style="margin-right:12px;"></i>Statistiken
                </h2>
                <div style="display:flex;align-items:center;gap:12px;">
                    <div class="drag-handle section-drag-handle" draggable="true" role="button" aria-label="Verschiebe Sektion" tabindex="0" title="Verschiebe Sektion" style="cursor:grab;padding:8px;border-radius:8px;border:1px solid rgba(255,255,255,0.08);background:rgba(255,255,255,0.02);color:var(--muted);">⠿</div>
                    <i class="fa fa-chevron-up" id="statsToggleIcon" style="font-size:20px;color:var(--accent);transition:transform 0.3s ease;"></i>
                </div>
            </div>
            <div id="statsContent" style="display:flex;flex-direction:column;gap:16px;overflow:hidden;transition:max-height 0.3s ease, opacity 0.3s ease;">
                <div style="text-align:center;padding:20px;color:var(--muted);font-size:12px;">
                    <i class="fa fa-spinner fa-spin"></i> Lade...
                </div>
            </div>
        </div>
        </div>
        
        <div class="flex" style="justify-content:space-between;align-items:center;margin-top:12px;gap:8px;">
            <div>
                <button class="btn primary" id="addSectionBtn"><i class="fa fa-plus" aria-hidden="true"></i> Neue Sektion erstellen</button>
            </div>
            <div class="flex" style="gap:8px;">
                <label class="muted" for="serverSyncToggle">Server-Sync</label>
                <input type="checkbox" id="serverSyncToggle" <?= (file_exists($layoutFile) ? 'checked' : '') ?> style="width:18px;height:18px;vertical-align:middle;" />
                <button class="btn ghost" id="undoLayout"><i class="fa fa-undo" aria-hidden="true"></i> Rückgängig</button>
                <button class="btn ghost" id="resetAll"><i class="fa fa-redo" aria-hidden="true"></i> Reset All</button>
                <button class="btn ghost" id="resetLayout"><i class="fa fa-trash" aria-hidden="true"></i> Layout zurücksetzen</button>
                <button class="btn ghost" id="saveServerLayout"><i class="fa fa-save" aria-hidden="true"></i> Auf Server speichern</button>
                <button class="btn ghost" id="deleteServerLayout"><i class="fa fa-times-circle" aria-hidden="true"></i> Server-Layout löschen</button>
                <button class="btn ghost" id="debugToggle"><i class="fa fa-bug" aria-hidden="true"></i> Debug: Aus</button>
            </div>
        </div>
    </div>

    <!-- Patchlist -->
    <div id="patchlist" style="display:none;">
        <h1>Patchlist Generator</h1>
        
        <!-- File Upload Section -->
        <div class="upload-section-grid">
            <div class="upload-drop-area">
                <div id="dropZone" class="drop-zone">
                    <i class="fa fa-cloud-upload-alt" style="font-size:36px;color:var(--accent);margin-bottom:12px;"></i>
                    <p style="font-size:15px;font-weight:600;margin:0 0 6px;">Dateien hierher ziehen</p>
                    <p style="font-size:12px;color:var(--muted);margin:0;">oder klicken zum Auswählen</p>
                    <input type="file" id="fileInput" multiple style="display:none;" />
                </div>
                <div id="uploadStatus" style="margin-top:12px;display:none;"></div>
            </div>
            <div class="upload-files-card">
                <div class="upload-files-header">
                    <h3><i class="fa fa-file-upload"></i> Hochgeladene Dateien</h3>
                    <div style="display:flex;align-items:center;gap:8px;">
                        <span id="uploadCount" class="upload-count">0</span>
                        <button id="cancelAllUploads" class="btn-cancel-all" style="display:none;" title="Alle abbrechen">
                            <i class="fa fa-times"></i>
                        </button>
                    </div>
                </div>
                <div id="uploadProgressContainer" class="upload-files-grid"></div>
            </div>
        </div>
        
        <div id="progress-container">
            <div id="progress-bar">0%</div>
        </div>
        <textarea id="log" readonly style="width:100%;min-height:160px;padding:12px 16px;border-radius:12px;border:1px solid rgba(var(--glow-rgb-1, 255,179,0),0.08);background:linear-gradient(135deg, rgba(0,0,0,0.3), rgba(0,0,0,0.2));color:var(--text);resize:vertical;font-size:12px;line-height:1.8;box-shadow:inset 0 2px 8px rgba(0,0,0,0.3);font-family:'Courier New',monospace;"></textarea>
        <button id="startButton" class="btn primary" aria-label="Start Patchlist"><i class="fa fa-play" aria-hidden="true"></i> Start Manuell</button>
        <button class="btn ghost notice" id="noticeBtn" aria-label="Notice"><i class="fa fa-info-circle" aria-hidden="true"></i> Notice</button>
    </div>

    <!-- File Browser -->
    <?php if($userRole === 0 || $userRole === 1): ?>
    <div id="fileBrowser" style="display:none;">
        <h1>Datei Browser</h1>
        <p class="kicker">Durchsuchen und Verwalten von Dateien im Zielordner</p>
        
        <!-- Breadcrumb Navigation -->
        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;">
            <div id="breadcrumb" class="breadcrumb">
                <span class="breadcrumb-item" data-path=""><i class="fa fa-home"></i> Root</span>
            </div>
            <button id="createFolderBtn" class="btn primary" style="padding:8px 16px;">
                <i class="fa fa-folder-plus"></i> Neuer Ordner
            </button>
        </div>
        
        <!-- File List -->
        <div id="fileList" class="file-list">
            <div style="text-align:center;padding:40px;color:var(--muted);">
                <i class="fa fa-spinner fa-spin" style="font-size:32px;"></i>
                <p>Lade Dateien...</p>
            </div>
        </div>
    </div>
    <?php endif; ?>

    <!-- Discord Patch Logs -->
    <div id="DiscordPatchLogs" style="display:none;">
        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;">
            <h1 style="margin:0;">Discord Patch Logs</h1>
            <div style="display:flex;gap:8px;">
                <button class="btn ghost" onclick="toggleScheduledModal()" style="padding:8px 16px;">
                    <i class="fa fa-clock"></i> Geplant
                </button>
                <button class="btn ghost" onclick="toggleActivityLog()" style="padding:8px 16px;">
                    <i class="fa fa-history"></i> Aktivitäten
                </button>
            </div>
        </div>
        
        <!-- Activity Log Modal -->
        <div id="activityLogModal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.8);z-index:10000;padding:40px;">
            <div style="max-width:900px;margin:0 auto;background:var(--bg);border-radius:12px;padding:24px;max-height:calc(100vh - 80px);overflow-y:auto;">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;">
                    <h2 style="margin:0;">Aktivitätsprotokoll</h2>
                    <button class="btn ghost" onclick="toggleActivityLog()" style="padding:4px 8px;">
                        <i class="fa fa-times"></i>
                    </button>
                </div>
                <div id="activityLogContent">
                    <div style="text-align:center;padding:40px;color:var(--muted);">
                        <i class="fa fa-spinner fa-spin"></i> Lade...
                    </div>
                </div>
            </div>
        </div>
        
        <!-- Scheduled Messages Modal -->
        <div id="scheduledModal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.8);z-index:10000;padding:40px;">
            <div style="max-width:900px;margin:0 auto;background:var(--bg);border-radius:12px;padding:24px;max-height:calc(100vh - 80px);overflow-y:auto;">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;">
                    <h2 style="margin:0;"><i class="fa fa-clock"></i> Geplante Nachrichten</h2>
                    <button class="btn ghost" onclick="toggleScheduledModal()" style="padding:4px 8px;">
                        <i class="fa fa-times"></i>
                    </button>
                </div>
                <div id="scheduledMessagesContent">
                    <div style="text-align:center;padding:40px;color:var(--muted);">
                        <i class="fa fa-spinner fa-spin"></i> Lade geplante Nachrichten...
                    </div>
                </div>
            </div>
        </div>
        
        <!-- Version History Modal -->
        <div id="versionHistoryModal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.8);z-index:10000;padding:40px;">
            <div style="max-width:700px;margin:0 auto;background:var(--bg);border-radius:12px;padding:24px;max-height:calc(100vh - 80px);overflow-y:auto;">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;">
                    <h2 style="margin:0;"><i class="fa fa-history"></i> Versionen-Historie</h2>
                    <button class="btn ghost" onclick="toggleVersionHistory()" style="padding:4px 8px;">
                        <i class="fa fa-times"></i>
                    </button>
                </div>
                <div id="versionHistoryContent">
                    <div style="text-align:center;padding:40px;color:var(--muted);">
                        <i class="fa fa-spinner fa-spin"></i> Lade Versionen...
                    </div>
                </div>
            </div>
        </div>
        
        <!-- Image Picker Modal -->
        <div id="imagePickerModal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.8);z-index:10000;padding:40px;">
            <div style="max-width:800px;margin:0 auto;background:var(--bg);border-radius:12px;padding:24px;max-height:calc(100vh - 80px);overflow-y:auto;">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;">
                    <h2 style="margin:0;"><i class="fa fa-image"></i> Bild auswählen</h2>
                    <button class="btn ghost" onclick="closeImagePicker()" style="padding:4px 8px;">
                        <i class="fa fa-times"></i>
                    </button>
                </div>
                <div id="imagePickerContent" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:12px;">
                    <div style="text-align:center;padding:40px;color:var(--muted);grid-column:1/-1;">
                        <i class="fa fa-spinner fa-spin"></i> Lade Bilder...
                    </div>
                </div>
            </div>
        </div>
        
        <!-- Patchlog Management -->
        <div style="display:grid;grid-template-columns:250px 1fr;gap:16px;margin-bottom:16px;">
            <!-- Patchlog List -->
            <div style="background:var(--surface);border-radius:8px;padding:16px;">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;">
                    <h3 style="margin:0;font-size:14px;color:var(--card-heading);">Gespeicherte Logs</h3>
                    <button class="btn ghost" style="padding:4px 8px;font-size:12px;" onclick="createNewPatchlog()" title="Neues Patchlog (Ctrl+N)">
                        <i class="fa fa-plus"></i>
                    </button>
                </div>
                <input type="text" id="patchlogSearch" placeholder="Suchen..." oninput="filterPatchlogs()" style="width:100%;padding:6px 8px;margin-bottom:8px;border-radius:4px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.2);color:var(--text);font-size:12px;" />
                <div id="patchlogList" style="max-height:300px;overflow-y:auto;">
                    <div style="text-align:center;padding:20px;color:var(--muted);font-size:12px;">
                        <i class="fa fa-spinner fa-spin"></i> Lade...
                    </div>
                </div>
            </div>
            
            <!-- Editor Area -->
            <div>
                <div style="margin-bottom:12px;display:flex;gap:8px;align-items:center;">
                    <input type="text" id="patchlogName" placeholder="Patchlog Name" style="flex:1;padding:8px;border-radius:6px;border:1px solid rgba(255,255,255,0.08);background:var(--surface);color:var(--text);" />
                    <input type="hidden" id="currentPatchlogId" value="" />
                </div>
                
                <div style="margin-bottom:12px;display:grid;grid-template-columns:1fr 1fr 200px;gap:12px;">
                    <div>
                        <label style="display:block;margin-bottom:8px;font-weight:600;font-size:14px;">
                            Webhooks
                            <button type="button" onclick="toggleWebhookMultiSelect()" class="btn ghost" style="padding:2px 6px;font-size:10px;margin-left:8px;" title="Multi-Select umschalten">
                                <i class="fa fa-check-square"></i>
                            </button>
                        </label>
                        <select id="webhookSelect" style="width:100%;padding:10px;border-radius:8px;border:1px solid rgba(255,255,255,0.08);background:var(--surface);color:var(--text);">
                            <option value="">-- Webhook auswählen --</option>
                        </select>
                        <div id="webhookMultiSelect" style="display:none;background:var(--surface);border:1px solid rgba(255,255,255,0.08);border-radius:8px;padding:8px;max-height:150px;overflow-y:auto;margin-top:8px;">
                            <!-- Checkboxes will be populated by JS -->
                        </div>
                    </div>
                    <div>
                        <label for="templateSelect" style="display:block;margin-bottom:8px;font-weight:600;font-size:14px;">Template</label>
                        <select id="templateSelect" onchange="loadTemplate()" style="width:100%;padding:10px;border-radius:8px;border:1px solid rgba(255,255,255,0.08);background:var(--surface);color:var(--text);">
                            <option value="">-- Template auswählen --</option>
                            <option value="basic">Basis Patchlog</option>
                            <option value="bugfix">Bugfix</option>
                            <option value="feature">Neues Feature</option>
                            <option value="update">Update-Ankündigung</option>
                            <option value="hotfix">Hotfix</option>
                        </select>
                    </div>
                    <div>
                        <label style="display:block;margin-bottom:8px;font-weight:600;font-size:14px;">Zeitpunkt <small style="color:var(--muted);font-weight:400;">(optional)</small></label>
                        <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;">
                            <input type="date" id="scheduleDate" placeholder="Datum" style="width:100%;padding:10px;border-radius:8px;border:1px solid rgba(255,255,255,0.08);background:var(--surface);color:var(--text);font-size:13px;" oninput="validateScheduleInputs()" />
                            <input type="time" id="scheduleTime" placeholder="Uhrzeit" step="300" style="width:100%;padding:10px;border-radius:8px;border:1px solid rgba(255,255,255,0.08);background:var(--surface);color:var(--text);font-size:13px;" oninput="validateScheduleInputs()" />
                        </div>
                    </div>
                </div>
                
                <div style="margin-bottom:8px;display:flex;gap:8px;align-items:center;">
                    <label style="font-size:13px;color:var(--muted);">Pings:</label>
                    <button type="button" class="btn ghost" style="padding:4px 8px;font-size:12px;" onclick="insertMention('@everyone')" title="@everyone einfügen">@everyone</button>
                    <button type="button" class="btn ghost" style="padding:4px 8px;font-size:12px;" onclick="insertMention('@here')" title="@here einfügen">@here</button>
                    <input type="text" id="customRole" placeholder="Rolle-ID oder Name" style="padding:4px 8px;border-radius:4px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.2);color:var(--text);font-size:12px;width:150px;" />
                    <button type="button" class="btn ghost" style="padding:4px 8px;font-size:12px;" onclick="insertCustomRole()" title="Custom Rolle einfügen"><i class="fa fa-plus"></i> Rolle</button>
                </div>
                
                <textarea id="markdownEditor"></textarea>
                
                <div style="display:flex;gap:8px;margin-top:8px;flex-wrap:wrap;">
                    <button class="btn ghost" onclick="savePatchlog()" aria-label="Save Patchlog" title="Speichern (Ctrl+S)"><i class="fa fa-save" aria-hidden="true"></i> Speichern</button>
                    <button class="btn ghost" onclick="toggleVersionHistory()" aria-label="Version History" title="Versionen anzeigen"><i class="fa fa-history" aria-hidden="true"></i> Versionen</button>
                    <button class="btn ghost" onclick="toggleEmbedBuilder()" aria-label="Embed Builder" title="Embed Builder öffnen"><i class="fa fa-magic" aria-hidden="true"></i> Embed Builder</button>
                    <button class="btn ghost" onclick="toggleDiscordPreview()" aria-label="Toggle Preview"><i class="fa fa-eye" aria-hidden="true"></i> Vorschau</button>
                    <button class="btn primary" onclick="sendDiscordPatch()" aria-label="Send Discord Patch"><i class="fa fa-paper-plane" aria-hidden="true"></i> Senden</button>
                    <button class="btn warn" onclick="deletePatchlog()" aria-label="Delete Patchlog" style="margin-left:auto;"><i class="fa fa-trash" aria-hidden="true"></i> Löschen</button>
                </div>
                
                <!-- Discord Preview -->
                <div id="discordPreviewContainer" style="display:none;margin-top:16px;background:#36393f;border-radius:8px;padding:16px;border:1px solid #202225;">
                    <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;">
                        <h3 style="margin:0;color:#dcddde;font-size:14px;"><i class="fa fa-eye"></i> Discord-Vorschau</h3>
                        <button class="btn ghost" style="padding:4px 8px;font-size:12px;" onclick="toggleDiscordPreview()">
                            <i class="fa fa-times"></i>
                        </button>
                    </div>
                    <div id="discordPreview" style="background:#40444b;border-radius:4px;padding:12px;color:#dcddde;font-size:14px;line-height:1.5;font-family:Whitney,'Helvetica Neue',Helvetica,Arial,sans-serif;max-height:400px;overflow-y:auto;"></div>
                </div>
                
                <!-- Embed Builder -->
                <div id="embedBuilderContainer" style="display:none;margin-top:16px;background:var(--surface);border-radius:8px;padding:16px;border:1px solid rgba(255,255,255,0.08);">
                    <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;">
                        <h3 style="margin:0;font-size:14px;"><i class="fa fa-magic"></i> Embed Builder</h3>
                        <button class="btn ghost" style="padding:4px 8px;font-size:12px;" onclick="toggleEmbedBuilder()">
                            <i class="fa fa-times"></i>
                        </button>
                    </div>
                    
                    <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;">
                        <!-- Left: Builder Form -->
                        <div style="background:rgba(0,0,0,0.2);border-radius:8px;padding:16px;">
                            <h4 style="margin:0 0 12px 0;font-size:13px;">Embed Einstellungen</h4>
                            
                            <!-- Templates -->
                            <div style="margin-bottom:16px;">
                                <label style="display:block;font-size:12px;margin-bottom:6px;color:var(--muted);">Standard-Vorlagen:</label>
                                <div style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px;">
                                    <button class="btn ghost" style="padding:4px 8px;font-size:11px;" onclick="loadEmbedTemplate('info')">ℹ️ Info</button>
                                    <button class="btn ghost" style="padding:4px 8px;font-size:11px;" onclick="loadEmbedTemplate('success')">✅ Erfolg</button>
                                    <button class="btn ghost" style="padding:4px 8px;font-size:11px;" onclick="loadEmbedTemplate('warning')">⚠️ Warnung</button>
                                    <button class="btn ghost" style="padding:4px 8px;font-size:11px;" onclick="loadEmbedTemplate('error')">❌ Fehler</button>
                                    <button class="btn ghost" style="padding:4px 8px;font-size:11px;" onclick="loadEmbedTemplate('patch')">📝 Patch</button>
                                </div>
                                <label style="display:block;font-size:12px;margin-bottom:6px;color:var(--muted);">Gespeicherte Vorlagen:</label>
                                <div style="display:flex;gap:6px;">
                                    <select id="savedEmbedSelect" style="flex:1;padding:6px 8px;border-radius:4px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.3);color:var(--text);font-size:12px;">
                                        <option value="">-- Vorlage wählen --</option>
                                    </select>
                                    <button class="btn ghost" style="padding:4px 8px;font-size:11px;" onclick="loadSavedEmbed()" title="Vorlage laden">
                                        <i class="fa fa-folder-open"></i>
                                    </button>
                                    <button class="btn ghost" style="padding:4px 8px;font-size:11px;" onclick="deleteSavedEmbed()" title="Vorlage löschen">
                                        <i class="fa fa-trash"></i>
                                    </button>
                                </div>
                            </div>
                            
                            <div style="margin-bottom:12px;">
                                <label for="embedTitle" style="display:block;font-size:12px;margin-bottom:4px;">Titel:</label>
                                <input type="text" id="embedTitle" placeholder="Embed Titel" maxlength="256" style="width:100%;padding:6px 8px;border-radius:4px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.3);color:var(--text);font-size:12px;" oninput="updateEmbedPreview()" />
                            </div>
                            
                            <div style="margin-bottom:12px;">
                                <label for="embedDescription" style="display:block;font-size:12px;margin-bottom:4px;">Beschreibung:</label>
                                <textarea id="embedDescription" placeholder="Embed Beschreibung" maxlength="4096" style="width:100%;padding:6px 8px;border-radius:4px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.3);color:var(--text);font-size:12px;min-height:80px;resize:vertical;" oninput="updateEmbedPreview()"></textarea>
                            </div>
                            
                            <div style="margin-bottom:12px;">
                                <label for="embedColor" style="display:block;font-size:12px;margin-bottom:4px;">Farbe:</label>
                                <div style="display:flex;gap:8px;align-items:center;">
                                    <input type="color" id="embedColor" value="#5865f2" style="width:60px;height:32px;border:1px solid rgba(255,255,255,0.08);border-radius:4px;background:transparent;cursor:pointer;" onchange="updateEmbedPreview()" />
                                    <input type="text" id="embedColorHex" value="#5865f2" placeholder="#5865f2" style="flex:1;padding:6px 8px;border-radius:4px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.3);color:var(--text);font-size:12px;" oninput="syncEmbedColor(this.value)" />
                                </div>
                            </div>
                            
                            <div style="margin-bottom:12px;">
                                <label for="embedThumbnail" style="display:block;font-size:12px;margin-bottom:4px;">Thumbnail:</label>
                                <div style="display:flex;gap:6px;">
                                    <input type="url" id="embedThumbnail" placeholder="URL oder wähle hochgeladenes Bild" style="flex:1;padding:6px 8px;border-radius:4px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.3);color:var(--text);font-size:12px;" oninput="updateEmbedPreview()" />
                                    <button class="btn ghost" style="padding:4px 8px;font-size:11px;" onclick="openImagePicker('thumbnail')" title="Hochgeladenes Bild wählen">
                                        <i class="fa fa-image"></i>
                                    </button>
                                </div>
                            </div>
                            
                            <div style="margin-bottom:12px;">
                                <label for="embedImage" style="display:block;font-size:12px;margin-bottom:4px;">Bild:</label>
                                <div style="display:flex;gap:6px;">
                                    <input type="url" id="embedImage" placeholder="URL oder wähle hochgeladenes Bild" style="flex:1;padding:6px 8px;border-radius:4px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.3);color:var(--text);font-size:12px;" oninput="updateEmbedPreview()" />
                                    <button class="btn ghost" style="padding:4px 8px;font-size:11px;" onclick="openImagePicker('image')" title="Hochgeladenes Bild wählen">
                                        <i class="fa fa-image"></i>
                                    </button>
                                </div>
                            </div>
                            
                            <div style="margin-bottom:12px;">
                                <label for="embedFooter" style="display:block;font-size:12px;margin-bottom:4px;">Footer Text:</label>
                                <input type="text" id="embedFooter" placeholder="Footer" maxlength="2048" style="width:100%;padding:6px 8px;border-radius:4px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.3);color:var(--text);font-size:12px;" oninput="updateEmbedPreview()" />
                            </div>
                            
                            <div style="margin-bottom:12px;">
                                <label style="display:block;font-size:12px;margin-bottom:6px;">Fields (max 25):</label>
                                <div id="embedFieldsList" style="display:flex;flex-direction:column;gap:6px;margin-bottom:8px;"></div>
                                <button class="btn ghost" style="padding:4px 8px;font-size:11px;width:100%;" onclick="addEmbedField()">
                                    <i class="fa fa-plus"></i> Field hinzufügen
                                </button>
                            </div>
                            
                            <div style="display:flex;gap:8px;margin-top:16px;">
                                <button class="btn primary" style="flex:1;padding:6px 12px;font-size:12px;" onclick="sendEmbedDirectly()">
                                    <i class="fa fa-paper-plane"></i> Jetzt senden
                                </button>
                                <button class="btn ghost" style="padding:6px 12px;font-size:12px;" onclick="convertEditorToEmbed()" title="Editor-Text zu Embed konvertieren">
                                    <i class="fa fa-exchange"></i>
                                </button>
                                <button class="btn ghost" style="padding:6px 12px;font-size:12px;" onclick="saveEmbedTemplate()" title="Als Vorlage speichern">
                                    <i class="fa fa-save"></i>
                                </button>
                                <button class="btn ghost" style="padding:6px 12px;font-size:12px;" onclick="clearEmbed()">
                                    <i class="fa fa-eraser"></i>
                                </button>
                            </div>
                        </div>
                        
                        <!-- Right: Live Preview -->
                        <div style="background:#36393f;border-radius:8px;padding:16px;">
                            <h4 style="margin:0 0 12px 0;font-size:13px;color:#dcddde;">Live-Vorschau</h4>
                            <div id="embedPreview" style="background:#2f3136;border-radius:4px;padding:12px;color:#dcddde;font-family:Whitney,'Helvetica Neue',Helvetica,Arial,sans-serif;">
                                <div style="text-align:center;padding:40px;color:#72767d;font-size:12px;">
                                    <i class="fa fa-magic" style="font-size:32px;margin-bottom:8px;opacity:0.5;"></i>
                                    <p>Fülle die Felder links aus, um eine Vorschau zu sehen</p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div id="discordPatchContent" style="margin-top:10px; color:#e0e0e0;"></div>
            </div>
        </div>
    </div>

    <!-- Settings -->
    <div id="settings" style="display:none;">
        <div style="margin-bottom:24px;">
            <h1 style="margin-bottom:8px;">⚙️ Einstellungen</h1>
            <p class="kicker"><?php 
                if($userRole === 0 || $userRole === 1){
                    echo 'Konfiguriere Server, Discord, Embeds und visuelle Anpassungen';
                } else if($userRole === 2){
                    echo 'Discord Webhooks und Medien verwalten';
                }
            ?></p>
        </div>
        
        <!-- Settings Navigation Tabs -->
        <?php if(isset($_SESSION['role']) && in_array((int)$_SESSION['role'], [0, 1])): ?>
        <div style="display:flex;gap:8px;margin-bottom:24px;border-bottom:2px solid rgba(255,255,255,0.06);padding-bottom:0;overflow-x:auto;">
            <button class="settings-tab active" data-tab="general" onclick="switchSettingsTab('general')">
                <i class="fa fa-cog"></i> Allgemein
            </button>
            <button class="settings-tab" data-tab="discord" onclick="switchSettingsTab('discord')">
                <i class="fa fa-comments"></i> Discord
            </button>
            <button class="settings-tab" data-tab="users" onclick="switchSettingsTab('users')">
                <i class="fa fa-users"></i> Benutzer
            </button>
            <button class="settings-tab" data-tab="media" onclick="switchSettingsTab('media')">
                <i class="fa fa-image"></i> Medien
            </button>
            <?php if((int)$_SESSION['role'] === 0): ?>
            <button class="settings-tab" data-tab="appearance" onclick="switchSettingsTab('appearance')">
                <i class="fa fa-palette"></i> Erscheinungsbild
            </button>
            <?php endif; ?>
            <button class="settings-tab" data-tab="advanced" onclick="switchSettingsTab('advanced')">
                <i class="fa fa-sliders-h"></i> Erweitert
            </button>
        </div>
        <?php elseif($userRole === 2): ?>
        <div style="display:flex;gap:8px;margin-bottom:24px;border-bottom:2px solid rgba(255,255,255,0.06);padding-bottom:0;overflow-x:auto;">
            <button class="settings-tab active" data-tab="discord" onclick="switchSettingsTab('discord')">
                <i class="fa fa-comments"></i> Discord
            </button>
            <button class="settings-tab" data-tab="media" onclick="switchSettingsTab('media')">
                <i class="fa fa-image"></i> Medien
            </button>
        </div>
        <?php endif; ?>
        
        <!-- General Tab (Rolle 0 & 1 only) -->
        <?php if(isset($_SESSION['role']) && in_array((int)$_SESSION['role'], [0, 1])): ?>
        <div class="settings-tab-content" id="tab-general" style="display:block;">
        <!-- Server-Konfiguration Card -->
        <div class="settings-card">
            <div class="settings-card-header">
                <h3><i class="fa fa-server" aria-hidden="true"></i> Server-Konfiguration</h3>
                <p class="muted">Grundlegende Server-Einstellungen</p>
            </div>
            <div class="settings-card-body">
                <div class="form-group">
                    <label for="snameInput">Servername</label>
                    <input type="text" id="snameInput" placeholder="z.B. Gala2, SgMt2" />
                    <small class="muted">Wird im Header und auf Cards angezeigt</small>
                </div>
                <div class="form-group">
                    <label for="targetDirInput">Zielordner für Patchlist</label>
                    <input type="text" id="targetDirInput" placeholder="z.B. metin2 oder sgmt2" />
                    <small class="muted">Pfad zum Spielordner (relativ oder absolut)</small>
                </div>
                <div class="form-group">
                    <label for="logoInput">Server-Logo</label>
                    <input type="file" id="logoInput" accept="image/gif,image/png,image/jpeg" />
                    <small class="muted">Unterstützt: GIF, PNG, JPG — Max. 2 MB</small>
                    <div style="display:flex; gap:8px; margin-top:8px;">
                        <button id="previewLogoBtn" class="btn ghost" type="button"><i class="fa fa-eye" aria-hidden="true"></i> Vorschau</button>
                        <button id="removeLogoBtn" class="btn ghost" type="button"><i class="fa fa-trash" aria-hidden="true"></i> Entfernen</button>
                    </div>
                    <div style="display:flex;align-items:center;gap:12px;margin-top:12px;padding:12px;background:rgba(var(--glow-rgb-1, 255,179,0),0.05);border-radius:8px;border:1px solid rgba(var(--glow-rgb-1, 255,179,0),0.1);">
                        <input type="checkbox" id="logoRoundInput" style="width:20px;height:20px;cursor:pointer;accent-color:var(--accent);" <?php echo $logoRound ? 'checked' : ''; ?> />
                        <label for="logoRoundInput" style="margin:0;cursor:pointer;font-size:14px;color:var(--text);user-select:none;">
                            <i class="fa fa-circle" style="margin-right:6px;color:var(--accent);"></i>Logo rund anzeigen
                        </label>
                    </div>
                    <?php if((int)$_SESSION['role'] === 0): ?>
                    <div style="display:flex;align-items:center;gap:12px;margin-top:12px;padding:12px;background:rgba(var(--glow-rgb-2, 255,179,0),0.05);border-radius:8px;border:1px solid rgba(var(--glow-rgb-2, 255,179,0),0.1);">
                        <input type="checkbox" id="modernDesignToggle" style="width:20px;height:20px;cursor:pointer;accent-color:var(--accent);" checked />
                        <label for="modernDesignToggle" style="margin:0;cursor:pointer;font-size:14px;color:var(--text);user-select:none;">
                            <i class="fa fa-magic" style="margin-right:6px;color:var(--accent);"></i>Modernes Design aktivieren
                        </label>
                    </div>
                    <?php endif; ?>
                </div>
            </div>
        </div>
        
        <!-- Sticky Save Bar for General -->
        <div class="settings-save-bar">
            <div class="settings-save-content">
                <div>
                    <strong>Allgemeine Einstellungen</strong>
                    <span class="muted" style="margin-left:12px;">Server-Konfiguration</span>
                </div>
                <div class="form-actions" style="margin:0;">
                    <button id="saveServerConfig" class="btn primary"><i class="fa fa-save" aria-hidden="true"></i> Speichern</button>
                    <button id="resetServerConfig" class="btn warn"><i class="fa fa-undo" aria-hidden="true"></i> Zurücksetzen</button>
                </div>
            </div>
            <div id="serverConfigStatus" class="status-message"></div>
        </div>
        </div><!-- End General Tab -->
        <?php endif; ?>
        
        <!-- Discord Tab (Rang 0, 1 & 2) -->
        <?php if($userRole !== 3): ?>
        <div class="settings-tab-content" id="tab-discord" style="display:none;">
        <!-- Discord-Webhook Card -->
        <div class="settings-card">
            <div class="settings-card-header" style="display:flex;justify-content:space-between;align-items:center;">
                <div>
                    <h3><i class="fa fa-comments" aria-hidden="true"></i> Discord Webhooks</h3>
                    <p class="muted">Verwalte mehrere Webhooks für verschiedene Channels</p>
                </div>
                <button id="addWebhookBtn" class="btn primary" style="padding:8px 16px;">
                    <i class="fa fa-plus"></i> Neuer Webhook
                </button>
            </div>
            <div class="settings-card-body">
                <div id="webhooksList" style="display:flex;flex-direction:column;gap:12px;">
                    <!-- Webhooks werden hier dynamisch eingefügt -->
                </div>
                <div id="noWebhooks" style="text-align:center;padding:40px;color:var(--muted);display:none;">
                    <i class="fa fa-inbox" style="font-size:32px;"></i>
                    <p>Keine Webhooks konfiguriert</p>
                    <small>Klicke auf "Neuer Webhook" um einen hinzuzufügen</small>
                </div>
                <div style="display:flex;gap:8px;margin-top:16px;padding-top:16px;border-top:1px solid rgba(255,255,255,0.06);">
                    <button id="testHookBtn" class="btn ghost"><i class="fa fa-flask" aria-hidden="true"></i> Test-Nachricht senden</button>
                    <button id="resetWebhookBtn" class="btn ghost"><i class="fa fa-undo" aria-hidden="true"></i> Webhooks zurücksetzen</button>
                </div>
            </div>
        </div>
        </div><!-- End Discord Tab -->
        <?php endif; ?>
        
        <!-- Media Tab (Rang 0, 1, 2) -->
        <?php $userRole = isset($_SESSION['role']) ? (int)$_SESSION['role'] : 1; ?>
        <?php if($userRole !== 3): ?>
        <div class="settings-tab-content" id="tab-media" style="<?php echo ($userRole === 2) ? 'display:block;' : 'display:none;'; ?>">
        <!-- Embed Bilder Verwaltung -->
        <div class="settings-card">
            <div class="settings-card-header">
                <h3><i class="fa fa-image" aria-hidden="true"></i> Embed Bilder Verwaltung</h3>
                <p class="muted">Bilder für Discord Embeds hochladen und verwalten</p>
            </div>
            <div class="settings-card-body">
                <div class="form-group">
                    <label>Bilder hochladen</label>
                    <div style="background:rgba(255,255,255,0.02);border:2px dashed rgba(255,255,255,0.1);border-radius:8px;padding:32px;text-align:center;cursor:pointer;transition:all 0.3s;" id="embedDropZone">
                        <input type="file" id="embedImageUpload" accept="image/png,image/jpeg,image/jpg,image/gif" multiple style="display:none;" />
                        <i class="fa fa-cloud-upload-alt" style="font-size:48px;color:var(--muted);margin-bottom:12px;display:block;"></i>
                        <button type="button" class="btn primary" onclick="document.getElementById('embedImageUpload').click()" style="margin-bottom:12px;">
                            <i class="fa fa-upload"></i> Bilder auswählen
                        </button>
                        <p style="color:var(--muted);font-size:13px;margin:8px 0 0;">oder Dateien hierher ziehen</p>
                        <small style="color:var(--muted);font-size:11px;">PNG, JPEG, GIF • Max. 10MB pro Datei</small>
                    </div>
                    <div id="uploadStatus" style="margin-top:12px;color:var(--muted);font-size:13px;text-align:center;"></div>
                </div>
                
                <div class="form-group">
                    <label style="display:flex;justify-content:space-between;align-items:center;">
                        <span>Hochgeladene Bilder</span>
                        <span style="color:var(--muted);font-size:12px;" id="imageCount">Lädt...</span>
                    </label>
                    <div id="embedImageGallery" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:12px;max-height:400px;overflow-y:auto;background:rgba(0,0,0,0.2);padding:12px;border-radius:8px;border:1px solid rgba(255,255,255,0.06);">
                        <div style="grid-column:1/-1;text-align:center;padding:40px;color:var(--muted);">
                            <i class="fa fa-spinner fa-spin"></i> Lade Bilder...
                        </div>
                    </div>
                </div>
            </div>
        </div>
        </div><!-- End Media Tab -->
        <?php endif; ?>
        
        <!-- Appearance Tab (Rolle 0 only) -->
        <?php if(isset($_SESSION['role']) && (int)$_SESSION['role'] === 0): ?>
        <div class="settings-tab-content" id="tab-appearance" style="display:none;">
        <!-- Super-Admin Color Settings -->
        <div class="settings-card">
            <div class="settings-card-header">
                <h3><i class="fa fa-palette" aria-hidden="true"></i> Farbeinstellungen</h3>
                <p class="muted">Passe die Farben des Admin-Panels an</p>
            </div>
            <div class="settings-card-body">
                <div style="max-height:500px; overflow-y:auto; padding-right:8px; margin-bottom:16px;">
                
                <h4 style="color:var(--accent); margin:0 0 12px; font-size:15px;">🎨 Basis-Farben</h4>
                <div class="form-group">
                    <label for="accentColorInput">Akzentfarbe</label>
                    <div style="display:flex; gap:12px; align-items:center;">
                        <input type="color" id="accentColorInput" class="color-picker" value="#ffb300" />
                        <input type="text" id="accentColorInputText" class="color-text" placeholder="#ffb300" value="#ffb300" />
                    </div>
                </div>
                
                <h4 style="color:var(--accent); margin:20px 0 12px; font-size:15px;">📝 Card-Elemente</h4>
                <div class="form-group">
                    <label for="cardHeadingInput">Card-Überschriften (h3)</label>
                    <div style="display:flex; gap:12px; align-items:center;">
                        <input type="color" id="cardHeadingInput" class="color-picker" value="#e6eef9" />
                        <input type="text" id="cardHeadingInputText" class="color-text" placeholder="#e6eef9" value="#e6eef9" />
                    </div>
                </div>
                <div class="form-group">
                    <label for="cardValueInput">Card-Werte (.value)</label>
                    <div style="display:flex; gap:12px; align-items:center;">
                        <input type="color" id="cardValueInput" class="color-picker" value="#ffffff" />
                        <input type="text" id="cardValueInputText" class="color-text" placeholder="#ffffff" value="#ffffff" />
                    </div>
                </div>
                
                <h4 style="color:var(--accent); margin:20px 0 12px; font-size:15px;">🔘 Buttons</h4>
                <div class="form-group">
                    <label for="ctaButtonInput">Call-to-Action Buttons</label>
                    <div style="display:flex; gap:12px; align-items:center;">
                        <input type="color" id="ctaButtonInput" class="color-picker" value="#ffb300" />
                        <input type="text" id="ctaButtonInputText" class="color-text" placeholder="#ffb300" value="#ffb300" />
                    </div>
                </div>
                <div class="form-group">
                    <label for="primaryButtonInput">Primary Buttons</label>
                    <div style="display:flex; gap:12px; align-items:center;">
                        <input type="color" id="primaryButtonInput" class="color-picker" value="#4caf50" />
                        <input type="text" id="primaryButtonInputText" class="color-text" placeholder="#4caf50" value="#4caf50" />
                    </div>
                </div>
                
                <h4 style="color:var(--accent); margin:20px 0 12px; font-size:15px;">🎯 Text & Icons</h4>
                <div class="form-group">
                    <label for="headerBrandInput">Header Brand Text</label>
                    <div style="display:flex; gap:12px; align-items:center;">
                        <input type="color" id="headerBrandInput" class="color-picker" value="#ffb300" />
                        <input type="text" id="headerBrandInputText" class="color-text" placeholder="#ffb300" value="#ffb300" />
                    </div>
                </div>
                <div class="form-group">
                    <label for="iconsInput">Alle Icons (fa)</label>
                    <div style="display:flex; gap:12px; align-items:center;">
                        <input type="color" id="iconsInput" class="color-picker" value="#ffb300" />
                        <input type="text" id="iconsInputText" class="color-text" placeholder="#ffb300" value="#ffb300" />
                    </div>
                </div>
                
                <h4 style="color:var(--accent); margin:20px 0 12px; font-size:15px;">✨ Schatten & Effekte (RGB)</h4>
                <div class="form-group">
                    <label for="cardShadowInput">Card Schatten</label>
                    <div class="rgb-picker-container">
                        <div class="rgb-preview" id="cardShadowPreview"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="cardShadowInput" data-channel="r" />
                                <span class="rgb-value">0</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="cardShadowInput" data-channel="g" />
                                <span class="rgb-value">0</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="cardShadowInput" data-channel="b" />
                                <span class="rgb-value">0</span>
                            </div>
                        </div>
                        <input type="text" id="cardShadowInput" class="color-text rgb-text-input" placeholder="0,0,0" readonly />
                    </div>
                </div>
                <div class="form-group">
                    <label for="buttonShadowInput">Button Schatten</label>
                    <div class="rgb-picker-container">
                        <div class="rgb-preview" id="buttonShadowPreview"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="buttonShadowInput" data-channel="r" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="179" class="rgb-slider" data-target="buttonShadowInput" data-channel="g" />
                                <span class="rgb-value">179</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="buttonShadowInput" data-channel="b" />
                                <span class="rgb-value">0</span>
                            </div>
                        </div>
                        <input type="text" id="buttonShadowInput" class="color-text rgb-text-input" placeholder="255,179,0" readonly />
                    </div>
                </div>
                <div class="form-group">
                    <label for="iconShadowInput">Icon Drop-Shadows</label>
                    <div class="rgb-picker-container">
                        <div class="rgb-preview" id="iconShadowPreview"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="iconShadowInput" data-channel="r" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="179" class="rgb-slider" data-target="iconShadowInput" data-channel="g" />
                                <span class="rgb-value">179</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="iconShadowInput" data-channel="b" />
                                <span class="rgb-value">0</span>
                            </div>
                        </div>
                        <input type="text" id="iconShadowInput" class="color-text rgb-text-input" placeholder="255,179,0" readonly />
                    </div>
                </div>
                <div class="form-group">
                    <label for="glow1ColorInput">Glühfarbe 1</label>
                    <div class="rgb-picker-container">
                        <div class="rgb-preview" id="glow1ColorPreview"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="glow1ColorInput" data-channel="r" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="179" class="rgb-slider" data-target="glow1ColorInput" data-channel="g" />
                                <span class="rgb-value">179</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="glow1ColorInput" data-channel="b" />
                                <span class="rgb-value">0</span>
                            </div>
                        </div>
                        <input type="text" id="glow1ColorInput" class="color-text rgb-text-input" placeholder="255,179,0" readonly />
                    </div>
                </div>
                <div class="form-group">
                    <label for="glow2ColorInput">Glühfarbe 2</label>
                    <div class="rgb-picker-container">
                        <div class="rgb-preview" id="glow2ColorPreview"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="glow2ColorInput" data-channel="r" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="179" class="rgb-slider" data-target="glow2ColorInput" data-channel="g" />
                                <span class="rgb-value">179</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="glow2ColorInput" data-channel="b" />
                                <span class="rgb-value">0</span>
                            </div>
                        </div>
                        <input type="text" id="glow2ColorInput" class="color-text rgb-text-input" placeholder="255,179,0" readonly />
                    </div>
                </div>
                
                <h4 style="color:var(--accent); margin:20px 0 12px; font-size:15px;">🎭 Sidebar-Elemente (RGB)</h4>
                <div class="form-group">
                    <label for="sidebarBorderInput">Sidebar Border & Akzente</label>
                    <div class="rgb-picker-container">
                        <div class="rgb-preview" id="sidebarBorderPreview"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="sidebarBorderInput" data-channel="r" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="179" class="rgb-slider" data-target="sidebarBorderInput" data-channel="g" />
                                <span class="rgb-value">179</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="sidebarBorderInput" data-channel="b" />
                                <span class="rgb-value">0</span>
                            </div>
                        </div>
                        <input type="text" id="sidebarBorderInput" class="color-text rgb-text-input" placeholder="255,179,0" readonly />
                    </div>
                </div>
                <div class="form-group">
                    <label for="sidebarBgInput">Sidebar Hintergrund</label>
                    <div class="rgb-picker-container">
                        <div class="rgb-preview" id="sidebarBgPreview"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="17" class="rgb-slider" data-target="sidebarBgInput" data-channel="r" />
                                <span class="rgb-value">17</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="19" class="rgb-slider" data-target="sidebarBgInput" data-channel="g" />
                                <span class="rgb-value">19</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="23" class="rgb-slider" data-target="sidebarBgInput" data-channel="b" />
                                <span class="rgb-value">23</span>
                            </div>
                        </div>
                        <input type="text" id="sidebarBgInput" class="color-text rgb-text-input" placeholder="17,19,23" readonly />
                    </div>
                </div>
                
                <!-- Card Hintergrund -->
                <div class="form-group">
                    <label for="cardBgInput">Card Hintergrund (RGB)</label>
                    <div class="rgb-picker-container">
                        <div id="cardBgPreview" class="color-preview" style="background:rgba(255,255,255,0.02);"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="cardBgInput" data-channel="r" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="cardBgInput" data-channel="g" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="cardBgInput" data-channel="b" />
                                <span class="rgb-value">255</span>
                            </div>
                        </div>
                        <input type="text" id="cardBgInput" class="color-text rgb-text-input" placeholder="255,255,255" readonly />
                    </div>
                    <label for="cardBgOpacityInput" style="margin-top:12px;">Card Hintergrund Deckkraft</label>
                    <input type="range" id="cardBgOpacityInput" min="0" max="1" step="0.01" value="0.02" style="width:100%;" />
                    <span id="cardBgOpacityValue" style="color:var(--muted);font-size:13px;">0.02</span>
                </div>
                
                <!-- Settings Hintergrund -->
                <div class="form-group">
                    <label for="settingsBgInput">Settings Card Hintergrund (RGB)</label>
                    <div class="rgb-picker-container">
                        <div id="settingsBgPreview" class="color-preview" style="background:rgba(255,255,255,0.02);"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="settingsBgInput" data-channel="r" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="settingsBgInput" data-channel="g" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="settingsBgInput" data-channel="b" />
                                <span class="rgb-value">255</span>
                            </div>
                        </div>
                        <input type="text" id="settingsBgInput" class="color-text rgb-text-input" placeholder="255,255,255" readonly />
                    </div>
                    <label for="settingsBgOpacityInput" style="margin-top:12px;">Settings Hintergrund Deckkraft</label>
                    <input type="range" id="settingsBgOpacityInput" min="0" max="1" step="0.01" value="0.02" style="width:100%;" />
                    <span id="settingsBgOpacityValue" style="color:var(--muted);font-size:13px;">0.02</span>
                </div>
                
                <!-- Tabellen Header -->
                <div class="form-group">
                    <label for="tableHeaderInput">Tabellen Header (RGB)</label>
                    <div class="rgb-picker-container">
                        <div id="tableHeaderPreview" class="color-preview" style="background:rgb(255,179,0);"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="tableHeaderInput" data-channel="r" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="179" class="rgb-slider" data-target="tableHeaderInput" data-channel="g" />
                                <span class="rgb-value">179</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="tableHeaderInput" data-channel="b" />
                                <span class="rgb-value">0</span>
                            </div>
                        </div>
                        <input type="text" id="tableHeaderInput" class="color-text rgb-text-input" placeholder="255,179,0" readonly />
                    </div>
                </div>
                
                <!-- Tabellen Hover -->
                <div class="form-group">
                    <label for="tableHoverInput">Tabellen Hover (RGB)</label>
                    <div class="rgb-picker-container">
                        <div id="tableHoverPreview" class="color-preview" style="background:rgb(255,179,0);"></div>
                        <div class="rgb-sliders">
                            <div class="rgb-slider-row">
                                <label>R</label>
                                <input type="range" min="0" max="255" value="255" class="rgb-slider" data-target="tableHoverInput" data-channel="r" />
                                <span class="rgb-value">255</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>G</label>
                                <input type="range" min="0" max="255" value="179" class="rgb-slider" data-target="tableHoverInput" data-channel="g" />
                                <span class="rgb-value">179</span>
                            </div>
                            <div class="rgb-slider-row">
                                <label>B</label>
                                <input type="range" min="0" max="255" value="0" class="rgb-slider" data-target="tableHoverInput" data-channel="b" />
                                <span class="rgb-value">0</span>
                            </div>
                        </div>
                        <input type="text" id="tableHoverInput" class="color-text rgb-text-input" placeholder="255,179,0" readonly />
                    </div>
                </div>
                
                </div>
                
                <div class="form-actions" style="background:#0f1111; padding:16px; border-top:2px solid rgba(255,255,255,0.08); box-shadow: 0 -6px 20px rgba(0,0,0,0.9);">
                    <button id="saveColorSettings" class="btn primary"><i class="fa fa-save" aria-hidden="true"></i> Farben speichern</button>
                    <button id="resetColorSettings" class="btn warn"><i class="fa fa-undo" aria-hidden="true"></i> Auf Standard zurücksetzen</button>
                </div>
                <div id="colorStatus" class="status-message" style="margin-top:12px;"></div>
            </div>
        </div>
        </div><!-- End Appearance Tab -->
        <?php endif; ?>
        
        <!-- Advanced Tab -->
        <div class="settings-tab-content" id="tab-advanced" style="display:none;">
        <!-- Cache-Verwaltung Card -->
        <div class="settings-card">
            <div class="settings-card-header">
                <h3><i class="fa fa-sync-alt" aria-hidden="true"></i> Cache-Verwaltung</h3>
                <p class="muted">Browser-Cache für JavaScript-Dateien</p>
            </div>
            <div class="settings-card-body">
                <p class="muted" style="margin-bottom:12px;">
                    Erzwingt das Neuladen von <code>admin.js</code> im Browser. Nützlich nach Updates oder bei Anzeigeproblemen.
                </p>
                <button id="clearCacheBtn" class="btn warn"><i class="fa fa-sync-alt" aria-hidden="true"></i> JS-Cache leeren</button>
            </div>
        </div>
        </div><!-- End Advanced Tab -->
        
        <style>
        /* Settings Tab Styles */
        .settings-tab {
            padding: 12px 20px;
            background: rgba(255,255,255,0.02);
            border: none;
            border-bottom: 3px solid transparent;
            color: var(--muted);
            cursor: pointer;
            transition: all 0.3s;
            font-size: 14px;
            font-weight: 500;
            white-space: nowrap;
        }
        .settings-tab:hover {
            background: rgba(255,255,255,0.04);
            color: var(--text);
        }
        .settings-tab.active {
            background: rgba(var(--glow-rgb-1, 255,179,0), 0.1);
            border-bottom-color: var(--accent);
            color: var(--accent);
        }
        .settings-tab i {
            margin-right: 6px;
        }
        .settings-tab-content {
            animation: fadeIn 0.3s ease-in-out;
        }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(-10px); }
            to { opacity: 1; transform: translateY(0); }
        }
        
        <style>
        .color-picker { 
            width:60px; height:40px; border-radius:8px; border:2px solid #444; 
            background:#111; cursor:pointer; transition: all 0.2s ease;
            box-shadow: 0 2px 8px rgba(0,0,0,0.3);
        }
        .color-picker:hover { border-color: var(--accent); box-shadow: 0 4px 12px rgba(var(--glow-rgb-1), 0.3); }
        .color-text { 
            flex:1; padding:10px 12px; border-radius:6px; border:1px solid #444; 
            background:#111; color:#e0e0e0; font-family: 'Courier New', monospace; font-weight:600;
        }
        
        /* RGB Picker Styles */
        .rgb-picker-container {
            background: linear-gradient(135deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01));
            border: 1px solid rgba(255,255,255,0.06);
            border-radius: 10px;
            padding: 16px;
            margin-top: 8px;
        }
        .rgb-preview {
            width: 100%;
            height: 50px;
            border-radius: 8px;
            border: 2px solid rgba(255,255,255,0.1);
            margin-bottom: 12px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.4), inset 0 2px 4px rgba(255,255,255,0.05);
            transition: all 0.3s ease;
        }
        .rgb-sliders {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-bottom: 12px;
        }
        .rgb-slider-row {
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .rgb-slider-row > label {
            width: 20px;
            font-weight: 700;
            color: var(--accent);
            font-size: 13px;
        }
        .rgb-slider {
            flex: 1;
            height: 8px;
            border-radius: 4px;
            background: linear-gradient(90deg, #111, var(--accent));
            outline: none;
            cursor: pointer;
            -webkit-appearance: none;
        }
        .rgb-slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: var(--accent);
            cursor: pointer;
            border: 2px solid #fff;
            box-shadow: 0 2px 8px rgba(0,0,0,0.4), 0 0 0 3px rgba(var(--glow-rgb-1), 0.2);
            transition: all 0.2s ease;
        }
        .rgb-slider::-webkit-slider-thumb:hover {
            transform: scale(1.2);
            box-shadow: 0 3px 12px rgba(0,0,0,0.6), 0 0 0 5px rgba(var(--glow-rgb-1), 0.3);
        }
        .rgb-slider::-moz-range-thumb {
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: var(--accent);
            cursor: pointer;
            border: 2px solid #fff;
            box-shadow: 0 2px 8px rgba(0,0,0,0.4), 0 0 0 3px rgba(var(--glow-rgb-1), 0.2);
            transition: all 0.2s ease;
        }
        .rgb-slider::-moz-range-thumb:hover {
            transform: scale(1.2);
            box-shadow: 0 3px 12px rgba(0,0,0,0.6), 0 0 0 5px rgba(var(--glow-rgb-1), 0.3);
        }
        .rgb-value {
            min-width: 35px;
            text-align: right;
            font-weight: 700;
            color: var(--text);
            font-size: 13px;
            font-family: 'Courier New', monospace;
        }
        .rgb-text-input {
            width: 100%;
            text-align: center;
            font-size: 14px;
            background: rgba(0,0,0,0.3) !important;
            border: 1px solid rgba(var(--glow-rgb-1), 0.3);
            cursor: default;
        }
        </style>
        <?php endif; ?>
        
        <style>
        /* Schedule Input Validation Shake */
        @keyframes shake-error {
            0%, 100% { transform: translateX(0); }
            25% { transform: translateX(-8px); }
            75% { transform: translateX(8px); }
        }
        .schedule-error {
            border-color: #ff4444 !important;
            animation: shake-error 0.4s ease-in-out;
            box-shadow: 0 0 0 3px rgba(255,68,68,0.2) !important;
        }
        </style>
        
        <!-- Users Tab (Rolle 0 or 1 only) -->
        <?php if(isset($_SESSION['role']) && in_array((int)$_SESSION['role'], [0, 1])): ?>
        <div class="settings-tab-content" id="tab-users" style="display:none;">
        <!-- Benutzerkonten Card -->
        <div class="settings-card">
            <div class="settings-card-header">
                <h3><i class="fa fa-users" aria-hidden="true"></i> Benutzerverwaltung</h3>
                <p class="muted">Erstelle und verwalte Benutzerkonten mit verschiedenen Rollen</p>
            </div>
            <div class="settings-card-body">
                <div style="background:rgba(255,179,0,0.1);border-left:3px solid var(--accent);padding:12px;border-radius:6px;margin-bottom:16px;">
                    <strong style="color:var(--accent);"><i class="fa fa-info-circle"></i> Rollenübersicht</strong>
                    <ul style="margin:8px 0 0 20px;font-size:13px;color:var(--muted);">
                        <li><strong>0 - Super-Admin:</strong> Alle Funktionen + Farbeinstellungen + Benutzerverwaltung</li>
                        <li><strong>1 - Admin:</strong> Alle Funktionen + Benutzerverwaltung (keine Farbeinstellungen)</li>
                        <li><strong>2 - Standard:</strong> Discord Webhooks + Medien (keine Patchlist/File Browser)</li>
                        <li><strong>3 - Eingeschränkt:</strong> Nur Dashboard (keine weiteren Funktionen)</li>
                    </ul>
                </div>
                
                <div class="user-management-container">
                    <div class="user-table-wrapper">
                        <table id="usersTable">
                            <thead>
                                <tr>
                                    <th>Benutzername</th>
                                    <th>Rolle</th>
                                    <th>Erstellt</th>
                                    <th>Aktionen</th>
                                </tr>
                            </thead>
                            <tbody></tbody>
                        </table>
                    </div>
                    <div class="user-create-card">
                        <h3 style="margin:0 0 16px; color:var(--accent); font-size:16px;"><i class="fa fa-user-plus" aria-hidden="true"></i> Neuer Benutzer</h3>
                        <div style="display:flex; flex-direction:column; gap:12px;">
                            <div>
                                <label for="newUsername">Benutzername</label>
                                <input type="text" id="newUsername" placeholder="username" style="width:100%; padding:8px; border-radius:6px; border:1px solid #444; background:#111; color:#e0e0e0;" />
                            </div>
                            <div>
                                <label for="newPassword">Passwort</label>
                                <input type="password" id="newPassword" placeholder="passwort" style="width:100%; padding:8px; border-radius:6px; border:1px solid #444; background:#111; color:#e0e0e0;" />
                            </div>
                            <div>
                                <label for="newRole">Rolle</label>
                                <select id="newRole" style="width:100%; padding:8px; border-radius:6px; border:1px solid #444; background:#111; color:#e0e0e0;">
                                    <option value="1">1 (Admin)</option>
                                    <option value="2" selected>2 (Standard)</option>
                                    <option value="3">3 (Eingeschränkt)</option>
                                </select>
                            </div>
                            <button class="btn primary" type="button" onclick="createUser()" style="width:100%;"><i class="fa fa-user-plus" aria-hidden="true"></i> Benutzer erstellen</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        </div><!-- End Users Tab -->
        <?php endif; ?>
    </div>

    <form method="get" style="text-align:center;">
        <button class="btn warn logout" type="submit" name="logout"><i class="fa fa-sign-out-alt" aria-hidden="true"></i> Logout</button>
    </form>
</div>

<script src="https://unpkg.com/easymde/dist/easymde.min.js"></script>
<script>
// Dynamic configuration from PHP (must be inline)
window.userRole = <?= isset($_SESSION['role']) ? (int)$_SESSION['role'] : 1 ?>;
window.serverLayoutExists = <?= (file_exists($layoutFile) ? 'true' : 'false') ?>;
</script>
<script src="assets/admin.js?v=<?= $cacheVersion ?>"></script>
<script src="assets/admin-cache.js?v=<?= $cacheVersion ?>"></script>
<!-- Toast container -->
<div class="toasts" id="toasts" aria-live="polite" aria-atomic="true"></div>

<!-- Confirm Modal -->
<div id="confirmModal" role="dialog" aria-modal="true" style="display:none;position:fixed;inset:0;align-items:center;justify-content:center;z-index:2100;">
    <div style="background:var(--surface);border:1px solid rgba(255,255,255,0.04);padding:20px;border-radius:8px;min-width:320px;box-shadow:0 12px 36px rgba(0,0,0,0.5);">
        <div id="confirmModalMessage" style="margin-bottom:12px;color:var(--text)"></div>
        <div style="text-align:right;display:flex;gap:8px;justify-content:flex-end">
            <button class="btn ghost" id="confirmCancel"><i class="fa fa-times" aria-hidden="true"></i> Abbrechen</button>
            <button class="btn primary" id="confirmOk"><i class="fa fa-check" aria-hidden="true"></i> Bestätigen</button>
        </div>
    </div>
</div>

<!-- Webhook Modal -->
<div id="webhookModal" role="dialog" aria-modal="true" style="display:none;position:fixed;inset:0;align-items:center;justify-content:center;z-index:2100;background:rgba(0,0,0,0.75);">
    <div style="background:var(--surface);border:1px solid rgba(var(--glow-rgb-1, 255,179,0),0.2);padding:28px;border-radius:12px;min-width:500px;max-width:600px;box-shadow:0 20px 60px rgba(0,0,0,0.7);">
        <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:24px;">
            <h3 style="margin:0;color:var(--accent);display:flex;align-items:center;gap:10px;font-size:20px;">
                <i class="fa fa-plus-circle" aria-hidden="true"></i>
                <span id="webhookModalTitle">Neuer Webhook</span>
            </h3>
            <button id="webhookModalClose" style="background:none;border:none;color:var(--muted);font-size:24px;cursor:pointer;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:all 0.2s;" onmouseover="this.style.background='rgba(255,255,255,0.05)';this.style.color='var(--text)';" onmouseout="this.style.background='none';this.style.color='var(--muted)';">
                <i class="fa fa-times"></i>
            </button>
        </div>
        
        <div style="display:flex;flex-direction:column;gap:20px;">
            <div>
                <label for="webhookNameInput" style="display:block;margin-bottom:8px;font-weight:600;color:var(--text);font-size:14px;">
                    <i class="fa fa-tag" style="margin-right:6px;color:var(--accent);"></i>Webhook-Name
                </label>
                <input type="text" id="webhookNameInput" placeholder="z.B. Main Channel, Updates, Announcements..." style="width:100%;padding:12px;border-radius:8px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.3);color:var(--text);font-size:14px;transition:all 0.2s;" onfocus="this.style.borderColor='var(--accent)';this.style.boxShadow='0 0 0 3px rgba(var(--glow-rgb-1, 255,179,0),0.1)';" onblur="this.style.borderColor='rgba(255,255,255,0.08)';this.style.boxShadow='none';" />
            </div>
            
            <div>
                <label for="webhookUrlInput" style="display:block;margin-bottom:8px;font-weight:600;color:var(--text);font-size:14px;">
                    <i class="fa fa-link" style="margin-right:6px;color:var(--accent);"></i>Webhook-URL
                </label>
                <input type="url" id="webhookUrlInput" placeholder="https://discord.com/api/webhooks/..." style="width:100%;padding:12px;border-radius:8px;border:1px solid rgba(255,255,255,0.08);background:rgba(0,0,0,0.3);color:var(--text);font-size:14px;font-family:monospace;transition:all 0.2s;" onfocus="this.style.borderColor='var(--accent)';this.style.boxShadow='0 0 0 3px rgba(var(--glow-rgb-1, 255,179,0),0.1)';" onblur="this.style.borderColor='rgba(255,255,255,0.08)';this.style.boxShadow='none';" />
                <small style="display:block;margin-top:6px;color:var(--muted);font-size:12px;">
                    <i class="fa fa-info-circle"></i> Discord Server Einstellungen → Integrationen → Webhooks
                </small>
            </div>
            
            <div style="display:flex;align-items:center;gap:12px;padding:12px;background:rgba(var(--glow-rgb-1, 255,179,0),0.05);border-radius:8px;border:1px solid rgba(var(--glow-rgb-1, 255,179,0),0.1);">
                <input type="checkbox" id="webhookEnabledInput" checked style="width:20px;height:20px;cursor:pointer;accent-color:var(--accent);" />
                <label for="webhookEnabledInput" style="margin:0;cursor:pointer;font-size:14px;color:var(--text);user-select:none;">
                    <i class="fa fa-check-circle" style="margin-right:6px;color:#4caf50;"></i>Webhook aktivieren
                </label>
            </div>
        </div>
        
        <div style="display:flex;gap:12px;margin-top:28px;justify-content:flex-end;">
            <button id="webhookModalCancel" class="btn ghost" style="padding:10px 20px;">
                <i class="fa fa-times"></i> Abbrechen
            </button>
            <button id="webhookModalSave" class="btn primary" style="padding:10px 24px;">
                <i class="fa fa-save"></i> Speichern
            </button>
        </div>
    </div>
</div>

<!-- Super Admin Assignment Modal -->
<div id="superAdminModal" role="dialog" aria-modal="true" style="display:none;position:fixed;inset:0;align-items:center;justify-content:center;z-index:2100;background:rgba(0,0,0,0.7);">
    <div style="background:var(--surface);border:2px solid var(--accent);padding:24px;border-radius:12px;min-width:400px;box-shadow:0 12px 48px rgba(0,0,0,0.8);">
        <h3 style="margin:0 0 16px;color:var(--accent);display:flex;align-items:center;gap:8px;">
            <i class="fa fa-crown" aria-hidden="true"></i> Super-Admin Zuweisung
        </h3>
        <div style="margin-bottom:16px;color:var(--text);line-height:1.6;">
            <p style="margin:0 0 8px;">Benutzer <strong id="superAdminUsername"></strong> zu Super-Admin (Rolle 0) befördern?</p>
            <p style="margin:0;font-size:13px;color:var(--muted);">⚠️ Dies gewährt vollständigen Zugriff inkl. Farbeinstellungen!</p>
        </div>
        <div style="margin-bottom:20px;">
            <label for="superAdminPassword" style="display:block;margin-bottom:8px;color:var(--text);font-weight:600;">Passwort eingeben:</label>
            <input type="password" id="superAdminPassword" placeholder="Passwort..." style="width:100%;padding:10px;border-radius:6px;border:1px solid #444;background:#111;color:var(--text);" />
        </div>
        <div style="display:flex;gap:8px;justify-content:flex-end">
            <button class="btn ghost" id="superAdminCancel"><i class="fa fa-times" aria-hidden="true"></i> Abbrechen</button>
            <button class="btn primary" id="superAdminConfirm"><i class="fa fa-crown" aria-hidden="true"></i> Super-Admin zuweisen</button>
        </div>
    </div>
</div>

</body>
</html>
