package de.hackernet.wireguardtv.web

import android.content.Context
import android.content.Intent
import android.net.wifi.WifiManager
import android.util.Log
import de.hackernet.wireguardtv.data.TunnelRepository
import de.hackernet.wireguardtv.vpn.WireGuardTunnelService
import de.hackernet.wireguardtv.model.TunnelConfig
import de.hackernet.wireguardtv.data.AppSettings
import de.hackernet.wireguardtv.data.SettingsRepository
import de.hackernet.wireguardtv.util.IpGeoService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.net.ServerSocket
import java.net.Socket
import java.net.URLDecoder
import java.util.concurrent.atomic.AtomicBoolean

/**
 * Einfacher HTTP-Server für WireGuard Config Upload
 * Läuft auf konfigurierbarem Port und bietet eine Web-Oberfläche zum Hochladen von .conf Dateien
 * Optionaler Passwortschutz mit Session-Cookie
 */
class ConfigWebServer(
    private val context: Context,
    private var port: Int = 8080,
    private var passwordEnabled: Boolean = false,
    private var password: String = ""
) {
    private var serverSocket: ServerSocket? = null
    private val isRunning = AtomicBoolean(false)
    private val scope = CoroutineScope(Dispatchers.IO)

    // Session-Management
    private val validSessions = mutableSetOf<String>()
    private val sessionTimeout = 3600_000L // 1 Stunde

    var onConfigReceived: ((String, String) -> Unit)? = null // name, content
    var onStatusChanged: ((Boolean, String?, Int) -> Unit)? = null // running, ip, port
    var onConnectTunnel: ((String) -> Unit)? = null // tunnelId
    var onDisconnectTunnel: (() -> Unit)? = null
    var onSettingsChanged: (() -> Unit)? = null // für Neustart nach Settings-Änderung

    companion object {
        private const val TAG = "ConfigWebServer"
    }

    /**
     * Konfiguration aktualisieren
     */
    fun updateConfig(newPort: Int, newPasswordEnabled: Boolean, newPassword: String) {
        this.port = newPort
        this.passwordEnabled = newPasswordEnabled
        this.password = newPassword
        // Sessions ungültig machen bei Passwortänderung
        validSessions.clear()
    }

    fun getPort(): Int = port

    fun start() {
        if (isRunning.get()) return

        scope.launch {
            try {
                serverSocket = ServerSocket(port)
                isRunning.set(true)

                val ip = getDeviceIpAddress()
                Log.i(TAG, "Server gestartet auf http://$ip:$port")
                onStatusChanged?.invoke(true, ip, port)

                while (isRunning.get()) {
                    try {
                        val clientSocket = serverSocket?.accept() ?: break
                        scope.launch { handleClient(clientSocket) }
                    } catch (e: Exception) {
                        if (isRunning.get()) {
                            Log.e(TAG, "Fehler beim Akzeptieren: ${e.message}")
                        }
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "Server-Fehler: ${e.message}")
                onStatusChanged?.invoke(false, null, port)
            }
        }
    }

    fun stop() {
        isRunning.set(false)
        try {
            serverSocket?.close()
        } catch (e: Exception) {
            Log.e(TAG, "Fehler beim Stoppen: ${e.message}")
        }
        serverSocket = null
        onStatusChanged?.invoke(false, null, port)
    }

    fun isRunning(): Boolean = isRunning.get()

    fun getDeviceIpAddress(): String {
        return try {
            val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager
            val ipInt = wifiManager?.connectionInfo?.ipAddress ?: 0
            if (ipInt == 0) {
                // Fallback: Alle Netzwerk-Interfaces durchsuchen
                getIpFromNetworkInterfaces() ?: "0.0.0.0"
            } else {
                String.format(
                    "%d.%d.%d.%d",
                    ipInt and 0xff,
                    ipInt shr 8 and 0xff,
                    ipInt shr 16 and 0xff,
                    ipInt shr 24 and 0xff
                )
            }
        } catch (e: Exception) {
            Log.e(TAG, "Fehler beim Ermitteln der IP: ${e.message}")
            getIpFromNetworkInterfaces() ?: "0.0.0.0"
        }
    }

    private fun getIpFromNetworkInterfaces(): String? {
        try {
            val interfaces = java.net.NetworkInterface.getNetworkInterfaces()
            while (interfaces.hasMoreElements()) {
                val iface = interfaces.nextElement()
                if (iface.isLoopback || !iface.isUp) continue

                val addresses = iface.inetAddresses
                while (addresses.hasMoreElements()) {
                    val addr = addresses.nextElement()
                    if (addr is java.net.Inet4Address && !addr.isLoopbackAddress) {
                        return addr.hostAddress
                    }
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "Fehler bei NetworkInterface: ${e.message}")
        }
        return null
    }

    private fun handleClient(socket: Socket) {
        try {
            socket.soTimeout = 30000
            val input = BufferedReader(InputStreamReader(socket.getInputStream()))
            val output = PrintWriter(socket.getOutputStream(), true)

            val requestLine = input.readLine() ?: return
            Log.d(TAG, "Request: $requestLine")

            val headers = mutableMapOf<String, String>()
            var line: String?
            while (input.readLine().also { line = it } != null && line!!.isNotEmpty()) {
                val colonIndex = line!!.indexOf(':')
                if (colonIndex > 0) {
                    headers[line!!.substring(0, colonIndex).trim().lowercase()] =
                        line!!.substring(colonIndex + 1).trim()
                }
            }

            // Session-Cookie extrahieren
            val sessionId = headers["cookie"]?.split(";")
                ?.map { it.trim() }
                ?.find { it.startsWith("session=") }
                ?.substringAfter("session=")

            val isAuthenticated = !passwordEnabled || validSessions.contains(sessionId)

            when {
                // Login-Seite und Login-Handler immer zugänglich
                requestLine.startsWith("GET /login") -> {
                    sendLoginPage(output)
                }
                requestLine.startsWith("POST /login") -> {
                    handleLogin(input, output, headers)
                }
                requestLine.startsWith("GET /logout") -> {
                    handleLogout(output, sessionId)
                }
                // Alles andere erfordert Authentifizierung wenn Passwort gesetzt
                !isAuthenticated -> {
                    sendRedirectToLogin(output)
                }
                requestLine.startsWith("GET / ") || requestLine.startsWith("GET /index") -> {
                    sendHtmlPage(output)
                }
                requestLine.startsWith("POST /upload") -> {
                    handleUpload(input, output, headers)
                }
                requestLine.startsWith("GET /api/tunnels") -> {
                    handleGetTunnels(output)
                }
                requestLine.startsWith("DELETE /api/tunnel/") -> {
                    val tunnelId = requestLine.substringAfter("/api/tunnel/").substringBefore(" ")
                    handleDeleteTunnel(output, tunnelId)
                }
                requestLine.startsWith("POST /api/tunnel/") && requestLine.contains("/connect") -> {
                    val tunnelId = requestLine.substringAfter("/api/tunnel/").substringBefore("/connect")
                    handleConnectTunnel(output, tunnelId)
                }
                requestLine.startsWith("POST /api/disconnect") -> {
                    handleDisconnectTunnel(output)
                }
                // Tunnel bearbeiten
                requestLine.startsWith("GET /api/tunnel/") && requestLine.contains("/edit") -> {
                    val tunnelId = requestLine.substringAfter("/api/tunnel/").substringBefore("/edit")
                    handleGetTunnelForEdit(output, tunnelId)
                }
                requestLine.startsWith("PUT /api/tunnel/") ||
                (requestLine.startsWith("POST /api/tunnel/") && requestLine.contains("/update")) -> {
                    val tunnelId = if (requestLine.contains("/update")) {
                        requestLine.substringAfter("/api/tunnel/").substringBefore("/update")
                    } else {
                        requestLine.substringAfter("/api/tunnel/").substringBefore(" ")
                    }
                    handleUpdateTunnel(input, output, headers, tunnelId)
                }
                // Autostart toggle
                requestLine.startsWith("POST /api/tunnel/") && requestLine.contains("/autostart") -> {
                    val tunnelId = requestLine.substringAfter("/api/tunnel/").substringBefore("/autostart")
                    handleToggleAutostart(input, output, headers, tunnelId)
                }
                // Settings API
                requestLine.startsWith("GET /api/settings") -> {
                    handleGetSettings(output)
                }
                requestLine.startsWith("POST /api/settings") -> {
                    handleUpdateSettings(input, output, headers)
                }
                // Geo Info API
                requestLine.startsWith("GET /api/geoinfo") -> {
                    handleGetGeoInfo(output)
                }
                requestLine.startsWith("GET /status") -> {
                    sendJson(output, """{"status": "ready", "device": "WireGuard TV"}""")
                }
                else -> {
                    send404(output)
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "Client-Fehler: ${e.message}")
        } finally {
            try { socket.close() } catch (e: Exception) {}
        }
    }

    private fun handleUpload(input: BufferedReader, output: PrintWriter, headers: Map<String, String>) {
        try {
            val contentLength = headers["content-length"]?.toIntOrNull() ?: 0
            val contentType = headers["content-type"] ?: ""

            if (contentLength == 0) {
                sendJson(output, """{"success": false, "error": "Keine Daten empfangen"}""")
                return
            }

            val body = CharArray(contentLength)
            var totalRead = 0
            while (totalRead < contentLength) {
                val read = input.read(body, totalRead, contentLength - totalRead)
                if (read == -1) break
                totalRead += read
            }
            val bodyString = String(body, 0, totalRead)

            var configName = "Imported"
            var configContent = ""

            if (contentType.contains("multipart/form-data")) {
                // Multipart Form Data parsen
                val boundary = contentType.substringAfter("boundary=").trim()
                val parts = bodyString.split("--$boundary")

                for (part in parts) {
                    if (part.contains("name=\"configName\"")) {
                        configName = part.substringAfter("\r\n\r\n").trim().substringBefore("\r\n")
                    } else if (part.contains("name=\"configFile\"") || part.contains("name=\"configContent\"")) {
                        configContent = part.substringAfter("\r\n\r\n").trim()
                        if (configContent.endsWith("\r\n")) {
                            configContent = configContent.dropLast(2)
                        }
                    }
                }
            } else if (contentType.contains("application/x-www-form-urlencoded")) {
                // URL-encoded Form Data
                val params = bodyString.split("&").associate {
                    val (key, value) = it.split("=", limit = 2)
                    URLDecoder.decode(key, "UTF-8") to URLDecoder.decode(value, "UTF-8")
                }
                configName = params["configName"] ?: "Imported"
                configContent = params["configContent"] ?: ""
            } else {
                // Raw config content
                configContent = bodyString
            }

            if (configContent.isBlank()) {
                sendJson(output, """{"success": false, "error": "Keine Config-Daten gefunden"}""")
                return
            }

            // Config validieren
            if (!configContent.contains("[Interface]") || !configContent.contains("[Peer]")) {
                sendJson(output, """{"success": false, "error": "Ungültige WireGuard Config (missing [Interface] or [Peer])"}""")
                return
            }

            // Config speichern
            try {
                // fromConfString(confString, name) - Parameter-Reihenfolge beachten!
                val tunnel = TunnelConfig.fromConfString(configContent, configName)
                val repository = TunnelRepository.getInstance(context)

                scope.launch {
                    repository.addTunnel(tunnel)
                    onConfigReceived?.invoke(configName, configContent)
                }

                sendJson(output, """{"success": true, "message": "Config '$configName' erfolgreich importiert!", "tunnelId": "${tunnel.id}"}""")
                Log.i(TAG, "Config importiert: $configName")

            } catch (e: Exception) {
                sendJson(output, """{"success": false, "error": "Fehler beim Parsen: ${e.message}"}""")
            }

        } catch (e: Exception) {
            Log.e(TAG, "Upload-Fehler: ${e.message}")
            sendJson(output, """{"success": false, "error": "${e.message}"}""")
        }
    }

    private fun sendHtmlPage(output: PrintWriter) {
        val html = """
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WireGuard TV</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            min-height: 100vh;
            padding: 20px;
            color: #fff;
        }
        .app-container { max-width: 900px; margin: 0 auto; }
        .header { text-align: center; margin-bottom: 30px; }
        .header svg { width: 60px; height: 60px; }
        .header h1 { margin: 10px 0 5px; font-size: 1.8em; }
        .header .subtitle { color: #88B4E7; }
        .tabs { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
        .tab {
            flex: 1; min-width: 120px; padding: 15px;
            background: rgba(255,255,255,0.1); border: none; border-radius: 10px;
            color: #fff; font-size: 14px; cursor: pointer; transition: all 0.3s;
        }
        .tab:hover, .tab.active { background: rgba(136, 180, 231, 0.3); }
        .tab.active { border-bottom: 3px solid #FF5722; }
        .panel { display: none; background: rgba(255,255,255,0.1); backdrop-filter: blur(10px); border-radius: 20px; padding: 30px; }
        .panel.active { display: block; }
        .tunnel-list { display: flex; flex-direction: column; gap: 15px; }
        .tunnel-card {
            background: rgba(0,0,0,0.3); border-radius: 15px; padding: 20px;
            border: 2px solid transparent; transition: all 0.3s;
        }
        .tunnel-card:hover { border-color: #88B4E7; }
        .tunnel-card.active { border-color: #4CAF50; background: rgba(76, 175, 80, 0.1); }
        .tunnel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; flex-wrap: wrap; gap: 10px; }
        .tunnel-info h3 { margin-bottom: 5px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
        .tunnel-info .endpoint { color: #888; font-size: 14px; }
        .status-badge { background: #4CAF50; color: #fff; padding: 3px 10px; border-radius: 20px; font-size: 12px; }
        .autostart-badge { background: #2196F3; color: #fff; padding: 3px 10px; border-radius: 20px; font-size: 12px; }
        .tunnel-actions { display: flex; gap: 8px; flex-wrap: wrap; }
        .btn {
            padding: 8px 16px; border: none; border-radius: 8px;
            cursor: pointer; font-size: 13px; transition: all 0.2s;
        }
        .btn-connect { background: #4CAF50; color: #fff; }
        .btn-disconnect { background: #FF9800; color: #fff; }
        .btn-edit { background: #2196F3; color: #fff; }
        .btn-autostart { background: #9C27B0; color: #fff; }
        .btn-autostart.active { background: #7B1FA2; }
        .password-wrapper { position: relative; }
        .password-wrapper input { padding-right: 45px; }
        .password-toggle {
            position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
            background: none; border: none; color: #888; cursor: pointer; padding: 5px;
        }
        .password-toggle:hover { color: #fff; }
        .btn-delete { background: #f44336; color: #fff; }
        .btn-secondary { background: rgba(255,255,255,0.2); color: #fff; }
        .btn:hover { transform: translateY(-2px); box-shadow: 0 4px 15px rgba(0,0,0,0.3); }
        .btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }
        .empty-state { text-align: center; padding: 40px; color: #888; }
        .form-group { margin-bottom: 20px; }
        label { display: block; margin-bottom: 8px; font-weight: 500; }
        input[type="text"], input[type="number"], input[type="password"], textarea {
            width: 100%; padding: 12px;
            border: 2px solid rgba(255,255,255,0.2); border-radius: 10px;
            background: rgba(0,0,0,0.3); color: #fff; font-size: 16px;
        }
        input:focus, textarea:focus { outline: none; border-color: #88B4E7; }
        textarea { min-height: 150px; font-family: monospace; resize: vertical; }
        input[type="file"] { display: none; }
        .file-label {
            display: block; padding: 15px;
            background: rgba(136, 180, 231, 0.2); border: 2px dashed #88B4E7;
            border-radius: 10px; text-align: center; cursor: pointer;
        }
        .file-label:hover { background: rgba(136, 180, 231, 0.3); }
        .file-label.has-file { border-style: solid; }
        .or-divider { text-align: center; margin: 20px 0; color: #888; }
        .submit-btn {
            width: 100%; padding: 15px;
            background: linear-gradient(135deg, #FF5722 0%, #E64A19 100%);
            border: none; border-radius: 10px; color: #fff;
            font-size: 18px; font-weight: 600; cursor: pointer;
        }
        .submit-btn:hover { transform: translateY(-2px); box-shadow: 0 4px 15px rgba(255, 87, 34, 0.4); }
        .message { margin-top: 20px; padding: 15px; border-radius: 10px; text-align: center; display: none; }
        .message.success { background: rgba(76, 175, 80, 0.3); border: 1px solid #4CAF50; display: block; }
        .message.error { background: rgba(244, 67, 54, 0.3); border: 1px solid #f44336; display: block; }
        .refresh-btn {
            background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2);
            color: #fff; padding: 8px 15px; border-radius: 8px; cursor: pointer; margin-bottom: 15px;
        }
        .refresh-btn:hover { background: rgba(255,255,255,0.2); }
        .modal {
            display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(0,0,0,0.8); z-index: 1000; align-items: center; justify-content: center;
        }
        .modal.active { display: flex; }
        .modal-content {
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            border-radius: 20px; padding: 30px; max-width: 600px; width: 90%; max-height: 90vh; overflow-y: auto;
        }
        .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
        .modal-close { background: none; border: none; color: #fff; font-size: 24px; cursor: pointer; }
        .checkbox-group { display: flex; align-items: center; gap: 10px; margin-bottom: 15px; }
        .checkbox-group input[type="checkbox"] { width: 20px; height: 20px; }
        .settings-section { margin-bottom: 30px; padding-bottom: 20px; border-bottom: 1px solid rgba(255,255,255,0.1); }
        .settings-section:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }
        .settings-section h3 { margin-bottom: 15px; color: #88B4E7; }
        .geo-info-box {
            background: rgba(0,0,0,0.3); border-radius: 15px; padding: 20px; margin-bottom: 20px;
            display: flex; align-items: center; gap: 15px; flex-wrap: wrap;
        }
        .geo-info-box.connected { border: 2px solid #4CAF50; }
        .geo-info-box.disconnected { border: 2px solid #666; }
        .geo-flag { font-size: 48px; line-height: 1; }
        .geo-details { flex: 1; min-width: 200px; }
        .geo-ip { font-size: 24px; font-weight: bold; color: #fff; margin-bottom: 5px; }
        .geo-location { font-size: 16px; color: #88B4E7; }
        .geo-status { font-size: 14px; margin-top: 8px; }
        .geo-status.connected { color: #4CAF50; }
        .geo-status.disconnected { color: #888; }
        .geo-loading { color: #888; font-style: italic; }
    </style>
</head>
<body>
    <div class="app-container">
        <div class="header">
            <svg viewBox="0 0 48 48" fill="none">
                <path d="M24 4L8 12v12c0 11.1 6.84 21.48 16 24 9.16-2.52 16-12.9 16-24V12L24 4z" fill="#FF5722"/>
                <path d="M24 4L8 12v12c0 11.1 6.84 21.48 16 24V4z" fill="#E64A19"/>
            </svg>
            <h1>WireGuard TV</h1>
            <p class="subtitle">VPN Management</p>
        </div>

        <div class="tabs">
            <button class="tab active" onclick="showPanel('tunnels', this)">Tunnel verwalten</button>
            <button class="tab" onclick="showPanel('upload', this)">Config hochladen</button>
            <button class="tab" onclick="showPanel('settings', this)">Einstellungen</button>
        </div>

        <div id="tunnels-panel" class="panel active">
            <div id="geo-info" class="geo-info-box disconnected">
                <div class="geo-loading">Lade Standort-Info...</div>
            </div>
            <button class="refresh-btn" onclick="loadTunnels(); loadGeoInfo();">Aktualisieren</button>
            <div id="tunnel-list" class="tunnel-list">
                <div class="empty-state">Lade Tunnel...</div>
            </div>
        </div>

        <div id="upload-panel" class="panel">
            <form id="uploadForm">
                <div class="form-group">
                    <label for="configName">Tunnel Name</label>
                    <input type="text" id="configName" name="configName" placeholder="z.B. Home VPN" required>
                </div>
                <div class="form-group">
                    <label>.conf Datei auswählen</label>
                    <label class="file-label" id="fileLabel">
                        <input type="file" id="configFile" accept=".conf">
                        <span id="fileLabelText">Datei auswählen oder hierher ziehen</span>
                    </label>
                </div>
                <div class="or-divider">— oder Config einfügen —</div>
                <div class="form-group">
                    <label for="configContent">WireGuard Config</label>
                    <textarea id="configContent" name="configContent" placeholder="[Interface]
PrivateKey = ...
Address = 10.0.0.2/24

[Peer]
PublicKey = ...
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0"></textarea>
                </div>
                <button type="submit" class="submit-btn" id="submitBtn">Config hochladen</button>
            </form>
            <div id="message" class="message"></div>
        </div>

        <div id="settings-panel" class="panel">
            <form id="settingsForm">
                <div class="settings-section">
                    <h3>WebServer Einstellungen</h3>
                    <div class="form-group">
                        <label for="serverPort">Port</label>
                        <input type="number" id="serverPort" name="port" min="1" max="65535" value="8080">
                    </div>
                    <div class="checkbox-group">
                        <input type="checkbox" id="passwordEnabled" name="passwordEnabled">
                        <label for="passwordEnabled" style="margin-bottom:0">Passwortschutz aktivieren</label>
                    </div>
                    <div class="form-group" id="passwordGroup" style="display:none">
                        <label for="serverPassword">Passwort</label>
                        <div class="password-wrapper">
                            <input type="password" id="serverPassword" name="password" placeholder="Passwort eingeben">
                            <button type="button" class="password-toggle" onclick="togglePasswordVisibility()" title="Passwort anzeigen">
                                <svg id="eyeIcon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                    <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
                                    <circle cx="12" cy="12" r="3"/>
                                </svg>
                            </button>
                        </div>
                    </div>
                    <div class="checkbox-group">
                        <input type="checkbox" id="autoStart" name="autoStart">
                        <label for="autoStart" style="margin-bottom:0">Server automatisch beim Gerätestart starten</label>
                    </div>
                </div>
                <button type="submit" class="submit-btn">Einstellungen speichern & Server neustarten</button>
            </form>
            <div id="settingsMessage" class="message"></div>
        </div>
    </div>

    <!-- Edit Modal -->
    <div id="editModal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <h2>Tunnel bearbeiten</h2>
                <button class="modal-close" onclick="closeEditModal()">&times;</button>
            </div>
            <form id="editForm">
                <input type="hidden" id="editTunnelId">
                <div class="form-group">
                    <label for="editName">Tunnel Name</label>
                    <input type="text" id="editName" required>
                </div>
                <div class="form-group">
                    <label for="editConfig">WireGuard Config</label>
                    <textarea id="editConfig" style="min-height:250px"></textarea>
                </div>
                <button type="submit" class="submit-btn">Speichern</button>
            </form>
        </div>
    </div>

    <script>
        function showPanel(name, btn) {
            document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
            document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
            document.getElementById(name + '-panel').classList.add('active');
            if (btn) btn.classList.add('active');
            if (name === 'tunnels') loadTunnels();
            if (name === 'settings') loadSettings();
        }

        async function loadTunnels() {
            const list = document.getElementById('tunnel-list');
            list.innerHTML = '<div class="empty-state">Lade...</div>';
            try {
                const res = await fetch('/api/tunnels');
                const data = await res.json();
                if (data.error) throw new Error(data.error);
                if (!data.tunnels || data.tunnels.length === 0) {
                    list.innerHTML = '<div class="empty-state">Keine Tunnel konfiguriert.<br>Lade eine Config hoch!</div>';
                    return;
                }
                list.innerHTML = data.tunnels.map(t => {
                    const isActive = t.active;
                    const isAutostart = t.autostart;
                    return '<div class="tunnel-card ' + (isActive ? 'active' : '') + '">' +
                        '<div class="tunnel-header">' +
                            '<div class="tunnel-info">' +
                                '<h3>' + esc(t.name) +
                                    (isActive ? ' <span class="status-badge">Verbunden</span>' : '') +
                                    (isAutostart ? ' <span class="autostart-badge">Autostart</span>' : '') +
                                '</h3>' +
                                '<div class="endpoint">' + esc(t.endpoint) + '</div>' +
                            '</div>' +
                        '</div>' +
                        '<div class="tunnel-actions">' +
                            (isActive
                                ? '<button class="btn btn-disconnect" onclick="disconnectTunnel()">Trennen</button>'
                                : '<button class="btn btn-connect" onclick="connectTunnel(\'' + t.id + '\')">Verbinden</button>') +
                            '<button class="btn btn-edit" onclick="editTunnel(\'' + t.id + '\')">Bearbeiten</button>' +
                            '<button class="btn btn-autostart' + (isAutostart ? ' active' : '') + '" onclick="toggleAutostart(\'' + t.id + '\',' + !isAutostart + ')">' +
                                (isAutostart ? 'Autostart ausschalten' : 'Autostart anschalten') + '</button>' +
                            '<button class="btn btn-delete" onclick="deleteTunnel(\'' + t.id + '\',\'' + esc(t.name) + '\')">Löschen</button>' +
                        '</div>' +
                    '</div>';
                }).join('');
            } catch (e) {
                list.innerHTML = '<div class="empty-state">Fehler beim Laden: ' + esc(e.message) + '</div>';
            }
        }

        async function connectTunnel(id) {
            try {
                const res = await fetch('/api/tunnel/' + id + '/connect', { method: 'POST' });
                const data = await res.json();
                if (data.success) setTimeout(loadTunnels, 1000);
                else alert('Fehler: ' + data.error);
            } catch (e) { alert('Fehler: ' + e.message); }
        }

        async function disconnectTunnel() {
            try {
                const res = await fetch('/api/disconnect', { method: 'POST' });
                const data = await res.json();
                if (data.success) setTimeout(loadTunnels, 1000);
            } catch (e) { alert('Fehler: ' + e.message); }
        }

        async function deleteTunnel(id, name) {
            if (!confirm('Tunnel "' + name + '" wirklich löschen?')) return;
            try {
                const res = await fetch('/api/tunnel/' + id, { method: 'DELETE' });
                const data = await res.json();
                if (data.success) loadTunnels();
                else alert('Fehler: ' + data.error);
            } catch (e) { alert('Fehler: ' + e.message); }
        }

        async function editTunnel(id) {
            try {
                const res = await fetch('/api/tunnel/' + id + '/edit');
                const data = await res.json();
                if (data.success) {
                    document.getElementById('editTunnelId').value = id;
                    document.getElementById('editName').value = data.tunnel.name;
                    document.getElementById('editConfig').value = data.tunnel.config;
                    document.getElementById('editModal').classList.add('active');
                } else alert('Fehler: ' + data.error);
            } catch (e) { alert('Fehler: ' + e.message); }
        }

        function closeEditModal() {
            document.getElementById('editModal').classList.remove('active');
        }

        document.getElementById('editForm').addEventListener('submit', async (e) => {
            e.preventDefault();
            const id = document.getElementById('editTunnelId').value;
            const name = document.getElementById('editName').value;
            const config = document.getElementById('editConfig').value;
            try {
                const formData = new FormData();
                formData.append('configName', name);
                formData.append('configContent', config);
                const res = await fetch('/api/tunnel/' + id + '/update', { method: 'POST', body: formData });
                const data = await res.json();
                if (data.success) {
                    closeEditModal();
                    loadTunnels();
                } else alert('Fehler: ' + data.error);
            } catch (e) { alert('Fehler: ' + e.message); }
        });

        async function toggleAutostart(id, enable) {
            try {
                const formData = new FormData();
                formData.append('enable', enable.toString());
                const res = await fetch('/api/tunnel/' + id + '/autostart', { method: 'POST', body: formData });
                const data = await res.json();
                if (data.success) {
                    // Bei Aktivierung warten (wegen VPN-Verbindungsaufbau), bei Deaktivierung sofort laden
                    setTimeout(loadTunnels, enable ? 1000 : 200);
                } else alert('Fehler: ' + data.error);
            } catch (e) { alert('Fehler: ' + e.message); }
        }

        function togglePasswordVisibility() {
            const pwInput = document.getElementById('serverPassword');
            const eyeIcon = document.getElementById('eyeIcon');
            if (pwInput.type === 'password') {
                pwInput.type = 'text';
                eyeIcon.innerHTML = '<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/>';
            } else {
                pwInput.type = 'password';
                eyeIcon.innerHTML = '<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';
            }
        }

        async function loadSettings() {
            try {
                const res = await fetch('/api/settings');
                const data = await res.json();
                if (data.success) {
                    document.getElementById('serverPort').value = data.settings.webServerPort;
                    document.getElementById('passwordEnabled').checked = data.settings.webServerPasswordEnabled;
                    document.getElementById('serverPassword').value = data.settings.webServerPassword || '';
                    document.getElementById('autoStart').checked = data.settings.webServerAutoStart;
                    togglePasswordField();
                }
            } catch (e) { console.error('Settings load error:', e); }
        }

        document.getElementById('passwordEnabled').addEventListener('change', togglePasswordField);
        function togglePasswordField() {
            const enabled = document.getElementById('passwordEnabled').checked;
            document.getElementById('passwordGroup').style.display = enabled ? 'block' : 'none';
        }

        document.getElementById('settingsForm').addEventListener('submit', async (e) => {
            e.preventDefault();
            const msg = document.getElementById('settingsMessage');
            try {
                const formData = new URLSearchParams();
                formData.append('port', document.getElementById('serverPort').value);
                formData.append('passwordEnabled', document.getElementById('passwordEnabled').checked);
                formData.append('password', document.getElementById('serverPassword').value);
                formData.append('autoStart', document.getElementById('autoStart').checked);
                const res = await fetch('/api/settings', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                    body: formData
                });
                const data = await res.json();
                if (data.success) {
                    msg.textContent = data.message;
                    msg.className = 'message success';
                    if (data.needsRestart) {
                        setTimeout(() => {
                            msg.textContent = 'Bitte Seite neu laden...';
                        }, 2000);
                    }
                } else {
                    msg.textContent = data.error;
                    msg.className = 'message error';
                }
            } catch (e) {
                msg.textContent = 'Fehler: ' + e.message;
                msg.className = 'message error';
            }
        });

        function esc(text) {
            if (!text) return '';
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        // Upload Form
        const form = document.getElementById('uploadForm');
        const fileInput = document.getElementById('configFile');
        const fileLabel = document.getElementById('fileLabel');
        const fileLabelText = document.getElementById('fileLabelText');
        const configContent = document.getElementById('configContent');
        const configName = document.getElementById('configName');
        const message = document.getElementById('message');
        const submitBtn = document.getElementById('submitBtn');

        fileInput.addEventListener('change', (e) => {
            const file = e.target.files[0];
            if (file) {
                fileLabelText.textContent = file.name;
                fileLabel.classList.add('has-file');
                if (!configName.value) configName.value = file.name.replace('.conf', '');
                const reader = new FileReader();
                reader.onload = (ev) => { configContent.value = ev.target.result; };
                reader.readAsText(file);
            }
        });

        fileLabel.addEventListener('dragover', (e) => { e.preventDefault(); fileLabel.style.borderColor = '#fff'; });
        fileLabel.addEventListener('dragleave', () => { fileLabel.style.borderColor = '#88B4E7'; });
        fileLabel.addEventListener('drop', (e) => {
            e.preventDefault();
            fileLabel.style.borderColor = '#88B4E7';
            if (e.dataTransfer.files[0]) {
                fileInput.files = e.dataTransfer.files;
                fileInput.dispatchEvent(new Event('change'));
            }
        });

        form.addEventListener('submit', async (e) => {
            e.preventDefault();
            const name = configName.value.trim();
            const content = configContent.value.trim();
            if (!name || !content) { showMsg('Bitte Name und Config eingeben', false); return; }
            submitBtn.disabled = true;
            submitBtn.textContent = 'Wird hochgeladen...';
            try {
                const formData = new FormData();
                formData.append('configName', name);
                formData.append('configContent', content);
                const res = await fetch('/upload', { method: 'POST', body: formData });
                const result = await res.json();
                if (result.success) {
                    showMsg(result.message, true);
                    form.reset();
                    fileLabelText.textContent = 'Datei auswählen oder hierher ziehen';
                    fileLabel.classList.remove('has-file');
                } else showMsg(result.error, false);
            } catch (err) { showMsg('Fehler: ' + err.message, false); }
            finally { submitBtn.disabled = false; submitBtn.textContent = 'Config hochladen'; }
        });

        function showMsg(text, success) {
            message.textContent = text;
            message.className = 'message ' + (success ? 'success' : 'error');
        }

        // Geo Info
        let geoRefreshInterval = null;

        async function loadGeoInfo() {
            const geoBox = document.getElementById('geo-info');
            try {
                const res = await fetch('/api/geoinfo');
                const data = await res.json();
                if (data.success) {
                    const statusClass = data.connected ? 'connected' : 'disconnected';
                    const statusText = data.connected ? '🔒 VPN verbunden' : '🔓 Nicht verbunden';
                    geoBox.className = 'geo-info-box ' + statusClass;
                    geoBox.innerHTML =
                        '<div class="geo-flag">' + data.flag + '</div>' +
                        '<div class="geo-details">' +
                            '<div class="geo-ip">' + esc(data.ip) + '</div>' +
                            '<div class="geo-location">' + esc(data.countryName) + (data.city ? ', ' + esc(data.city) : '') + '</div>' +
                            '<div class="geo-status ' + statusClass + '">' + statusText + '</div>' +
                        '</div>';
                } else {
                    geoBox.className = 'geo-info-box disconnected';
                    geoBox.innerHTML = '<div class="geo-loading">Standort konnte nicht ermittelt werden</div>';
                }
            } catch (e) {
                geoBox.className = 'geo-info-box disconnected';
                geoBox.innerHTML = '<div class="geo-loading">Fehler: ' + esc(e.message) + '</div>';
            }
        }

        function startGeoRefresh() {
            // Sofort laden
            loadGeoInfo();
            // Alle 30 Sekunden aktualisieren
            if (geoRefreshInterval) clearInterval(geoRefreshInterval);
            geoRefreshInterval = setInterval(loadGeoInfo, 30000);
        }

        function stopGeoRefresh() {
            if (geoRefreshInterval) {
                clearInterval(geoRefreshInterval);
                geoRefreshInterval = null;
            }
        }

        // Bei Tab-Wechsel Geo-Refresh starten/stoppen und Formulare zurücksetzen
        const originalShowPanel = showPanel;
        showPanel = function(name, btn) {
            document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
            document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
            document.getElementById(name + '-panel').classList.add('active');
            if (btn) btn.classList.add('active');
            if (name === 'tunnels') {
                loadTunnels();
                startGeoRefresh();
            } else {
                stopGeoRefresh();
            }
            if (name === 'settings') loadSettings();
            if (name === 'upload') {
                // Upload-Formular zurücksetzen
                document.getElementById('uploadForm').reset();
                document.getElementById('fileLabelText').textContent = 'Datei auswählen oder hierher ziehen';
                document.getElementById('fileLabel').classList.remove('has-file');
                document.getElementById('message').textContent = '';
                document.getElementById('message').className = 'message';
            }
        };

        // Initial load
        loadTunnels();
        startGeoRefresh();
    </script>
</body>
</html>
        """.trimIndent()

        output.print("HTTP/1.1 200 OK\r\n")
        output.print("Content-Type: text/html; charset=utf-8\r\n")
        output.print("Content-Length: ${html.toByteArray(Charsets.UTF_8).size}\r\n")
        output.print("Connection: close\r\n")
        output.print("\r\n")
        output.print(html)
        output.flush()
    }

    private fun sendJson(output: PrintWriter, json: String) {
        output.print("HTTP/1.1 200 OK\r\n")
        output.print("Content-Type: application/json; charset=utf-8\r\n")
        output.print("Content-Length: ${json.toByteArray(Charsets.UTF_8).size}\r\n")
        output.print("Access-Control-Allow-Origin: *\r\n")
        output.print("Connection: close\r\n")
        output.print("\r\n")
        output.print(json)
        output.flush()
    }

    private fun send404(output: PrintWriter) {
        val body = "Not Found"
        output.print("HTTP/1.1 404 Not Found\r\n")
        output.print("Content-Type: text/plain\r\n")
        output.print("Content-Length: ${body.length}\r\n")
        output.print("Connection: close\r\n")
        output.print("\r\n")
        output.print(body)
        output.flush()
    }

    private fun sendRedirectToLogin(output: PrintWriter) {
        output.print("HTTP/1.1 302 Found\r\n")
        output.print("Location: /login\r\n")
        output.print("Connection: close\r\n")
        output.print("\r\n")
        output.flush()
    }

    private fun handleLogin(input: BufferedReader, output: PrintWriter, headers: Map<String, String>) {
        try {
            val contentLength = headers["content-length"]?.toIntOrNull() ?: 0
            if (contentLength == 0) {
                sendLoginPage(output, "Bitte Passwort eingeben")
                return
            }

            val body = CharArray(contentLength)
            var totalRead = 0
            while (totalRead < contentLength) {
                val read = input.read(body, totalRead, contentLength - totalRead)
                if (read == -1) break
                totalRead += read
            }
            val bodyString = String(body, 0, totalRead)

            // Passwort aus Form-Daten extrahieren
            val params = bodyString.split("&").associate {
                val parts = it.split("=", limit = 2)
                val key = URLDecoder.decode(parts.getOrElse(0) { "" }, "UTF-8")
                val value = URLDecoder.decode(parts.getOrElse(1) { "" }, "UTF-8")
                key to value
            }
            val submittedPassword = params["password"] ?: ""

            if (submittedPassword == password) {
                // Login erfolgreich - Session erstellen
                val sessionId = java.util.UUID.randomUUID().toString()
                validSessions.add(sessionId)
                Log.i(TAG, "Login erfolgreich, Session: $sessionId")

                output.print("HTTP/1.1 302 Found\r\n")
                output.print("Location: /\r\n")
                output.print("Set-Cookie: session=$sessionId; Path=/; HttpOnly; Max-Age=3600\r\n")
                output.print("Connection: close\r\n")
                output.print("\r\n")
                output.flush()
            } else {
                Log.w(TAG, "Login fehlgeschlagen - falsches Passwort")
                sendLoginPage(output, "Falsches Passwort")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Login-Fehler: ${e.message}")
            sendLoginPage(output, "Fehler: ${e.message}")
        }
    }

    private fun handleLogout(output: PrintWriter, sessionId: String?) {
        sessionId?.let { validSessions.remove(it) }
        output.print("HTTP/1.1 302 Found\r\n")
        output.print("Location: /login\r\n")
        output.print("Set-Cookie: session=; Path=/; HttpOnly; Max-Age=0\r\n")
        output.print("Connection: close\r\n")
        output.print("\r\n")
        output.flush()
    }

    private fun sendLoginPage(output: PrintWriter, errorMessage: String? = null) {
        val html = """
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WireGuard TV - Login</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #fff;
        }
        .login-container {
            background: rgba(255,255,255,0.1);
            backdrop-filter: blur(10px);
            border-radius: 20px;
            padding: 40px;
            width: 100%;
            max-width: 400px;
            text-align: center;
        }
        .logo {
            width: 80px;
            height: 80px;
            margin-bottom: 20px;
        }
        h1 {
            margin-bottom: 10px;
            font-size: 1.8em;
        }
        .subtitle {
            color: #88B4E7;
            margin-bottom: 30px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        input[type="password"] {
            width: 100%;
            padding: 15px;
            border: 2px solid rgba(255,255,255,0.2);
            border-radius: 10px;
            background: rgba(0,0,0,0.3);
            color: #fff;
            font-size: 16px;
            text-align: center;
        }
        input[type="password"]:focus {
            outline: none;
            border-color: #FF5722;
        }
        input[type="password"]::placeholder {
            color: rgba(255,255,255,0.5);
        }
        .submit-btn {
            width: 100%;
            padding: 15px;
            background: linear-gradient(135deg, #FF5722 0%, #E64A19 100%);
            border: none;
            border-radius: 10px;
            color: #fff;
            font-size: 18px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.2s;
        }
        .submit-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(255, 87, 34, 0.4);
        }
        .error-message {
            background: rgba(244, 67, 54, 0.3);
            border: 1px solid #f44336;
            padding: 10px;
            border-radius: 8px;
            margin-bottom: 20px;
            color: #ff8a80;
        }
    </style>
</head>
<body>
    <div class="login-container">
        <svg class="logo" viewBox="0 0 48 48" fill="none">
            <path d="M24 4L8 12v12c0 11.1 6.84 21.48 16 24 9.16-2.52 16-12.9 16-24V12L24 4z" fill="#FF5722"/>
            <path d="M24 4L8 12v12c0 11.1 6.84 21.48 16 24V4z" fill="#E64A19"/>
        </svg>
        <h1>WireGuard TV</h1>
        <p class="subtitle">Passwort erforderlich</p>
        ${if (errorMessage != null) "<div class=\"error-message\">$errorMessage</div>" else ""}
        <form method="POST" action="/login">
            <div class="form-group">
                <input type="password" name="password" placeholder="Passwort eingeben" autofocus required>
            </div>
            <button type="submit" class="submit-btn">Anmelden</button>
        </form>
    </div>
</body>
</html>
        """.trimIndent()

        output.print("HTTP/1.1 200 OK\r\n")
        output.print("Content-Type: text/html; charset=utf-8\r\n")
        output.print("Content-Length: ${html.toByteArray(Charsets.UTF_8).size}\r\n")
        output.print("Connection: close\r\n")
        output.print("\r\n")
        output.print(html)
        output.flush()
    }

    private fun handleGetTunnels(output: PrintWriter) {
        // WICHTIG: Synchron ausführen, sonst wird Connection geschlossen bevor Response gesendet
        runBlocking {
            try {
                val repository = TunnelRepository.getInstance(context)
                val settingsRepository = SettingsRepository.getInstance(context)
                val tunnels = repository.getTunnels()
                val activeTunnelId = repository.getActiveTunnelId()
                val settings = settingsRepository.getSettings()

                val tunnelsJson = tunnels.joinToString(",") { tunnel ->
                    val isActive = tunnel.id == activeTunnelId
                    val isAutostart = settings.autoConnectOnBoot && settings.defaultTunnelId == tunnel.id
                    val endpoint = tunnel.peers.firstOrNull()?.endpoint ?: "N/A"
                    """{"id":"${tunnel.id}","name":"${escapeJson(tunnel.name)}","endpoint":"${escapeJson(endpoint)}","active":$isActive,"autostart":$isAutostart}"""
                }

                sendJson(output, """{"tunnels":[$tunnelsJson],"activeTunnelId":${if (activeTunnelId != null) "\"$activeTunnelId\"" else "null"}}""")
            } catch (e: Exception) {
                Log.e(TAG, "handleGetTunnels error: ${e.message}", e)
                sendJson(output, """{"error":"${escapeJson(e.message ?: "Unknown error")}"}""")
            }
        }
    }

    private fun escapeJson(text: String): String {
        return text.replace("\\", "\\\\")
            .replace("\"", "\\\"")
            .replace("\n", "\\n")
            .replace("\r", "\\r")
            .replace("\t", "\\t")
    }

    private fun handleDeleteTunnel(output: PrintWriter, tunnelId: String) {
        runBlocking {
            try {
                val repository = TunnelRepository.getInstance(context)
                val settingsRepository = SettingsRepository.getInstance(context)

                // Prüfen ob Tunnel aktiv ist - direkt über Intent trennen
                if (repository.getActiveTunnelId() == tunnelId) {
                    val intent = Intent(context, WireGuardTunnelService::class.java).apply {
                        action = WireGuardTunnelService.ACTION_DISCONNECT
                    }
                    context.startService(intent)
                    onDisconnectTunnel?.invoke()
                }

                // Autostart entfernen falls dieser Tunnel als Autostart konfiguriert war
                val settings = settingsRepository.getSettings()
                if (settings.defaultTunnelId == tunnelId) {
                    settingsRepository.updateSettings(settings.copy(
                        autoConnectOnBoot = false,
                        defaultTunnelId = null
                    ))
                }

                repository.deleteTunnel(tunnelId)
                sendJson(output, """{"success":true,"message":"Tunnel gelöscht"}""")
                Log.i(TAG, "Tunnel gelöscht: $tunnelId")
            } catch (e: Exception) {
                sendJson(output, """{"success":false,"error":"${escapeJson(e.message ?: "Unknown error")}"}""")
            }
        }
    }

    private fun handleConnectTunnel(output: PrintWriter, tunnelId: String) {
        try {
            // VPN Service direkt über Intent starten (funktioniert auch ohne laufende App)
            val intent = Intent(context, WireGuardTunnelService::class.java).apply {
                action = WireGuardTunnelService.ACTION_CONNECT
                putExtra(WireGuardTunnelService.EXTRA_TUNNEL_ID, tunnelId)
            }
            context.startForegroundService(intent)

            // Auch Callback aufrufen falls gesetzt (für UI-Updates)
            onConnectTunnel?.invoke(tunnelId)

            sendJson(output, """{"success":true,"message":"Verbindung wird aufgebaut..."}""")
            Log.i(TAG, "Connect request: $tunnelId")
        } catch (e: Exception) {
            sendJson(output, """{"success":false,"error":"${e.message}"}""")
        }
    }

    private fun handleDisconnectTunnel(output: PrintWriter) {
        try {
            // VPN Service direkt über Intent stoppen (funktioniert auch ohne laufende App)
            val intent = Intent(context, WireGuardTunnelService::class.java).apply {
                action = WireGuardTunnelService.ACTION_DISCONNECT
            }
            context.startService(intent)

            // Auch Callback aufrufen falls gesetzt (für UI-Updates)
            onDisconnectTunnel?.invoke()

            sendJson(output, """{"success":true,"message":"Verbindung wird getrennt..."}""")
            Log.i(TAG, "Disconnect request")
        } catch (e: Exception) {
            sendJson(output, """{"success":false,"error":"${escapeJson(e.message ?: "Unknown error")}"}""")
        }
    }

    private fun handleGetTunnelForEdit(output: PrintWriter, tunnelId: String) {
        runBlocking {
            try {
                val repository = TunnelRepository.getInstance(context)
                val tunnel = repository.getTunnel(tunnelId)
                if (tunnel != null) {
                    val confString = tunnel.toConfString()
                    sendJson(output, """{"success":true,"tunnel":{"id":"${tunnel.id}","name":"${escapeJson(tunnel.name)}","config":"${escapeJson(confString)}"}}""")
                } else {
                    sendJson(output, """{"success":false,"error":"Tunnel nicht gefunden"}""")
                }
            } catch (e: Exception) {
                sendJson(output, """{"success":false,"error":"${escapeJson(e.message ?: "Unknown error")}"}""")
            }
        }
    }

    private fun handleUpdateTunnel(input: BufferedReader, output: PrintWriter, headers: Map<String, String>, tunnelId: String) {
        runBlocking {
            try {
                val contentLength = headers["content-length"]?.toIntOrNull() ?: 0
                val contentType = headers["content-type"] ?: ""

                if (contentLength == 0) {
                    sendJson(output, """{"success":false,"error":"Keine Daten empfangen"}""")
                    return@runBlocking
                }

                val body = CharArray(contentLength)
                var totalRead = 0
                while (totalRead < contentLength) {
                    val read = input.read(body, totalRead, contentLength - totalRead)
                    if (read == -1) break
                    totalRead += read
                }
                val bodyString = String(body, 0, totalRead)

                var configName = ""
                var configContent = ""

                if (contentType.contains("multipart/form-data")) {
                    val boundary = contentType.substringAfter("boundary=").trim()
                    val parts = bodyString.split("--$boundary")
                    for (part in parts) {
                        if (part.contains("name=\"configName\"")) {
                            configName = part.substringAfter("\r\n\r\n").trim().substringBefore("\r\n")
                        } else if (part.contains("name=\"configContent\"")) {
                            configContent = part.substringAfter("\r\n\r\n").trim()
                            if (configContent.endsWith("\r\n")) {
                                configContent = configContent.dropLast(2)
                            }
                        }
                    }
                } else if (contentType.contains("application/x-www-form-urlencoded")) {
                    val params = bodyString.split("&").associate {
                        val (key, value) = it.split("=", limit = 2)
                        URLDecoder.decode(key, "UTF-8") to URLDecoder.decode(value, "UTF-8")
                    }
                    configName = params["configName"] ?: ""
                    configContent = params["configContent"] ?: ""
                }

                if (configName.isBlank() || configContent.isBlank()) {
                    sendJson(output, """{"success":false,"error":"Name und Config erforderlich"}""")
                    return@runBlocking
                }

                // Config validieren
                if (!configContent.contains("[Interface]") || !configContent.contains("[Peer]")) {
                    sendJson(output, """{"success":false,"error":"Ungültige WireGuard Config"}""")
                    return@runBlocking
                }

                val repository = TunnelRepository.getInstance(context)

                // Bestehenden Tunnel löschen und neu erstellen mit gleicher ID
                val existingTunnel = repository.getTunnel(tunnelId)
                if (existingTunnel == null) {
                    sendJson(output, """{"success":false,"error":"Tunnel nicht gefunden"}""")
                    return@runBlocking
                }

                // Neuen Tunnel aus Config parsen
                val newTunnel = TunnelConfig.fromConfString(configContent, configName)
                // ID beibehalten
                val updatedTunnel = newTunnel.copy(id = tunnelId)

                repository.deleteTunnel(tunnelId)
                repository.addTunnel(updatedTunnel)

                sendJson(output, """{"success":true,"message":"Tunnel aktualisiert"}""")
                Log.i(TAG, "Tunnel aktualisiert: $tunnelId -> $configName")
            } catch (e: Exception) {
                Log.e(TAG, "Update error: ${e.message}", e)
                sendJson(output, """{"success":false,"error":"${escapeJson(e.message ?: "Unknown error")}"}""")
            }
        }
    }

    private fun handleToggleAutostart(input: BufferedReader, output: PrintWriter, headers: Map<String, String>, tunnelId: String) {
        runBlocking {
            try {
                val contentLength = headers["content-length"]?.toIntOrNull() ?: 0
                val contentType = headers["content-type"] ?: ""
                var enableAutostart = true

                if (contentLength > 0) {
                    val body = CharArray(contentLength)
                    var totalRead = 0
                    while (totalRead < contentLength) {
                        val read = input.read(body, totalRead, contentLength - totalRead)
                        if (read == -1) break
                        totalRead += read
                    }
                    val bodyString = String(body, 0, totalRead)
                    Log.d(TAG, "handleToggleAutostart body: $bodyString")

                    // Parse enable parameter - unterstützt verschiedene Formate
                    if (contentType.contains("multipart/form-data")) {
                        // Multipart: suche nach name="enable" und dann den Wert
                        val boundary = contentType.substringAfter("boundary=").trim()
                        val parts = bodyString.split("--$boundary")
                        for (part in parts) {
                            if (part.contains("name=\"enable\"")) {
                                val value = part.substringAfter("\r\n\r\n").trim().substringBefore("\r\n").trim()
                                Log.d(TAG, "Parsed enable value from multipart: '$value'")
                                enableAutostart = value == "true"
                            }
                        }
                    } else if (bodyString.contains("enable=false") || bodyString.contains("\"enable\":false")) {
                        enableAutostart = false
                    } else if (bodyString.contains("enable=true") || bodyString.contains("\"enable\":true")) {
                        enableAutostart = true
                    }
                }

                Log.d(TAG, "handleToggleAutostart: tunnelId=$tunnelId, enableAutostart=$enableAutostart")

                val settingsRepository = SettingsRepository.getInstance(context)
                val currentSettings = settingsRepository.getSettings()

                val newSettings = if (enableAutostart) {
                    currentSettings.copy(
                        autoConnectOnBoot = true,
                        defaultTunnelId = tunnelId
                    )
                } else {
                    currentSettings.copy(
                        autoConnectOnBoot = false,
                        defaultTunnelId = null
                    )
                }

                settingsRepository.updateSettings(newSettings)

                // Bei Aktivierung auch gleich verbinden - direkt über Intent
                if (enableAutostart) {
                    val intent = Intent(context, WireGuardTunnelService::class.java).apply {
                        action = WireGuardTunnelService.ACTION_CONNECT
                        putExtra(WireGuardTunnelService.EXTRA_TUNNEL_ID, tunnelId)
                    }
                    context.startForegroundService(intent)
                    onConnectTunnel?.invoke(tunnelId)
                }

                sendJson(output, """{"success":true,"autostart":$enableAutostart,"message":"${if (enableAutostart) "Autostart aktiviert" else "Autostart deaktiviert"}"}""")
                Log.i(TAG, "Autostart ${if (enableAutostart) "aktiviert" else "deaktiviert"} für Tunnel: $tunnelId")
            } catch (e: Exception) {
                sendJson(output, """{"success":false,"error":"${escapeJson(e.message ?: "Unknown error")}"}""")
            }
        }
    }

    private fun handleGetSettings(output: PrintWriter) {
        runBlocking {
            try {
                val settingsRepository = SettingsRepository.getInstance(context)
                val settings = settingsRepository.getSettings()

                // Passwort im Klartext zurückgeben (Verbindung ist eh lokal im LAN)
                sendJson(output, """{
                    "success":true,
                    "settings":{
                        "webServerPort":${settings.webServerPort},
                        "webServerPasswordEnabled":${settings.webServerPasswordEnabled},
                        "webServerPassword":"${escapeJson(settings.webServerPassword)}",
                        "webServerAutoStart":${settings.webServerAutoStart},
                        "autoConnectOnBoot":${settings.autoConnectOnBoot},
                        "defaultTunnelId":${if (settings.defaultTunnelId != null) "\"${settings.defaultTunnelId}\"" else "null"}
                    }
                }""".replace("\n", "").replace("  ", ""))
            } catch (e: Exception) {
                sendJson(output, """{"success":false,"error":"${escapeJson(e.message ?: "Unknown error")}"}""")
            }
        }
    }

    private fun handleUpdateSettings(input: BufferedReader, output: PrintWriter, headers: Map<String, String>) {
        runBlocking {
            try {
                val contentLength = headers["content-length"]?.toIntOrNull() ?: 0
                if (contentLength == 0) {
                    sendJson(output, """{"success":false,"error":"Keine Daten empfangen"}""")
                    return@runBlocking
                }

                val body = CharArray(contentLength)
                var totalRead = 0
                while (totalRead < contentLength) {
                    val read = input.read(body, totalRead, contentLength - totalRead)
                    if (read == -1) break
                    totalRead += read
                }
                val bodyString = String(body, 0, totalRead)

                // Form-Daten parsen
                val params = bodyString.split("&").associate {
                    val parts = it.split("=", limit = 2)
                    val key = URLDecoder.decode(parts.getOrElse(0) { "" }, "UTF-8")
                    val value = URLDecoder.decode(parts.getOrElse(1) { "" }, "UTF-8")
                    key to value
                }

                val newPort = params["port"]?.toIntOrNull()?.coerceIn(1, 65535)
                val passwordEnabled = params["passwordEnabled"] == "true" || params["passwordEnabled"] == "on"
                val newPassword = params["password"] ?: ""
                val autoStart = params["autoStart"] == "true" || params["autoStart"] == "on"

                // Validierung
                if (passwordEnabled && newPassword.isEmpty()) {
                    sendJson(output, """{"success":false,"error":"Passwort erforderlich wenn aktiviert"}""")
                    return@runBlocking
                }

                val settingsRepository = SettingsRepository.getInstance(context)
                val currentSettings = settingsRepository.getSettings()

                // Nur die WebServer-relevanten Settings aktualisieren
                val updatedSettings = currentSettings.copy(
                    webServerPort = newPort ?: currentSettings.webServerPort,
                    webServerPasswordEnabled = passwordEnabled,
                    webServerPassword = if (passwordEnabled && newPassword != "********") newPassword else currentSettings.webServerPassword,
                    webServerAutoStart = autoStart
                )

                settingsRepository.updateSettings(updatedSettings)

                // Server-Konfiguration aktualisieren
                updateConfig(
                    updatedSettings.webServerPort,
                    updatedSettings.webServerPasswordEnabled,
                    updatedSettings.webServerPassword
                )

                sendJson(output, """{"success":true,"message":"Einstellungen gespeichert. Server wird neu gestartet...","needsRestart":true}""")
                Log.i(TAG, "Settings aktualisiert: port=${updatedSettings.webServerPort}, passwordEnabled=$passwordEnabled, autoStart=$autoStart")

                // Callback für Neustart
                onSettingsChanged?.invoke()
            } catch (e: Exception) {
                Log.e(TAG, "Settings update error: ${e.message}", e)
                sendJson(output, """{"success":false,"error":"${escapeJson(e.message ?: "Unknown error")}"}""")
            }
        }
    }

    private fun handleGetGeoInfo(output: PrintWriter) {
        runBlocking {
            try {
                val repository = TunnelRepository.getInstance(context)
                val activeTunnelId = repository.getActiveTunnelId()
                val isConnected = activeTunnelId != null

                // IP-Geo-Info abrufen
                val ipInfo = IpGeoService.getPublicIpInfo()

                if (ipInfo != null) {
                    sendJson(output, """{
                        "success":true,
                        "connected":$isConnected,
                        "ip":"${escapeJson(ipInfo.ip)}",
                        "countryCode":"${escapeJson(ipInfo.countryCode)}",
                        "countryName":"${escapeJson(ipInfo.countryName)}",
                        "city":${if (ipInfo.city != null) "\"${escapeJson(ipInfo.city)}\"" else "null"},
                        "flag":"${ipInfo.flag}"
                    }""".replace("\n", "").replace("  ", ""))
                } else {
                    sendJson(output, """{"success":false,"error":"Geo-Info konnte nicht abgerufen werden","connected":$isConnected}""")
                }
            } catch (e: Exception) {
                Log.e(TAG, "handleGetGeoInfo error: ${e.message}", e)
                sendJson(output, """{"success":false,"error":"${escapeJson(e.message ?: "Unknown error")}"}""")
            }
        }
    }
}
