<?php

$accessToken = null;
$refreshingToken = false;
$pendingResolvers = [];

function refresh_access_token() {
	global $accessToken, $refreshingToken, $pendingResolvers;

	// If a refresh is already in progress, wait
	if ($refreshingToken) {
		$promise = function() use (&$accessToken) {
			return $accessToken;
		};
		$pendingResolvers[] = $promise;
		return end($pendingResolvers)();
	}

	$refreshingToken = true;

	$config = get_option('athena_options');
	if (!$config) {
		$refreshingToken = false;
		// Admin "Show Logs" view
		AthenaLogger::reindexLogs('No general configuration found', 'error');
		// Debug Log
		throw new Exception("No general configuration found");
	}

	$backendUrl = rtrim($config['athena_dashboard_url'], '/') . '/';
	$clientId = $config['client_id'];
	$clientSecret = $config['client_secret'];

	$response = wp_remote_post($backendUrl . 'oauth/token', [
		'headers' => ['Content-Type' => 'application/json'],
		'body' => json_encode([
			'client_id' => $clientId,
			'client_secret' => $clientSecret,
			'grant_type' => 'client_credentials',
			'scope' => '*'
		]),
		'timeout' => 15,
	]);

	if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) {
		$refreshingToken = false;
		$accessToken = null;
		foreach ($pendingResolvers as $resolve) { $resolve(); }
		$pendingResolvers = [];
		// Admin "Show Logs" view
		AthenaLogger::reindexLogs('Reindex failed: Failed to refresh token.', 'error');
		// Debug Log
		throw new Exception("Failed to refresh token");
	}

	$body = json_decode(wp_remote_retrieve_body($response), true);
	$accessToken = $body['access_token'] ?? null;

	$refreshingToken = false;
	foreach ($pendingResolvers as $resolve) { $resolve(); }
	$pendingResolvers = [];
}

function ensure_token() {
	global $accessToken;
	if (!$accessToken) {
		refresh_access_token();
	}
	return $accessToken;
}

function authorized_fetch($endpoint, $body, $retryCount = 0) {
	global $accessToken;

	$config = get_option('athena_options');
	if (!$config) {
		return new WP_Error('config_missing', 'Configuration not found', ['status' => 500]);
	}

	$backendUrl = rtrim($config['athena_dashboard_url'], '/') . '/';
	$token = ensure_token();

	$response = wp_remote_post($backendUrl . "api/v3/{$endpoint}", [
		'headers' => [
			'Content-Type' => 'application/json',
			'Authorization' => 'Bearer ' . $token,
		],
		'body' => json_encode($body),
		'timeout' => 120,
	]);

	$statusCode = wp_remote_retrieve_response_code($response);

	if ($statusCode === 401 && $retryCount < 2) {
		refresh_access_token();
		return authorized_fetch($endpoint, $body, $retryCount + 1);
	}

	if (is_wp_error($response) || $statusCode < 200 || $statusCode >= 300) {
		AthenaLogger::error('API request failed for endpoint ' . $endpoint . ' with status ' . $statusCode . ' and body: ' . wp_remote_retrieve_body($response));
		return new WP_Error('api_error', 'API request failed', ['status' => $statusCode]);
	}

	return json_decode(wp_remote_retrieve_body($response), true);
}