<?php

use App\Services\Graph\GraphContractRegistry;
use App\Services\Graph\GraphLogger;
use App\Services\Graph\MicrosoftGraphClient;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;

beforeEach(function () {
    config()->set('graph.base_url', 'https://graph.microsoft.com');
    config()->set('graph.version', 'beta');
    config()->set('graph.managed_environment_id', 'tenant');
    config()->set('graph.client_id', 'client');
    config()->set('graph.client_secret', 'secret');
    config()->set('graph.scope', 'https://graph.microsoft.com/.default');

    // Ensure we don't accidentally resolve via supported_policy_types
    config()->set('tenantpilot.supported_policy_types', []);
});

it('uses graph contract resource path for applyPolicy', function () {
    config()->set('graph_contracts.types.mamAppConfiguration', [
        'resource' => 'deviceAppManagement/targetedManagedAppConfigurations',
        'allowed_select' => ['id', 'displayName'],
        'allowed_expand' => [],
        'type_family' => ['#microsoft.graph.targetedManagedAppConfiguration'],
        'create_method' => 'POST',
        'update_method' => 'PATCH',
        'id_field' => 'id',
        'hydration' => 'properties',
    ]);

    Http::fake([
        'https://login.microsoftonline.com/*' => Http::response([
            'access_token' => 'fake-token',
            'expires_in' => 3600,
        ], 200),
        'https://graph.microsoft.com/*' => Http::response(['id' => 'A_1'], 200),
    ]);

    $client = new MicrosoftGraphClient(
        logger: app(GraphLogger::class),
        contracts: app(GraphContractRegistry::class),
    );

    $client->applyPolicy(
        policyType: 'mamAppConfiguration',
        policyId: 'A_1',
        payload: ['displayName' => 'Test'],
        options: ['tenant' => 'tenant', 'client_id' => 'client', 'client_secret' => 'secret'],
    );

    Http::assertSent(function (Request $request) {
        if (! str_contains($request->url(), 'graph.microsoft.com')) {
            return false;
        }

        return str_contains($request->url(), '/beta/deviceAppManagement/targetedManagedAppConfigurations/A_1');
    });
});

it('uses built-in endpoint mapping for endpoint security policies when config is missing', function () {
    config()->set('graph_contracts.types.endpointSecurityPolicy', []);
    config()->set('tenantpilot.foundation_types', []);

    Http::fake([
        'https://login.microsoftonline.com/*' => Http::response([
            'access_token' => 'fake-token',
            'expires_in' => 3600,
        ], 200),
        'https://graph.microsoft.com/*' => Http::response(['id' => 'E_1'], 200),
    ]);

    $client = new MicrosoftGraphClient(
        logger: app(GraphLogger::class),
        contracts: app(GraphContractRegistry::class),
    );

    $client->applyPolicy(
        policyType: 'endpointSecurityPolicy',
        policyId: 'E_1',
        payload: ['name' => 'Test'],
        options: ['tenant' => 'tenant', 'client_id' => 'client', 'client_secret' => 'secret'],
    );

    Http::assertSent(function (Request $request) {
        if (! str_contains($request->url(), 'graph.microsoft.com')) {
            return false;
        }

        if (! str_contains($request->url(), '/beta/deviceManagement/configurationPolicies/E_1')) {
            return false;
        }

        return ! str_contains($request->url(), '/beta/deviceManagement/endpointSecurityPolicy/E_1');
    });
});
