<?php
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/auth.php';

set_time_limit(60);

$code  = $_GET['code'] ?? null;
$state = $_GET['state'] ?? null;

if (!$code || !$state) {
    http_response_code(400);
    die("OAuth Fehler: code/state fehlt");
}

if (empty($_SESSION['oauth_state']) || !hash_equals($_SESSION['oauth_state'], $state)) {
    http_response_code(403);
    die("OAuth Fehler: Ungültiger State (CSRF Schutz)");
}

unset($_SESSION['oauth_state']);

/**
 * Helper: POST Form Request via cURL
 */
function curlPostForm(string $url, array $data): array
{
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($data),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER => false,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 20,
    ]);

    $body = curl_exec($ch);

    if ($body === false) {
        $err = curl_error($ch);
        curl_close($ch);
        throw new RuntimeException("cURL POST Fehler: $err");
    }

    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    return [$httpCode, $body];
}

/**
 * Helper: GET JSON Request via cURL
 */
function curlGetJson(string $url, string $accessToken): array
{
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . $accessToken
        ],
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 20,
    ]);

    $body = curl_exec($ch);

    if ($body === false) {
        $err = curl_error($ch);
        curl_close($ch);
        throw new RuntimeException("cURL GET Fehler: $err");
    }

    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $json = json_decode($body, true);
    return [$httpCode, $json, $body];
}

// 1) Access Token holen
try {
    [$tokenHttp, $tokenBody] = curlPostForm(GITLAB_BASE_URL . '/oauth/token', [
        'client_id' => GITLAB_CLIENT_ID,
        'client_secret' => GITLAB_CLIENT_SECRET,
        'code' => $code,
        'grant_type' => 'authorization_code',
        'redirect_uri' => GITLAB_REDIRECT_URI
    ]);
} catch (Throwable $e) {
    http_response_code(500);
    die("Token-Request failed: " . $e->getMessage());
}

if ($tokenHttp !== 200) {
    http_response_code(500);
    die("Token-Request HTTP $tokenHttp: " . htmlspecialchars($tokenBody));
}

$tokenData = json_decode($tokenBody, true);
$accessToken = $tokenData['access_token'] ?? null;

if (!$accessToken) {
    http_response_code(500);
    die("Kein access_token erhalten");
}

// 2) User Info holen
try {
    [$userHttp, $userData, $userRaw] = curlGetJson(GITLAB_BASE_URL . '/api/v4/user', $accessToken);
} catch (Throwable $e) {
    http_response_code(500);
    die("User-Request failed: " . $e->getMessage());
}

if ($userHttp !== 200 || empty($userData['id'])) {
    http_response_code(500);
    die("User-Request HTTP $userHttp: " . htmlspecialchars($userRaw));
}

$userId = (int)$userData['id'];
$projectId = (int)GITLAB_REQUIRED_PROJECT_ID;

// 3) Projekt-Zugriff prüfen: GET /projects/:id (gilt für Owner, direkte Mitglieder und vererbte Gruppen)
$projectUrl = GITLAB_BASE_URL . "/api/v4/projects/$projectId";
try {
    [$projectHttp, $projectData, $projectRaw] = curlGetJson($projectUrl, $accessToken);
} catch (Throwable $e) {
    http_response_code(500);
    die("Projekt-Check failed: " . $e->getMessage());
}

if ($projectHttp !== 200) {
    http_response_code(403);
    die("Zugriff verweigert: Du hast keinen Zugriff auf das Projekt.");
}

// access_level aus members/all holen (inkl. vererbt); sonst Fallback
$accessLevel = 20; // Reporter als Fallback
$membersUrl = GITLAB_BASE_URL . "/api/v4/projects/$projectId/members/all?per_page=100";
try {
    [$membersHttp, $membersList, $membersRaw] = curlGetJson($membersUrl, $accessToken);
    if ($membersHttp === 200 && is_array($membersList)) {
        foreach ($membersList as $m) {
            if ((int)($m['id'] ?? 0) === $userId) {
                $accessLevel = (int)($m['access_level'] ?? 20);
                break;
            }
        }
    }
} catch (Throwable $e) {
    // ignorieren, access_level bleibt Fallback
}
if ($accessLevel <= 0) {
    $accessLevel = 20;
}

// 4) Login Session setzen
$_SESSION['admin_logged_in'] = true;
$_SESSION['admin_gitlab_user'] = [
    'id' => $userId,
    'username' => $userData['username'] ?? null,
    'name' => $userData['name'] ?? null,
    'email' => $userData['email'] ?? null,
    'access_level' => $accessLevel,
];

// Weiter
header('Location: index.php');
exit;
