<?php

declare(strict_types=1);

namespace SbpJm\FlarumMSTeamsWebhook\Service;

use Flarum\Settings\SettingsRepositoryInterface;
use GuzzleHttp\Client;
use RuntimeException;

class GraphTokenProvider
{
    protected ?string $accessToken = null;
    protected int $expiresAt = 0;

    public function __construct(
        protected Client $http,
        protected SettingsRepositoryInterface $settings
    ) {
    }

    public function getAccessToken(): string
    {
        if ($this->accessToken !== null && time() < ($this->expiresAt - 60)) {
            return $this->accessToken;
        }

        $tenantId = trim((string) $this->settings->get('sbp-jm-msteams-webhook.tenant_id', ''));
        $clientId = trim((string) $this->settings->get('sbp-jm-msteams-webhook.client_id', ''));
        $clientSecret = (string) $this->settings->get('sbp-jm-msteams-webhook.client_secret', '');

        if ($tenantId === '' || $clientId === '' || $clientSecret === '') {
            throw new RuntimeException('Missing Microsoft Graph credentials in Flarum settings.');
        }

        $response = $this->http->request('POST', sprintf('https://login.microsoftonline.com/%s/oauth2/v2.0/token', rawurlencode($tenantId)), [
            'form_params' => [
                'grant_type' => 'client_credentials',
                'client_id' => $clientId,
                'client_secret' => $clientSecret,
                'scope' => 'https://graph.microsoft.com/.default',
            ],
            'timeout' => (int) $this->settings->get('sbp-jm-msteams-webhook.timeout_seconds', '15'),
        ]);

        $payload = json_decode((string) $response->getBody(), true);

        if (!is_array($payload) || empty($payload['access_token'])) {
            throw new RuntimeException('Microsoft Graph token response did not contain an access token.');
        }

        $this->accessToken = (string) $payload['access_token'];
        $this->expiresAt = time() + (int) ($payload['expires_in'] ?? 3600);

        return $this->accessToken;
    }
}