<?php
// auth.php - KONSOLIDIERTE VERSION (SCHLANK & VOLLSTÄNDIG)
ini_set('display_errors', 0);
error_reporting(E_ALL);
$debugLogFile = __DIR__ . '/auth-debug.log';

set_error_handler(function($errno, $errstr, $errfile, $errline) use ($debugLogFile) {
    $msg = "[" . date('Y-m-d H:i:s') . "] PHP Error ($errno): $errstr in $errfile on line $errline\n";
    file_put_contents($debugLogFile, $msg, FILE_APPEND);
    return false; 
});

ob_start();

try {
    require_once __DIR__ . '/logging_functions.php';
    require_once __DIR__ . '/validation_functions.php';

    enforceValidRequest($debugLogFile);

    $config = require __DIR__ . '/config.php';
    $dbConfig = require __DIR__ . '/db-connection.php';
    $expirySeconds = (int)($config['sessionExpirySeconds'] ?? 100);

    if (session_status() === PHP_SESSION_NONE) {
        ini_set('session.cookie_httponly', '1');
        ini_set('session.cookie_samesite', 'Lax');
        session_start();
    }

    $dsn = "pgsql:host={$dbConfig['host']};port={$dbConfig['port']};dbname={$dbConfig['dbname']}";
    $pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['password'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
    $pdo->exec("SET TIME ZONE 'Europe/Berlin'");

    $data = $_GET;
    $jsonInput = json_decode(file_get_contents('php://input'), true);
    if (is_array($jsonInput)) {
        $data = array_merge($data, $jsonInput);
    }

    $action = $data['action'] ?? 'check';
    
    require_once __DIR__ . '/auth-guard.php'; 
    $currentUid = (int)($_SESSION['uid'] ?? 1);

    if ($currentUid > 1 && isset($_SESSION['CREATED']) && (time() - $_SESSION['CREATED'] > $expirySeconds)) {
        $expiredUser = $_SESSION['username'] ?? 'User';
        $_SESSION = [];
        session_destroy();
        session_start();
        $_SESSION['STATUS_EXPIRED'] = true;
        $_SESSION['LAST_USER_NAME'] = $expiredUser;
        $currentUid = 1;
    }

    $responseData = ['success' => false, 'uid' => 1, 'username' => 'Gast'];

    switch ($action) {
        case 'check':
            if ($currentUid > 1) {
                $responseData = ['success' => true, 'uid' => $currentUid, 'username' => $_SESSION['username']];
            } elseif (isset($_SESSION['STATUS_EXPIRED'])) {
                http_response_code(401); 
                $responseData = ['success' => false, 'status' => 'expired', 'last_user' => $_SESSION['LAST_USER_NAME'], 'uid' => 1];
                unset($_SESSION['STATUS_EXPIRED'], $_SESSION['LAST_USER_NAME']);
            }
            break;

        case 'login':
        case 'register':
            $user = trim($data['username'] ?? '');
            $pass = $data['password'] ?? '';
            $authSuccess = false;

            if ($action === 'login') {
                $stmt = $pdo->prepare("SELECT uid, username, password_hash FROM public.\"{$config['userTable']}\" WHERE username ILIKE ?");
                $stmt->execute([$user]);
                $res = $stmt->fetch(PDO::FETCH_ASSOC);

                if ($res && password_verify($pass, $res['password_hash'])) {
                    $_SESSION['uid'] = (int)$res['uid'];
                    $_SESSION['username'] = $res['username'];
                    $authSuccess = true;
                }
            } else { // REGISTER
                $check = $pdo->prepare("SELECT uid FROM public.\"{$config['userTable']}\" WHERE username ILIKE ?");
                $check->execute([$user]);
                if ($check->fetch()) {
                    $responseData = ['success' => false, 'error' => 'Name bereits vergeben.', 'uid' => 1];
                } else {
                    $stmt = $pdo->prepare("INSERT INTO public.\"{$config['userTable']}\" (username, password_hash) VALUES (?, ?) RETURNING uid");
                    $stmt->execute([$user, password_hash($pass, PASSWORD_DEFAULT)]);
                    $_SESSION['uid'] = (int)$stmt->fetchColumn();
                    $_SESSION['username'] = $user;
                    $authSuccess = true;
                }
            }

            // Gemeinsame Token-Logik für Login & Register
            if ($authSuccess) {
                $_SESSION['CREATED'] = time();
                $uid = $_SESSION['uid'];

                // Alte Tokens bereinigen
                $pdo->prepare("DELETE FROM public.\"{$config['userTokenTable']}\" WHERE uid = ?")->execute([$uid]);

                // Neuen Token generieren
                $selector = bin2hex(random_bytes(8));
                $validator = bin2hex(random_bytes(32));
                $tokenHash = password_hash($validator, PASSWORD_DEFAULT);
                $expirySec = $config['rememberMeExpirySeconds'] ?? 7776000;
                $expiresAt = date('Y-m-d H:i:s', time() + $expirySec);

                $stmtIns = $pdo->prepare("INSERT INTO public.\"{$config['userTokenTable']}\" (uid, selector, token_hash, expires_at) VALUES (?, ?, ?, ?)");
                $stmtIns->execute([$uid, $selector, $tokenHash, $expiresAt]);

                setcookie('remember_me', "$selector:$validator", [
                    'expires' => time() + $expirySec,
                    'path' => '/',
                    'secure' => true,
                    'httponly' => true,
                    'samesite' => 'Lax'
                ]);

                $responseData = ['success' => true, 'uid' => $uid, 'username' => $_SESSION['username']];
            } elseif ($action === 'login' && !$authSuccess) {
                http_response_code(401);
                $responseData = ['success' => false, 'error' => 'Login fehlgeschlagen.', 'uid' => 1];
            }
            break;

        case 'export':
            require_once __DIR__ . '/auth-export.php'; 
            exit;

        case 'logout':
            if (isset($_COOKIE['remember_me'])) {
                $parts = explode(':', $_COOKIE['remember_me']);
                $stmt = $pdo->prepare("DELETE FROM public.\"{$config['userTokenTable']}\" WHERE selector = ?");
                $stmt->execute([$parts[0] ?? '']);
            }
            setcookie('remember_me', '', time() - 3600, '/');
            session_destroy();
            $responseData = ['success' => true, 'uid' => 1];
            break;

        case 'chgPwd':
            $new = $data['newPassword'] ?? '';
            $old = $data['oldPassword'] ?? '';
            if ($currentUid > 1 && strlen($new) >= ($config['minPwdLength'] ?? 8)) {
                $stmt = $pdo->prepare("SELECT password_hash FROM public.\"{$config['userTable']}\" WHERE uid = ?");
                $stmt->execute([$currentUid]);
                $res = $stmt->fetch();
                if ($res && password_verify($old, $res['password_hash'])) {
                    $pdo->prepare("UPDATE public.\"{$config['userTable']}\" SET password_hash = ? WHERE uid = ?")
                        ->execute([password_hash($new, PASSWORD_DEFAULT), $currentUid]);
                    $responseData = ['success' => true, 'uid' => $currentUid];
                } else {
                    $responseData = ['success' => false, 'error' => 'Altes Passwort falsch.', 'uid' => $currentUid];
                }
            }
            break;

        case 'anonymize':
            $stmt = $pdo->prepare("SELECT password_hash FROM public.\"{$config['userTable']}\" WHERE uid = ?");
            $stmt->execute([$currentUid]);
            $u = $stmt->fetch();
            if ($u && password_verify($data['password'] ?? '', $u['password_hash'])) {
                $pdo->beginTransaction();
                $pdo->prepare("UPDATE public.\"{$config['logTable']}\" SET uid = 1 WHERE uid = ?")->execute([$currentUid]);
                $pdo->prepare("UPDATE public.\"{$config['poiPhotoTable']}\" SET upload_by = 1 WHERE upload_by = ?")->execute([$currentUid]);
                $pdo->prepare("UPDATE public.\"{$config['userTable']}\" SET status = 2, password_hash = 'ANON' WHERE uid = ?")->execute([$currentUid]);
                $pdo->commit();
                session_destroy();
                $responseData = ['success' => true, 'uid' => 1];
            } else {
                $responseData = ['success' => false, 'error' => 'Passwort falsch.', 'uid' => $currentUid];
            }
            break;
    }

    while (ob_get_level() > 0) ob_end_clean();
    header('Content-Type: application/json');
    echo json_encode($responseData);

} catch (Throwable $e) {
    file_put_contents($debugLogFile, "[" . date('Y-m-d H:i:s') . "] FATAL: " . $e->getMessage() . "\n", FILE_APPEND);
    http_response_code(500);
    echo json_encode(['success' => false, 'error' => 'Serverfehler', 'uid' => 1]);
}