<?php
// oauth/authorize.php
session_start();

require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../classes/OAuth.php';

$requestParams = [
    'response_type' => $_GET['response_type'] ?? '',
    'client_id' => $_GET['client_id'] ?? '',
    'redirect_uri' => $_GET['redirect_uri'] ?? '',
    'scope' => $_GET['scope'] ?? '',
    'state' => $_GET['state'] ?? '',
];

$responseType = $requestParams['response_type'];
$clientId = trim($requestParams['client_id']);
$redirectUri = trim($requestParams['redirect_uri']);
$scope = trim($requestParams['scope']);
$state = $requestParams['state'];

function oauth_bad_request(string $message): void {
    http_response_code(400);
    header('Content-Type: application/json');
    echo json_encode(['error' => 'invalid_request', 'error_description' => $message], JSON_UNESCAPED_SLASHES);
    exit();
}

function oauth_redirect_with_error(string $redirectUri, string $error, ?string $description = null, ?string $state = null): void {
    $fragment = '';
    if (($hashPos = strpos($redirectUri, '#')) !== false) {
        $fragment = substr($redirectUri, $hashPos);
        $redirectUri = substr($redirectUri, 0, $hashPos);
    }
    $separator = (strpos($redirectUri, '?') === false) ? '?' : '&';
    $payload = ['error' => $error];
    if ($description) {
        $payload['error_description'] = $description;
    }
    if ($state !== null && $state !== '') {
        $payload['state'] = $state;
    }
    $location = $redirectUri . $separator . http_build_query($payload) . $fragment;
    header('Location: ' . $location);
    exit();
}

function oauth_redirect_with_params(string $redirectUri, array $params): void {
    $fragment = '';
    if (($hashPos = strpos($redirectUri, '#')) !== false) {
        $fragment = substr($redirectUri, $hashPos);
        $redirectUri = substr($redirectUri, 0, $hashPos);
    }
    $separator = (strpos($redirectUri, '?') === false) ? '?' : '&';
    $location = $redirectUri . $separator . http_build_query($params) . $fragment;
    header('Location: ' . $location);
    exit();
}

if ($responseType !== 'code') {
    oauth_bad_request('Unsupported response_type. Only "code" is supported.');
}

if ($clientId === '' || $redirectUri === '') {
    oauth_bad_request('Missing client_id or redirect_uri.');
}

if (!is_logged_in()) {
    $_SESSION['oauth_pending_request'] = [
        'params' => $requestParams,
        'created_at' => time(),
    ];
    set_message("Please login to continue with the requested integration.", "warning");
    header('Location: ../index.php');
    exit();
}

if (!isset($_SESSION['person_id']) || (int) $_SESSION['person_id'] <= 0) {
    oauth_bad_request('Your session is missing required profile information.');
}

$oauthService = new OAuthService($pdo);
$client = $oauthService->getClient($clientId);

if (!$client) {
    oauth_bad_request('Unknown or revoked client.');
}

if (!$oauthService->isRedirectUriAllowed($client, $redirectUri)) {
    oauth_bad_request('The provided redirect_uri is not registered for this client.');
}

if (!$oauthService->isScopeAllowed($client, $scope)) {
    oauth_redirect_with_error($redirectUri, 'invalid_scope', 'Requested scope is not permitted.', $state);
}

$codeData = $oauthService->issueAuthorizationCode(
    $clientId,
    (int) $_SESSION['person_id'],
    $redirectUri,
    $scope !== '' ? $scope : null
);

$payload = ['code' => $codeData['code']];
if ($state !== '') {
    $payload['state'] = $state;
}

oauth_redirect_with_params($redirectUri, $payload);
