<?php
declare(strict_types=1);

// =============================================================
// EKL Installer
// - DB-Verbindung testen
// - Optional: Datenbank erstellen
// - Tabellen anlegen (schema.sql)
// - Bis zu 5 Nutzer anlegen (Passwörter werden erzeugt)
// - Passwörter als Argon2id speichern
// - Zugangsdaten per E-Mail verschicken
// - .env schreiben + install.lock setzen
// =============================================================

function h(string $v): string { return htmlspecialchars($v, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }

function hasArgon2id(): bool
{
    return defined('PASSWORD_ARGON2ID');
}

function generatePassword(int $len = 16): string
{
    // bewusst ohne leicht verwechselbare Zeichen
    $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%&*?';
    $max = strlen($chars) - 1;
    $out = '';
    for ($i = 0; $i < $len; $i++) {
        $out .= $chars[random_int(0, $max)];
    }
    return $out;
}

function detectBaseUrl(): string
{
    $https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
    $scheme = $https ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
    $script = $_SERVER['SCRIPT_NAME'] ?? '';
    // /install/index.php -> App-Root
    $root = rtrim(str_replace('/install/index.php', '', $script), '/');
    return $scheme . '://' . $host . $root;
}

function splitSqlStatements(string $sql): array
{
    // Block-Kommentare entfernen
    $sql = preg_replace('~/\*.*?\*/~s', '', $sql) ?? $sql;
    // Zeilen-Kommentare entfernen
    $lines = preg_split('~\R~u', $sql) ?: [];
    $clean = [];
    foreach ($lines as $line) {
        $t = trim($line);
        if ($t === '' || strpos($t, '--') === 0 || strpos($t, '#') === 0) {
            continue;
        }
        $clean[] = $line;
    }
    $sql = implode("\n", $clean);

    // sehr einfacher Split (Schema ist bewusst simpel)
    $parts = array_map('trim', explode(';', $sql));
    $stmts = [];
    foreach ($parts as $p) {
        if ($p !== '') {
            $stmts[] = $p;
        }
    }
    return $stmts;
}

function ensureWritableOrExplain(string $path): array
{
    // Gibt [ok(bool), msg]
    if (file_exists($path)) {
        if (is_writable($path)) return [true, 'Datei ist schreibbar.'];
        return [false, 'Datei ist vorhanden, aber nicht schreibbar. Rechte prüfen.'];
    }
    $dir = dirname($path);
    if (!is_dir($dir)) {
        return [false, 'Verzeichnis existiert nicht: ' . $dir];
    }
    if (!is_writable($dir)) {
        return [false, 'Verzeichnis ist nicht schreibbar: ' . $dir];
    }
    return [true, 'Verzeichnis ist schreibbar, Datei kann erstellt werden.'];
}

function sendCredentialsMailHtml(
    string $to,
    string $subject,
    string $htmlBody,
    string $plainBody,
    string $fromEmail,
    string $fromName = ''
): array {
    // Gibt [ok(bool), msg]
    $from = $fromEmail;
    if ($fromName !== '') {
        // Minimaler Header-Schutz
        $safeName = trim(str_replace(["\r", "\n"], '', $fromName));
        $from = '"' . addslashes($safeName) . '" <' . $fromEmail . '>';
    }

    $boundary = 'bnd_' . bin2hex(random_bytes(12));

    $headers = [];
    $headers[] = 'MIME-Version: 1.0';
    $headers[] = 'From: ' . $from;
    $headers[] = 'Content-Type: multipart/alternative; boundary="' . $boundary . '"';

    $body  = "--{$boundary}\r\n";
    $body .= "Content-Type: text/plain; charset=UTF-8\r\n";
    $body .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
    $body .= $plainBody . "\r\n\r\n";

    $body .= "--{$boundary}\r\n";
    $body .= "Content-Type: text/html; charset=UTF-8\r\n";
    $body .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
    $body .= $htmlBody . "\r\n\r\n";
    $body .= "--{$boundary}--\r\n";

    $ok = @mail($to, $subject, $body, implode("\r\n", $headers));
    if ($ok) return [true, 'E-Mail wurde versendet (HTML).'];
    return [false, 'mail() hat false zurückgegeben. Hosting-Mail-Funktion prüfen.'];
}

$lockFile = __DIR__ . '/install.lock';
$schemaFile = __DIR__ . '/schema.sql';
$envFile = dirname(__DIR__) . '/.env';

// Wenn installiert: nur Info anzeigen.
if (file_exists($lockFile)) {
    $base = detectBaseUrl();
    ?>
    <!doctype html>
    <html lang="de">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>EKL Setup</title>
        <style>
            :root{--bg:#0b1220;--card:#111827;--muted:#94a3b8;--text:#e5e7eb;--line:#243041;--ok:#22c55e;--bad:#ef4444;--btn:#2563eb;}
            body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;background:var(--bg);color:var(--text);}
            .wrap{max-width:900px;margin:0 auto;padding:24px;}
            .card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:20px;box-shadow:0 16px 40px rgba(0,0,0,.35);}
            h1{margin:0 0 8px 0;letter-spacing:.08em;font-size:20px;}
            p{color:var(--muted);line-height:1.45;margin:10px 0;}
            a{color:#93c5fd;text-decoration:none;}
            .badge{display:inline-flex;align-items:center;gap:8px;margin-top:12px;padding:10px 12px;border-radius:12px;background:rgba(34,197,94,.08);border:1px solid rgba(34,197,94,.25);}
            .dot{width:10px;height:10px;border-radius:99px;background:var(--ok);}
            .btn{display:inline-block;margin-top:14px;background:var(--btn);color:white;padding:10px 14px;border-radius:10px;}
        </style>
    </head>
    <body>
        <div class="wrap">
            <div class="card">
                <h1>EKL Setup</h1>
                <div class="badge"><span class="dot"></span><strong>Installiert</strong></div>
                <p>Die Installation ist bereits abgeschlossen. Aus Sicherheitsgründen solltest du den Ordner <code>/install</code> löschen oder zumindest auf dem Server sperren.</p>
                <a class="btn" href="<?= h($base) ?>/login.php">Zur Anmeldung</a>
            </div>
        </div>
    </body>
    </html>
    <?php
    exit;
}

$defaultBaseUrl = detectBaseUrl();

// Form-Werte (für Re-Render bei Fehlern)
$in = [
    'db_host' => 'localhost',
    'db_port' => '',
    'db_name' => '',
    'db_user' => '',
    'db_pass' => '',
    'create_db' => '0',
    'base_url' => $defaultBaseUrl,
    'mail_from' => '',
    'mail_from_name' => 'EKL',
    'users' => [],
];

// Default 1 User-Zeile
$in['users'][] = ['username'=>'', 'email'=>'', 'first_name'=>'', 'last_name'=>'', 'text_color'=>'#3b82f6'];

$steps = []; // ['label'=>, 'ok'=>, 'detail'=>]
$createdUsers = []; // pro user: ['username','email','password','mail_ok','mail_msg']
$fatalError = '';

// Für Anzeige (wird nach POST überschrieben)
$loginUrl = $defaultBaseUrl . '/login.php';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Inputs einsammeln
    $in['db_host'] = trim((string)($_POST['db_host'] ?? 'localhost'));
    $in['db_port'] = trim((string)($_POST['db_port'] ?? ''));
    $in['db_name'] = trim((string)($_POST['db_name'] ?? ''));
    $in['db_user'] = trim((string)($_POST['db_user'] ?? ''));
    $in['db_pass'] = (string)($_POST['db_pass'] ?? '');
    $in['create_db'] = (string)($_POST['create_db'] ?? '0');
    $in['base_url'] = rtrim(trim((string)($_POST['base_url'] ?? $defaultBaseUrl)), '/');

    // Anzeige-Link sofort setzen (auch wenn Setup später abbricht)
    $loginUrl = $in['base_url'] . '/login.php';
    $in['mail_from'] = trim((string)($_POST['mail_from'] ?? ''));
    $in['mail_from_name'] = trim((string)($_POST['mail_from_name'] ?? 'EKL'));
    $inUsers = $_POST['users'] ?? [];

    // Nutzer normalisieren (max 5)
    $users = [];
    if (is_array($inUsers)) {
        $i = 0;
        foreach ($inUsers as $row) {
            if ($i >= 5) break;
            $u = [
                'username' => trim((string)($row['username'] ?? '')),
                'email' => trim((string)($row['email'] ?? '')),
                'first_name' => trim((string)($row['first_name'] ?? '')),
                'last_name' => trim((string)($row['last_name'] ?? '')),
                'text_color' => trim((string)($row['text_color'] ?? '#3b82f6')),
            ];
            // Leere Zeilen ignorieren
            if ($u['username'] === '' && $u['email'] === '' && $u['first_name'] === '' && $u['last_name'] === '') {
                $i++;
                continue;
            }
            $users[] = $u;
            $i++;
        }
    }
    $in['users'] = $users;

    // =========================================================
    // Vorchecks
    // =========================================================
    if (!hasArgon2id()) {
        $fatalError = 'PASSWORD_ARGON2ID ist auf diesem Server nicht verfügbar. Ohne Argon2id darf das Setup nicht fortfahren.';
    }
    if ($fatalError === '' && $in['db_host'] === '') $fatalError = 'DB Host fehlt.';
    if ($fatalError === '' && $in['db_name'] === '') $fatalError = 'DB Name fehlt.';
    if ($fatalError === '' && $in['db_user'] === '') $fatalError = 'DB User fehlt.';
    if ($fatalError === '' && count($users) < 1) $fatalError = 'Mindestens ein Nutzer muss angelegt werden.';
    if ($fatalError === '' && $in['mail_from'] === '') $fatalError = 'Absender-E-Mail (From) fehlt. Ohne From ist Mailversand in vielen Hostings blockiert.';

    // Duplicate Username/Email im Formular
    if ($fatalError === '') {
        $seenU = [];
        $seenE = [];
        foreach ($users as $u) {
            if ($u['username'] === '' || $u['email'] === '' || $u['first_name'] === '' || $u['last_name'] === '') {
                $fatalError = 'Bei jedem Nutzer müssen Username, E-Mail, Vorname und Nachname gesetzt sein.';
                break;
            }
            $lu = mb_strtolower($u['username']);
            $le = mb_strtolower($u['email']);
            if (isset($seenU[$lu])) { $fatalError = 'Username doppelt im Setup: ' . $u['username']; break; }
            if (isset($seenE[$le])) { $fatalError = 'E-Mail doppelt im Setup: ' . $u['email']; break; }
            $seenU[$lu] = true;
            $seenE[$le] = true;
        }
    }

    // .env schreibbar?
    if ($fatalError === '') {
        [$okEnv, $envMsg] = ensureWritableOrExplain($envFile);
        $steps[] = ['label' => '.env Schreibrechte prüfen', 'ok' => $okEnv, 'detail' => $envMsg];
        if (!$okEnv) {
            $fatalError = 'Ohne Schreibrechte kann das Setup keine Konfiguration speichern.';
        }
    }

    // =========================================================
    // DB Schritte
    // =========================================================
    $pdo = null;
    if ($fatalError === '') {
        try {
            $portPart = ($in['db_port'] !== '') ? ';port=' . $in['db_port'] : '';
            // 1) Verbindung ohne DB (für CREATE DATABASE)
            $dsnNoDb = 'mysql:host=' . $in['db_host'] . $portPart . ';charset=utf8mb4';
            $pdoNoDb = new PDO($dsnNoDb, $in['db_user'], $in['db_pass'], [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            ]);
            $steps[] = ['label' => 'DB Verbindung testen', 'ok' => true, 'detail' => 'PDO Verbindung erfolgreich.'];

            if ($in['create_db'] === '1') {
                $db = str_replace('`', '', $in['db_name']);
                $pdoNoDb->exec("CREATE DATABASE IF NOT EXISTS `{$db}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
                $steps[] = ['label' => 'Datenbank erstellen', 'ok' => true, 'detail' => 'Datenbank ist vorhanden oder wurde erstellt.'];
            } else {
                $steps[] = ['label' => 'Datenbank erstellen', 'ok' => true, 'detail' => 'Übersprungen (Datenbank existiert bereits).'];
            }

            // 2) Verbindung mit DB
            $dsn = 'mysql:host=' . $in['db_host'] . $portPart . ';dbname=' . $in['db_name'] . ';charset=utf8mb4';
            $pdo = new PDO($dsn, $in['db_user'], $in['db_pass'], [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            ]);
            $steps[] = ['label' => 'DB Verbindung zur Zieldatenbank', 'ok' => true, 'detail' => 'Verbunden mit DB: ' . $in['db_name']];
        } catch (Throwable $e) {
            $steps[] = ['label' => 'DB Verbindung', 'ok' => false, 'detail' => $e->getMessage()];
            $fatalError = 'Keine DB Verbindung möglich. Zugangsdaten und Rechte prüfen.';
        }
    }

    // Tabellen anlegen
    if ($fatalError === '' && $pdo) {
        try {
            if (!file_exists($schemaFile)) {
                throw new RuntimeException('schema.sql fehlt im /install Ordner.');
            }
            $sql = file_get_contents($schemaFile);
            if ($sql === false) {
                throw new RuntimeException('schema.sql konnte nicht gelesen werden.');
            }
            $stmts = splitSqlStatements($sql);
            foreach ($stmts as $s) {
                $pdo->exec($s);
            }
            $steps[] = ['label' => 'Tabellen anlegen', 'ok' => true, 'detail' => 'Schema wurde ausgeführt.'];
        } catch (Throwable $e) {
            $steps[] = ['label' => 'Tabellen anlegen', 'ok' => false, 'detail' => $e->getMessage()];
            $fatalError = 'Schema konnte nicht installiert werden.';
        }
    }

    // Nutzer anlegen
    if ($fatalError === '' && $pdo) {
        try {
            // Nur wenn Tabelle leer ist, damit Setup nicht doppelt schreibt
            $count = (int)$pdo->query('SELECT COUNT(*) FROM users')->fetchColumn();
            if ($count > 0) {
                $steps[] = ['label' => 'Nutzer anlegen', 'ok' => false, 'detail' => 'In der Tabelle users sind bereits Einträge vorhanden. Setup bricht hier ab, um Duplikate zu vermeiden.'];
                $fatalError = 'Users existieren bereits.';
            } else {
                $stmt = $pdo->prepare('INSERT INTO users (username,email,first_name,last_name,password,text_color) VALUES (:u,:e,:fn,:ln,:pw,:c)');
                foreach ($users as $u) {
                    $plain = generatePassword(16);
                    $hash = password_hash($plain, PASSWORD_ARGON2ID);
                    if (!is_string($hash) || $hash === '') {
                        throw new RuntimeException('password_hash(PASSWORD_ARGON2ID) fehlgeschlagen.');
                    }
                    $stmt->execute([
                        ':u' => $u['username'],
                        ':e' => $u['email'],
                        ':fn' => $u['first_name'],
                        ':ln' => $u['last_name'],
                        ':pw' => $hash,
                        ':c' => ($u['text_color'] !== '' ? $u['text_color'] : null),
                    ]);
                    $createdUsers[] = [
                        'username' => $u['username'],
                        'email' => $u['email'],
                        'first_name' => $u['first_name'],
                        'last_name' => $u['last_name'],
                        'password' => $plain,
                        'mail_ok' => false,
                        'mail_msg' => 'nicht gesendet',
                    ];
                }
                $steps[] = ['label' => 'Nutzer anlegen', 'ok' => true, 'detail' => count($createdUsers) . ' Nutzer wurden angelegt.'];
            }
        } catch (Throwable $e) {
            $steps[] = ['label' => 'Nutzer anlegen', 'ok' => false, 'detail' => $e->getMessage()];
            $fatalError = 'Nutzer konnten nicht angelegt werden.';
        }
    }

    // E-Mails versenden
    // E-Mails versenden
if ($fatalError === '' && $pdo) {
    try {
        $loginUrl = $in['base_url'] . '/login.php';

        foreach ($createdUsers as $idx => $cu) {
            $subject = 'EKL Zugangsdaten';

            // Plaintext Fallback
            $plainBody =
                "Hallo {$cu['first_name']},\n\n" .
                "dein EKL-Account wurde angelegt.\n\n" .
                "Benutzername: {$cu['username']}\n" .
                "Passwort: {$cu['password']}\n\n" .
                "Login: {$loginUrl}\n\n" .
                "Bitte ändere dein Passwort nach dem ersten Login.\n\n" .
                "© 2025, 2026 MiLe-Dev.com\n" .
                "https://mile-dev.com\n";

            // HTML Body (Email-safe Inline Styles)
            $safeFirst = h((string)$cu['first_name']);
            $safeUser  = h((string)$cu['username']);
            $safePass  = h((string)$cu['password']);
            $safeLogin = h((string)$loginUrl);

            $htmlBody = '
<!doctype html>
<html lang="de">
<head><meta charset="utf-8"></head>
<body style="margin:0;padding:0;background:#f3f4f6;">
  <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="background:#f3f4f6;">
    <tr>
      <td align="center" style="padding:24px;">
        <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="max-width:640px;background:#ffffff;border:1px solid #e5e7eb;border-radius:12px;overflow:hidden;">
          <tr>
            <td style="padding:20px 22px;border-bottom:1px solid #e5e7eb;">
              <div style="font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;font-size:18px;font-weight:700;color:#0b5cff;">
                EKL Zugangsdaten
              </div>
              <div style="font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;font-size:13px;color:#6b7280;margin-top:6px;">
                Dein Account wurde erfolgreich angelegt.
              </div>
            </td>
          </tr>

          <tr>
            <td style="padding:20px 22px;">
              <div style="font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;font-size:14px;color:#111827;line-height:1.55;">
                Hallo <strong>' . $safeFirst . '</strong>,<br><br>
                hier sind deine Zugangsdaten:
              </div>

              <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="margin-top:14px;border:1px solid #e5e7eb;border-radius:10px;">
                <tr>
                  <td style="padding:12px 14px;background:#f9fafb;border-bottom:1px solid #e5e7eb;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;font-size:12px;color:#6b7280;">
                    Zugangsdaten
                  </td>
                </tr>
                <tr>
                  <td style="padding:14px;">
                    <div style="font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,\'Liberation Mono\',\'Courier New\',monospace;font-size:13px;color:#111827;line-height:1.65;">
                      <div><span style="color:#6b7280;">Benutzername:</span> ' . $safeUser . '</div>
                      <div><span style="color:#6b7280;">Passwort:</span> ' . $safePass . '</div>
                    </div>
                  </td>
                </tr>
              </table>

              <div style="margin-top:16px;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;font-size:14px;color:#111827;">
                Login:
              </div>

              <div style="margin-top:10px;">
                <a href="' . $safeLogin . '" style="display:inline-block;background:#0b5cff;color:#ffffff;text-decoration:none;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;font-size:14px;font-weight:700;padding:12px 16px;border-radius:8px;">
                  Zur Anmeldung
                </a>
              </div>

              <div style="margin-top:14px;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;font-size:12px;color:#6b7280;line-height:1.55;">
                Sicherheit: Bitte ändere dein Passwort nach dem ersten Login.
              </div>
            </td>
          </tr>

          <tr>
            <td style="padding:14px 22px;border-top:1px solid #e5e7eb;background:#f9fafb;">
              <div style="font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;font-size:12px;color:#6b7280;line-height:1.5;">
                © 2025, 2026
                <a href="https://mile-dev.com" style="color:#0b5cff;text-decoration:underline;">MiLe-Dev.com</a>
              </div>
            </td>
          </tr>
        </table>

        <div style="max-width:640px;margin-top:10px;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;font-size:11px;color:#9ca3af;line-height:1.4;">
          Wenn der Button nicht funktioniert, nutze diesen Link: <span style="word-break:break-all;">' . $safeLogin . '</span>
        </div>
      </td>
    </tr>
  </table>
</body>
</html>';

            [$ok, $msg] = sendCredentialsMailHtml(
                $cu['email'],
                $subject,
                $htmlBody,
                $plainBody,
                $in['mail_from'],
                $in['mail_from_name']
            );

            $createdUsers[$idx]['mail_ok'] = $ok;
            $createdUsers[$idx]['mail_msg'] = $msg;
        }

        $fails = array_filter($createdUsers, fn($u) => !$u['mail_ok']);
        if (count($fails) === 0) {
            $steps[] = ['label' => 'E-Mails versenden', 'ok' => true, 'detail' => 'Alle E-Mails wurden versendet.'];
        } else {
            $steps[] = ['label' => 'E-Mails versenden', 'ok' => false, 'detail' => count($fails) . ' E-Mail(s) konnten nicht gesendet werden. Zugangsdaten werden zusätzlich unten angezeigt.'];
        }
    } catch (Throwable $e) {
        $steps[] = ['label' => 'E-Mails versenden', 'ok' => false, 'detail' => $e->getMessage()];
    }
}

    // .env schreiben
    if ($fatalError === '' && $pdo) {
        try {
            $lines = [];
            $lines[] = 'DB_HOST=' . $in['db_host'];
            $lines[] = 'DB_PORT=' . $in['db_port'];
            $lines[] = 'DB_NAME=' . $in['db_name'];
            $lines[] = 'DB_USER=' . $in['db_user'];
            $lines[] = 'DB_PASS=' . $in['db_pass'];
            $lines[] = '';
            $lines[] = 'APP_ENV=prod';
            $lines[] = 'APP_DEBUG=0';
            $lines[] = '';
            $lines[] = 'BASE_URL=' . $in['base_url'];
            $lines[] = 'MAIL_FROM=' . $in['mail_from'];
            $lines[] = 'MAIL_FROM_NAME=' . $in['mail_from_name'];
            $content = implode("\n", $lines) . "\n";

            $ok = (file_put_contents($envFile, $content, LOCK_EX) !== false);
            if (!$ok) {
                throw new RuntimeException('.env konnte nicht geschrieben werden.');
            }
            $steps[] = ['label' => '.env schreiben', 'ok' => true, 'detail' => 'Konfiguration wurde gespeichert.'];
        } catch (Throwable $e) {
            $steps[] = ['label' => '.env schreiben', 'ok' => false, 'detail' => $e->getMessage()];
            $fatalError = 'Konfiguration konnte nicht gespeichert werden.';
        }
    }

    // Lock setzen
    if ($fatalError === '' && $pdo) {
        try {
            $ok = (file_put_contents($lockFile, "installed_at=" . date('c') . "\n", LOCK_EX) !== false);
            if (!$ok) {
                throw new RuntimeException('install.lock konnte nicht geschrieben werden.');
            }
            $steps[] = ['label' => 'Installation abschließen', 'ok' => true, 'detail' => 'install.lock wurde gesetzt.'];
        } catch (Throwable $e) {
            $steps[] = ['label' => 'Installation abschließen', 'ok' => false, 'detail' => $e->getMessage()];
            $fatalError = 'Installation konnte nicht abgeschlossen werden.';
        }
    }
}

$installedOk = (file_exists($lockFile) && $fatalError === '' && $_SERVER['REQUEST_METHOD'] === 'POST');
$loginUrl = rtrim($in['base_url'], '/') . '/login.php';
?>
<!doctype html>
<html lang="de">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>EKL Setup</title>
    <style>
        :root{--bg:#0b1220;--card:#111827;--muted:#94a3b8;--text:#e5e7eb;--line:#243041;--ok:#22c55e;--bad:#ef4444;--warn:#f59e0b;--btn:#2563eb;--input:#0f172a;}
        *{box-sizing:border-box}
        body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;background:var(--bg);color:var(--text);}
        .wrap{max-width:980px;margin:0 auto;padding:24px;}
        .top{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:16px;}
        .brand{display:flex;flex-direction:column;gap:6px;}
        h1{margin:0;letter-spacing:.10em;font-size:20px;}
        .sub{color:var(--muted);line-height:1.45;max-width:62ch;}
        .card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:18px;box-shadow:0 16px 40px rgba(0,0,0,.35);}
        .grid{display:grid;grid-template-columns:1fr;gap:14px;}
        @media (min-width:900px){.grid{grid-template-columns:1.05fr .95fr;}}
        label{display:block;font-size:12px;color:var(--muted);margin:0 0 6px 0;}
        input[type=text],input[type=password],input[type=email]{width:100%;padding:10px 11px;border-radius:10px;border:1px solid var(--line);background:var(--input);color:var(--text);}
        input[type=text]::placeholder,input[type=password]::placeholder{color:#64748b;}
        .row{display:grid;grid-template-columns:1fr;gap:10px;}
        @media (min-width:700px){.row.two{grid-template-columns:1fr 1fr;}.row.three{grid-template-columns:1fr 1fr 1fr;}.row.four{grid-template-columns:1fr 1fr 1fr 1fr;}}
        .hint{color:var(--muted);font-size:12px;line-height:1.45;margin-top:8px;}
        .section-title{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:10px;}
        .section-title h2{margin:0;font-size:14px;letter-spacing:.08em;}
        .pill{font-size:12px;color:#cbd5e1;background:rgba(148,163,184,.10);border:1px solid rgba(148,163,184,.18);padding:6px 10px;border-radius:999px;}
        .actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px;}
        .btn{appearance:none;border:0;background:var(--btn);color:white;padding:10px 14px;border-radius:10px;cursor:pointer;font-weight:600;}
        .btn.secondary{background:transparent;border:1px solid var(--line);color:var(--text);}
        .chk{display:flex;align-items:center;gap:10px;margin-top:10px;color:var(--muted);font-size:13px;}
        .chk input{width:16px;height:16px;}
        .steps{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:8px;}
        .step{display:flex;gap:10px;align-items:flex-start;padding:10px;border:1px solid var(--line);border-radius:12px;background:rgba(15,23,42,.35);}
        .icon{width:18px;height:18px;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;margin-top:1px;font-size:12px;font-weight:700;}
        .ok{background:rgba(34,197,94,.12);border:1px solid rgba(34,197,94,.35);color:var(--ok);}
        .bad{background:rgba(239,68,68,.12);border:1px solid rgba(239,68,68,.35);color:var(--bad);}
        .step b{display:block;font-size:13px;}
        .step small{display:block;color:var(--muted);line-height:1.35;margin-top:2px;word-break:break-word;}
        .alert{border-radius:12px;padding:12px;border:1px solid var(--line);background:rgba(239,68,68,.10);}
        .alert strong{color:#fecaca;}
        .okbox{border-radius:12px;padding:12px;border:1px solid rgba(34,197,94,.35);background:rgba(34,197,94,.10);}
        table{width:100%;border-collapse:separate;border-spacing:0;margin-top:10px;}
        th,td{padding:10px;border-bottom:1px solid var(--line);text-align:left;font-size:13px;vertical-align:top;}
        th{color:var(--muted);font-weight:600;}
        .mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;}
        .warn{color:#fcd34d;}
        .users-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:10px;}
        .smallbtn{appearance:none;border:1px solid var(--line);background:transparent;color:var(--text);padding:8px 10px;border-radius:10px;cursor:pointer;font-weight:600;font-size:12px;}
        .user-row{border:1px solid var(--line);border-radius:12px;padding:12px;background:rgba(15,23,42,.28);margin-bottom:10px;}
        .user-row .remove{float:right;}
        .color{padding:0;height:40px;}
        .footer-note{margin-top:14px;color:var(--muted);font-size:12px;line-height:1.45;}
        code{background:rgba(148,163,184,.10);border:1px solid rgba(148,163,184,.18);padding:2px 6px;border-radius:8px;}
    </style>
</head>
<body>
<div class="wrap">
    <div class="top">
        <div class="brand">
            <h1>EKL Setup</h1>
            <div class="sub">
                Dieses Setup macht drei Dinge: Es verbindet die Datenbank, legt die Tabellen an und erstellt die ersten Nutzer.
                Nach jedem Schritt siehst du sofort, was geklappt hat und warum etwas nicht klappt. Sollten sich die Nutzer ändern,
                Musst du diese danach direkt in der DB anlegen. 
                Gehe dazu in Dein SQL Verwaltungsprogramm und bearbeitet die "Table 'Users'. Bedenke das die Kennwörter per Agon2ID eingetragen werden müssen!
                Du kannst neue Passwörter direkt unter <a href="https://mile-dev.com/projekte/webanwendungen/webtools.html" target="_blank" rel="noopener">https://mile-dev.com/projekte/webanwendungen/webtools.html</a>
            </div>
        </div>
        <div class="pill">Installer. Version 1</div>
    </div>

    <div class="grid">
        <div class="card">
            <div class="section-title">
                <h2>1. Datenbank</h2>
                <span class="pill">PDO MySQL</span>
            </div>

            <?php if ($fatalError !== ''): ?>
                <div class="alert">
                    <strong>Abbruch:</strong> <?= h($fatalError) ?>
                    <div class="hint" style="margin-top:8px;">
                        Tipp: Prüfe Host, User, Passwort und ob dein Hosting externe DB-Verbindungen erlaubt.
                    </div>
                </div>
            <?php endif; ?>

            <?php if ($installedOk): ?>
                <div class="okbox">
                    <strong>Fertig.</strong> Installation ist abgeschlossen.
                    <div class="hint" style="margin-top:8px;">
                        Sicherheit: Lösche den Ordner <code>/install</code> oder sperre ihn per Server-Konfiguration.
                    </div>
                    <div class="actions">
                        <a class="btn" href="<?= h($loginUrl) ?>">Zur Anmeldung</a>
                    </div>
                </div>
            <?php endif; ?>

            <form method="post" autocomplete="off">
                <div class="row two" style="margin-top:14px;">
                    <div>
                        <label>DB Host</label>
                        <input type="text" name="db_host" value="<?= h($in['db_host']) ?>" placeholder="localhost" required>
                        <div class="hint">Beispiel: <code>localhost</code> oder eine Hosting-DB wie <code>db123.hosting.tld</code>.</div>
                    </div>
                    <div>
                        <label>DB Port (optional)</label>
                        <input type="text" name="db_port" value="<?= h($in['db_port']) ?>" placeholder="3306">
                        <div class="hint">Leer lassen, wenn du es nicht brauchst.</div>
                    </div>
                </div>

                <div class="row two" style="margin-top:10px;">
                    <div>
                        <label>DB Name</label>
                        <input type="text" name="db_name" value="<?= h($in['db_name']) ?>" placeholder="ekl" required>
                        <div class="hint">Die Datenbank, in der EKL die Tabellen erstellt.</div>
                    </div>
                    <div>
                        <label>DB User</label>
                        <input type="text" name="db_user" value="<?= h($in['db_user']) ?>" placeholder="dbuser" required>
                        <div class="hint">Der User muss CREATE TABLE dürfen.</div>
                    </div>
                </div>

                <div class="row" style="margin-top:10px;">
                    <div>
                        <label>DB Passwort</label>
                        <input type="password" name="db_pass" value="<?= h($in['db_pass']) ?>" placeholder="" required>
                        <div class="hint">Wird in <code>.env</code> gespeichert. Dateirechte sauber setzen.</div>
                    </div>
                </div>

                <div class="chk">
                    <input type="checkbox" id="create_db" name="create_db" value="1" <?= ($in['create_db']==='1'?'checked':'') ?>>
                    <label for="create_db" style="margin:0;">Datenbank automatisch anlegen (nur wenn dein DB-User das darf)</label>
                </div>

                <div class="section-title" style="margin-top:18px;">
                    <h2>2. Domain und Mail</h2>
                    <span class="pill">Zugangsdaten Versand</span>
                </div>

                <div class="row" style="margin-top:10px;">
                    <div>
                        <label>Base URL der Installation</label>
                        <input type="text" name="base_url" value="<?= h($in['base_url']) ?>" placeholder="<?= h($defaultBaseUrl) ?>" required>
                        <div class="hint">Wird für Links genutzt, z. B. in E-Mails. Ohne Slash am Ende.</div>
                    </div>
                </div>

                <div class="row two" style="margin-top:10px;">
                    <div>
                        <label>Absender E-Mail (From)</label>
                        <input type="email" name="mail_from" value="<?= h($in['mail_from']) ?>" placeholder="noreply@deine-domain.tld" required>
                        <div class="hint">Viele Hostings blocken sonst Mails. Nimm eine Adresse deiner Domain.</div>
                    </div>
                    <div>
                        <label>Absender Name (optional)</label>
                        <input type="text" name="mail_from_name" value="<?= h($in['mail_from_name']) ?>" placeholder="EKL">
                        <div class="hint">Wird im Mail-Header angezeigt.</div>
                    </div>
                </div>

                <div class="section-title" style="margin-top:18px;">
                    <h2>3. Erste Nutzer</h2>
                    <span class="pill">max. 5</span>
                </div>
                <div class="hint" style="margin-top:0;">
                    Passwörter werden automatisch erzeugt, als Argon2id gehasht gespeichert und per E-Mail versendet.
                    Wenn ein Mailversand scheitert, siehst du die Zugangsdaten unten trotzdem einmalig.
                </div>

                <div class="users-head">
                    <div class="hint" style="margin:0;">Lege 1 bis 5 Nutzer an. Leere Zeilen werden ignoriert.</div>
                    <div>
                        <button type="button" class="smallbtn" id="addUserBtn">Nutzer hinzufügen</button>
                    </div>
                </div>

                <div id="usersWrap">
                    <?php
                    $renderUsers = $in['users'];
                    if (!is_array($renderUsers) || count($renderUsers) === 0) {
                        $renderUsers = [['username'=>'','email'=>'','first_name'=>'','last_name'=>'','text_color'=>'#3b82f6']];
                    }
                    $idx = 0;
                    foreach ($renderUsers as $u):
                        $idxSafe = (int)$idx;
                    ?>
                        <div class="user-row" data-idx="<?= $idxSafe ?>">
                            <button type="button" class="smallbtn remove" onclick="removeUser(this)">Entfernen</button>
                            <div class="row four">
                                <div>
                                    <label>Username</label>
                                    <input type="text" name="users[<?= $idxSafe ?>][username]" value="<?= h((string)($u['username'] ?? '')) ?>" required>
                                </div>
                                <div>
                                    <label>E-Mail</label>
                                    <input type="email" name="users[<?= $idxSafe ?>][email]" value="<?= h((string)($u['email'] ?? '')) ?>" required>
                                </div>
                                <div>
                                    <label>Vorname</label>
                                    <input type="text" name="users[<?= $idxSafe ?>][first_name]" value="<?= h((string)($u['first_name'] ?? '')) ?>" required>
                                </div>
                                <div>
                                    <label>Nachname</label>
                                    <input type="text" name="users[<?= $idxSafe ?>][last_name]" value="<?= h((string)($u['last_name'] ?? '')) ?>" required>
                                </div>
                            </div>
                            <div class="row" style="margin-top:10px;">
                                <div>
                                    <label>Textfarbe (optional)</label>
                                    <input class="color" type="text" name="users[<?= $idxSafe ?>][text_color]" value="<?= h((string)($u['text_color'] ?? '#3b82f6')) ?>" placeholder="#3b82f6">
                                    <div class="hint">Kann leer bleiben. Beispiel: <code>#3b82f6</code>.</div>
                                </div>
                            </div>
                        </div>
                    <?php $idx++; endforeach; ?>
                </div>

                <div class="actions">
                    <button class="btn" type="submit">Installation starten</button>
                    <a class="btn secondary" href="index.php">Formular zurücksetzen</a>
                </div>

                <div class="footer-note">
                    Argon2id Pflicht: Wenn dein PHP ohne Argon2 kompiliert ist, bricht das Setup ab.
                    Du erkennst es sofort in der Statusliste rechts.
                </div>
            </form>
        </div>

        <div class="card">
            <div class="section-title">
                <h2>Status</h2>
                <span class="pill">Schritt für Schritt</span>
            </div>

            <ul class="steps">
                <?php if ($_SERVER['REQUEST_METHOD'] !== 'POST'): ?>
                    <li class="step">
                        <span class="icon ok">i</span>
                        <div>
                            <b>Bereit</b>
                            <small>Fülle links das Formular aus. Danach startet der Installer und zeigt hier die Ergebnisse.</small>
                        </div>
                    </li>
                <?php else: ?>
                    <?php foreach ($steps as $s): ?>
                        <li class="step">
                            <span class="icon <?= $s['ok'] ? 'ok' : 'bad' ?>"><?= $s['ok'] ? '✓' : '✕' ?></span>
                            <div>
                                <b><?= h($s['label']) ?></b>
                                <small><?= h($s['detail']) ?></small>
                            </div>
                        </li>
                    <?php endforeach; ?>
                <?php endif; ?>
            </ul>

            <?php if ($_SERVER['REQUEST_METHOD'] === 'POST' && count($createdUsers) > 0): ?>
                <div style="margin-top:16px;">
                    <div class="section-title">
                        <h2>Zugangsdaten</h2>
                        <span class="pill warn">einmalig anzeigen</span>
                    </div>
                    <div class="hint">
                        Diese Passwörter werden nicht wieder angezeigt. Speichere sie jetzt, falls E-Mails nicht rausgehen.
                        Danach sollten die Nutzer ihr Passwort direkt in <code>Mein Profil</code> ändern.
                    </div>
                    <table>
                        <thead>
                        <tr>
                            <th>User</th>
                            <th>E-Mail</th>
                            <th>Passwort</th>
                            <th>Mail</th>
                        </tr>
                        </thead>
                        <tbody>
                        <?php foreach ($createdUsers as $u): ?>
                            <tr>
                                <td class="mono"><?= h($u['username']) ?></td>
                                <td><?= h($u['email']) ?></td>
                                <td class="mono"><?= h($u['password']) ?></td>
                                <td>
                                    <?= $u['mail_ok'] ? '<span class="mono" style="color:var(--ok)">✓</span>' : '<span class="mono" style="color:var(--bad)">✕</span>' ?>
                                    <div class="hint" style="margin:4px 0 0 0;"><?= h($u['mail_msg']) ?></div>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                        </tbody>
                    </table>
                    <div class="hint" style="margin-top:10px;">
                        Login-Link: <a href="<?= h($loginUrl) ?>"><?= h($loginUrl) ?></a>
                    </div>
                </div>
            <?php endif; ?>
        </div>
    </div>
</div>

<script>
    const usersWrap = document.getElementById('usersWrap');
    const addUserBtn = document.getElementById('addUserBtn');

    function countUserRows(){
        return usersWrap.querySelectorAll('.user-row').length;
    }

    function nextIndex(){
        const rows = usersWrap.querySelectorAll('.user-row');
        let max = -1;
        rows.forEach(r => {
            const idx = parseInt(r.getAttribute('data-idx') || '0', 10);
            if (idx > max) max = idx;
        });
        return max + 1;
    }

    function removeUser(btn){
        const row = btn.closest('.user-row');
        if (!row) return;
        row.remove();
        if (countUserRows() < 1) {
            // immer mindestens 1 Zeile
            addUserRow();
        }
    }
    window.removeUser = removeUser;

    function addUserRow(){
        if (countUserRows() >= 5) {
            alert('Maximal 5 Nutzer.');
            return;
        }
        const idx = nextIndex();
        const div = document.createElement('div');
        div.className = 'user-row';
        div.setAttribute('data-idx', String(idx));
        div.innerHTML = `
            <button type="button" class="smallbtn remove" onclick="removeUser(this)">Entfernen</button>
            <div class="row four">
                <div>
                    <label>Username</label>
                    <input type="text" name="users[${idx}][username]" required>
                </div>
                <div>
                    <label>E-Mail</label>
                    <input type="email" name="users[${idx}][email]" required>
                </div>
                <div>
                    <label>Vorname</label>
                    <input type="text" name="users[${idx}][first_name]" required>
                </div>
                <div>
                    <label>Nachname</label>
                    <input type="text" name="users[${idx}][last_name]" required>
                </div>
            </div>
            <div class="row" style="margin-top:10px;">
                <div>
                    <label>Textfarbe (optional)</label>
                    <input class="color" type="text" name="users[${idx}][text_color]" value="#3b82f6" placeholder="#3b82f6">
                    <div class="hint">Kann leer bleiben. Beispiel: <code>#3b82f6</code>.</div>
                </div>
            </div>
        `;
        usersWrap.appendChild(div);
        div.querySelector('input[type=text]')?.focus();
    }

    addUserBtn?.addEventListener('click', addUserRow);
</script>
</body>
</html>
