<?php

use App\Models\ProviderConnection;
use App\Models\ProviderCredential;
use App\Models\ManagedEnvironment;
use App\Services\Graph\GraphClientInterface;
use App\Services\Graph\GraphResponse;
use App\Services\Providers\MicrosoftGraphOptionsResolver;
use App\Services\Providers\ProviderGateway;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('preserves current Microsoft-backed gateway runtime behavior through the provider-owned seam', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([
        'managed_environment_id' => $tenant->getKey(),
        'workspace_id' => $tenant->workspace_id,
        'provider' => 'microsoft',
        'entra_tenant_id' => 'entra-tenant-id',
        'is_default' => true,
    ]);

    ProviderCredential::factory()->create([
        'provider_connection_id' => $connection->getKey(),
        'payload' => [
            'client_id' => 'client-id',
            'client_secret' => 'client-secret',
        ],
    ]);

    $graph = new class implements GraphClientInterface
    {
        /** @var array<string, mixed> */
        public array $options = [];

        public function listPolicies(string $policyType, array $options = []): GraphResponse
        {
            $this->options = $options;

            return new GraphResponse(true);
        }

        public function getPolicy(string $policyType, string $policyId, array $options = []): GraphResponse
        {
            return new GraphResponse(true);
        }

        public function getOrganization(array $options = []): GraphResponse
        {
            return new GraphResponse(true);
        }

        public function applyPolicy(string $policyType, string $policyId, array $payload, array $options = []): GraphResponse
        {
            return new GraphResponse(true);
        }

        public function getServicePrincipalPermissions(array $options = []): GraphResponse
        {
            return new GraphResponse(true);
        }

        public function request(string $method, string $path, array $options = []): GraphResponse
        {
            return new GraphResponse(true);
        }
    };

    $gateway = app()->make(ProviderGateway::class, [
        'graph' => $graph,
    ]);

    $gateway->listPolicies($connection, 'deviceConfiguration', ['query' => ['$select' => 'id']]);

    expect($graph->options)->toMatchArray([
        'tenant' => 'entra-tenant-id',
        'client_id' => 'client-id',
        'client_secret' => 'client-secret',
        'query' => ['$select' => 'id'],
    ]);
    expect($graph->options['client_request_id'])->toBeString()->not->toBeEmpty();
});

it('preserves Microsoft graph option resolution for default provider connections', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    $connection = ProviderConnection::factory()->dedicated()->consentGranted()->create([
        'managed_environment_id' => $tenant->getKey(),
        'workspace_id' => $tenant->workspace_id,
        'provider' => 'microsoft',
        'entra_tenant_id' => 'default-entra-tenant-id',
        'is_default' => true,
    ]);

    ProviderCredential::factory()->create([
        'provider_connection_id' => $connection->getKey(),
        'payload' => [
            'client_id' => 'default-client-id',
            'client_secret' => 'default-client-secret',
        ],
    ]);

    $options = app(MicrosoftGraphOptionsResolver::class)->resolveForTenant($tenant);

    expect($options['tenant'])->toBe('default-entra-tenant-id')
        ->and($options['client_id'])->toBe('default-client-id')
        ->and($options['client_secret'])->toBe('default-client-secret')
        ->and($options['client_request_id'])->toBeString()->not->toBeEmpty();
});
