<?php
// src/auth.php
// Zentrale Auth-Logik: Session, CSRF, Login, Registrierung, aktueller Nutzer

declare(strict_types=1);

require_once __DIR__ . '/../config/db.php'; // Stellt $pdo (PDO) bereit

// --- Session Setup ---
if (session_status() !== PHP_SESSION_ACTIVE) {
    $secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
    session_set_cookie_params([
        'lifetime' => 0,
        'path'     => '/',
        'domain'   => '',         // Standard: aktuelle Domain
        'secure'   => $secure,
        'httponly' => true,
        'samesite' => 'Lax',
    ]);
    session_start();
}

// --- Sprache ermitteln / speichern ---
function auth_get_lang(): string {
    if (!empty($_GET['lang'])) {
        $_SESSION['lang'] = $_GET['lang'];
    }
    if (!empty($_SESSION['lang'])) {
        return $_SESSION['lang'];
    }
    return 'en';
}

// --- CSRF-Token ---
function auth_csrf_token(): string {
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

function auth_verify_csrf(?string $token): bool {
    if (empty($token) || empty($_SESSION['csrf_token'])) {
        return false;
    }
    return hash_equals($_SESSION['csrf_token'], $token);
}

// --- PDO Helper ---
function auth_pdo(): PDO {
    // $pdo kommt aus config/db.php
    global $pdo;
    if (!$pdo instanceof PDO) {
        throw new RuntimeException('Database connection not available.');
    }
    return $pdo;
}

// --- Aktueller User ---
function auth_current_user(): ?array {
    if (!empty($_SESSION['user_cache']) && is_array($_SESSION['user_cache'])) {
        return $_SESSION['user_cache'];
    }
    if (empty($_SESSION['user_id'])) {
        return null;
    }
    $pdo = auth_pdo();
    $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id LIMIT 1');
    $stmt->execute([':id' => $_SESSION['user_id']]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$user) {
        return null;
    }
    $_SESSION['user_cache'] = $user;
    return $user;
}

function auth_require_login(): void {
    if (!auth_current_user()) {
        $lang = auth_get_lang();
        header('Location: /login.php?lang=' . urlencode($lang));
        exit;
    }
}

// --- Avatar-Helfer ---
function auth_user_initials(array $user): string {
    $name = $user['full_name'] ?? '';
    if (trim($name) === '') {
        $name = $user['username'] ?? $user['email'] ?? 'U';
    }
    $parts = preg_split('/\s+/', trim($name));
    $initials = strtoupper(mb_substr($parts[0], 0, 1));
    if (count($parts) > 1) {
        $initials .= strtoupper(mb_substr(end($parts), 0, 1));
    }
    return $initials;
}

function auth_user_avatar_url(array $user): ?string {
    if (!empty($user['avatar_path'])) {
        return '/uploads/avatars/' . ltrim($user['avatar_path'], '/');
    }
    return null;
}

// --- Registrierung ---
function auth_register_user(
    string $email,
    string $username,
    string $fullName,
    string $password,
    string $passwordConfirm,
    string $preferredLang
): array {
    $pdo = auth_pdo();
    $errors = [];

    $email = trim($email);
    $username = trim($username);
    $fullName = trim($fullName);

    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors['email'] = 'Bitte eine gültige E-Mail-Adresse eingeben.';
    }

    if ($username === '' || !preg_match('/^[a-zA-Z0-9_.-]{3,32}$/', $username)) {
        $errors['username'] = 'Username muss 3–32 Zeichen lang sein und darf nur Buchstaben, Zahlen, ., _, - enthalten.';
    }

    if (mb_strlen($fullName) < 3) {
        $errors['full_name'] = 'Bitte einen vollständigen Namen angeben.';
    }

    if (mb_strlen($password) < 10) {
        $errors['password'] = 'Passwort muss mindestens 10 Zeichen lang sein.';
    }

    if ($password !== $passwordConfirm) {
        $errors['password_confirm'] = 'Passwörter stimmen nicht überein.';
    }

    $allowedLangs = ['de', 'en', 'it', 'fr'];
    if (!in_array($preferredLang, $allowedLangs, true)) {
        $preferredLang = 'en';
    }

    // E-Mail / Username bereits vergeben?
    if (!$errors) {
        $stmt = $pdo->prepare('SELECT email, username FROM users WHERE email = :email OR username = :username LIMIT 1');
        $stmt->execute([
            ':email'    => $email,
            ':username' => $username,
        ]);
        $existing = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($existing) {
            if (strcasecmp($existing['email'], $email) === 0) {
                $errors['email'] = 'Diese E-Mail-Adresse wird bereits verwendet.';
            }
            if (strcasecmp($existing['username'], $username) === 0) {
                $errors['username'] = 'Dieser Username ist bereits vergeben.';
            }
        }
    }

    if ($errors) {
        return ['success' => false, 'errors' => $errors];
    }

    $hash = password_hash($password, PASSWORD_DEFAULT);
    $now = (new DateTimeImmutable('now', new DateTimeZone('UTC')))->format('Y-m-d H:i:s');

    $stmt = $pdo->prepare('
        INSERT INTO users (email, username, full_name, password_hash, preferred_lang, created_at, updated_at)
        VALUES (:email, :username, :full_name, :password_hash, :preferred_lang, :created_at, :updated_at)
    ');
    $stmt->execute([
        ':email'         => $email,
        ':username'      => $username,
        ':full_name'     => $fullName,
        ':password_hash' => $hash,
        ':preferred_lang'=> $preferredLang,
        ':created_at'    => $now,
        ':updated_at'    => $now,
    ]);

    $userId = (int)$pdo->lastInsertId();
    $_SESSION['user_id'] = $userId;
    unset($_SESSION['user_cache']); // neu laden beim nächsten Zugriff
    $_SESSION['lang'] = $preferredLang;

    return ['success' => true, 'errors' => []];
}

// --- Login ---
function auth_login(string $login, string $password): array {
    $pdo = auth_pdo();
    $errors = [];

    $login = trim($login);

    if ($login === '' || $password === '') {
        $errors['login'] = 'Bitte Zugangsdaten vollständig ausfüllen.';
        return ['success' => false, 'errors' => $errors];
    }

    $stmt = $pdo->prepare('
        SELECT * FROM users 
        WHERE email = :login OR username = :login
        LIMIT 1
    ');
    $stmt->execute([':login' => $login]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$user || !password_verify($password, $user['password_hash'])) {
        $errors['login'] = 'E-Mail/Username oder Passwort ist falsch.';
        return ['success' => false, 'errors' => $errors];
    }

    $_SESSION['user_id'] = (int)$user['id'];
    unset($_SESSION['user_cache']);
    if (!empty($user['preferred_lang'])) {
        $_SESSION['lang'] = $user['preferred_lang'];
    }

    // Option: Password-Rehash, wenn Algorithmus veraltet
    if (password_needs_rehash($user['password_hash'], PASSWORD_DEFAULT)) {
        $newHash = password_hash($password, PASSWORD_DEFAULT);
        $upd = $pdo->prepare('UPDATE users SET password_hash = :hash WHERE id = :id');
        $upd->execute([':hash' => $newHash, ':id' => $user['id']]);
    }

    return ['success' => true, 'errors' => []];
}

// --- Profil aktualisieren (Name, Sprache) ---
function auth_update_profile(int $userId, string $fullName, string $preferredLang): array {
    $pdo = auth_pdo();
    $errors = [];

    $fullName = trim($fullName);
    if (mb_strlen($fullName) < 3) {
        $errors['full_name'] = 'Bitte einen gültigen Namen angeben.';
    }

    $allowedLangs = ['de', 'en', 'it', 'fr'];
    if (!in_array($preferredLang, $allowedLangs, true)) {
        $preferredLang = 'en';
    }

    if ($errors) {
        return ['success' => false, 'errors' => $errors];
    }

    $now = (new DateTimeImmutable('now', new DateTimeZone('UTC')))->format('Y-m-d H:i:s');
    $stmt = $pdo->prepare('
        UPDATE users 
        SET full_name = :full_name,
            preferred_lang = :preferred_lang,
            updated_at = :updated_at
        WHERE id = :id
    ');
    $stmt->execute([
        ':full_name'     => $fullName,
        ':preferred_lang'=> $preferredLang,
        ':updated_at'    => $now,
        ':id'            => $userId,
    ]);

    unset($_SESSION['user_cache']);
    $_SESSION['lang'] = $preferredLang;

    return ['success' => true, 'errors' => []];
}

// --- Logout ---
function auth_logout(): void {
    $_SESSION = [];
    if (ini_get('session.use_cookies')) {
        $params = session_get_cookie_params();
        setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
    }
    session_destroy();
}
