<?php

namespace App\Services;

use GuzzleHttp\Client;
use Illuminate\Support\Arr;

class MicrosoftGraphTokenManager
{
    public function __construct(
        private string $tenantId = '',
        private string $clientId = '',
        private string $clientSecret = '',
        private ?Client $http = null,
    ) {
        $this->tenantId    = $this->tenantId    ?: config('services.azure.tenant_id');
        $this->clientId    = $this->clientId    ?: config('services.azure.client_id');
        $this->clientSecret= $this->clientSecret?: config('services.azure.client_secret');
        $this->http = $this->http ?: new Client(['http_errors' => false, 'timeout' => 60]);
    }
    
    public function getAccessToken(): string
    {
        // Fail fast if creds are missing
        foreach (['tenantId','clientId','clientSecret'] as $k) {
            if (empty($this->$k)) {
                throw new \RuntimeException("Azure credential {$k} is missing");
            }
        }
    
        $resp = $this->http->post(
            "https://login.microsoftonline.com/{$this->tenantId}/oauth2/v2.0/token",
            [
                // 👇 IMPORTANT: send as application/x-www-form-urlencoded
                'form_params' => [
                    'grant_type'    => 'client_credentials',
                    'client_id'     => $this->clientId,
                    'client_secret' => $this->clientSecret,
                    'scope'         => 'https://graph.microsoft.com/.default',
                ],
                'http_errors' => false,
                'timeout'     => 60,
            ]
        );
    
        $status = $resp->getStatusCode();
        $body   = (string) $resp->getBody();
        $json   = json_decode($body, true);
    
        if ($status !== 200 || !is_array($json) || empty($json['access_token'])) {
            \Log::error('Azure token error', [
                'status' => $status,
                'body'   => substr($body, 0, 500),
            ]);
            throw new \RuntimeException("Token error {$status}");
        }
    
        return $json['access_token'];
    }

    public function refresh(string $refreshToken): array
    {
        $resp = $this->http->post("https://login.microsoftonline.com/{$this->tenantId}/oauth2/v2.0/token", [
            'form_params' => [
                'client_id'     => $this->clientId,
                'client_secret' => $this->clientSecret,
                'grant_type'    => 'refresh_token',
                'refresh_token' => $refreshToken,
                'scope'         => 'https://graph.microsoft.com/.default offline_access',
            ],
        ]);
        
        
        $data = json_decode((string)$resp->getBody(), true);
        Log::debug($data);
        if (!Arr::get($data, 'access_token')) {
            throw new \RuntimeException('Failed to refresh Graph token: '.(string)$resp->getBody());
        }
        return $data;
    }
}
