<?php

use App\Filament\Resources\PolicyVersionResource;
use App\Models\Policy;
use App\Models\PolicyVersion;
use App\Models\ManagedEnvironment;
use App\Models\User;

beforeEach(function () {
    putenv('INTUNE_TENANT_ID');
    unset($_ENV['INTUNE_TENANT_ID'], $_SERVER['INTUNE_TENANT_ID']);

    $this->tenant = ManagedEnvironment::factory()->create();
    $this->policy = Policy::factory()->create([
        'managed_environment_id' => $this->tenant->id,
    ]);
    $this->user = User::factory()->create();
    [$this->user, $this->tenant] = createUserWithTenant($this->tenant, $this->user, role: 'owner');
});

it('displays policy version page', function () {
    $version = PolicyVersion::factory()->create([
        'managed_environment_id' => $this->tenant->id,
        'policy_id' => $this->policy->id,
        'version_number' => 1,
    ]);

    $this->actingAs($this->user);

    $response = $this->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $this->tenant));

    $response->assertOk();
});

it('displays assignments widget when version has assignments', function () {
    $version = PolicyVersion::factory()->create([
        'managed_environment_id' => $this->tenant->id,
        'policy_id' => $this->policy->id,
        'version_number' => 1,
        'assignments' => [
            [
                'id' => 'assignment-1',
                'intent' => 'apply',
                'target' => [
                    '@odata.type' => '#microsoft.graph.groupAssignmentTarget',
                    'groupId' => 'group-123',
                    'assignment_filter_name' => 'Targeted Devices',
                    'deviceAndAppManagementAssignmentFilterId' => 'filter-1',
                    'deviceAndAppManagementAssignmentFilterType' => 'include',
                ],
            ],
            [
                'id' => 'assignment-2',
                'intent' => 'apply',
                'target' => [
                    '@odata.type' => '#microsoft.graph.exclusionGroupAssignmentTarget',
                    'groupId' => 'group-456',
                    'deviceAndAppManagementAssignmentFilterId' => null,
                    'deviceAndAppManagementAssignmentFilterType' => 'none',
                ],
            ],
        ],
        'scope_tags' => [
            'ids' => ['0'],
            'names' => ['Default'],
        ],
    ]);

    $this->actingAs($this->user);

    $response = $this->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $this->tenant));

    $response->assertOk();
    $response->assertSeeLivewire('policy-version-assignments-widget');
    $response->assertSee('2 assignment(s)');
    $response->assertSee('Include group');
    $response->assertSee('Exclude group');
    $response->assertSee('Filter (include): Targeted Devices');
});

it('displays empty state when version has no assignments', function () {
    $version = PolicyVersion::factory()->create([
        'managed_environment_id' => $this->tenant->id,
        'policy_id' => $this->policy->id,
        'version_number' => 1,
        'assignments' => null,
    ]);

    $this->actingAs($this->user);

    $response = $this->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $this->tenant));

    $response->assertOk();
    $response->assertSee('Assignments were not captured for this version');
});

it('shows empty assignments message when assignments were fetched', function () {
    $version = PolicyVersion::factory()->create([
        'managed_environment_id' => $this->tenant->id,
        'policy_id' => $this->policy->id,
        'version_number' => 1,
        'assignments' => null,
        'metadata' => [
            'assignments_fetched' => true,
            'assignments_count' => 0,
        ],
    ]);

    $this->actingAs($this->user);

    $response = $this->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $this->tenant));

    $response->assertOk();
    $response->assertSee('No assignments found for this version');
});

it('shows a dedicated RBAC explanation instead of a Graph error for role definitions', function () {
    $policy = Policy::factory()->create([
        'managed_environment_id' => $this->tenant->id,
        'policy_type' => 'intuneRoleDefinition',
    ]);

    $version = PolicyVersion::factory()->create([
        'managed_environment_id' => $this->tenant->id,
        'policy_id' => $policy->id,
        'version_number' => 1,
        'policy_type' => 'intuneRoleDefinition',
        'assignments' => null,
        'metadata' => [
            'assignments_fetch_failed' => true,
            'assignments_fetch_error' => "Parsing OData Select and Expand failed: Could not find a property named 'assignments' on type 'microsoft.graph.roleDefinition'.",
        ],
    ]);

    $this->actingAs($this->user);

    $response = $this->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $this->tenant));

    $response->assertOk();
    $response->assertSee('Standard policy assignments do not apply to Intune RBAC role definitions.');
    $response->assertSee('Role memberships and scope are modeled separately as Intune RBAC role assignments.');
    $response->assertDontSee('Assignments could not be fetched from Microsoft Graph.');
    $response->assertDontSee("Could not find a property named 'assignments' on type 'microsoft.graph.roleDefinition'.");
});

it('shows compliance notifications when present', function () {
    $version = PolicyVersion::factory()->create([
        'managed_environment_id' => $this->tenant->id,
        'policy_id' => $this->policy->id,
        'version_number' => 1,
        'policy_type' => 'deviceCompliancePolicy',
        'assignments' => null,
        'snapshot' => [
            'scheduledActionsForRule' => [
                [
                    'ruleName' => 'Test rule',
                    'scheduledActionConfigurations' => [
                        [
                            'actionType' => 'notification',
                            'notificationTemplateId' => 'template-123',
                        ],
                    ],
                ],
            ],
        ],
    ]);

    $this->actingAs($this->user);

    $response = $this->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $this->tenant));

    $response->assertOk();
    $response->assertSee('Compliance notifications');
    $response->assertSee('Test rule');
    $response->assertSee('template-123');
});

it('uses a default label when compliance rule name is missing', function () {
    $version = PolicyVersion::factory()->create([
        'managed_environment_id' => $this->tenant->id,
        'policy_id' => $this->policy->id,
        'version_number' => 1,
        'policy_type' => 'deviceCompliancePolicy',
        'assignments' => null,
        'snapshot' => [
            'scheduledActionsForRule' => [
                [
                    'ruleName' => null,
                    'scheduledActionConfigurations' => [
                        [
                            'actionType' => 'notification',
                            'notificationTemplateId' => 'template-456',
                        ],
                    ],
                ],
            ],
        ],
    ]);

    $this->actingAs($this->user);

    $response = $this->get(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $this->tenant));

    $response->assertOk();
    $response->assertSee('Compliance notifications');
    $response->assertSee('Default rule');
    $response->assertSee('template-456');
});

it('renders structured normalized settings for compliance policy versions', function () {
    $version = PolicyVersion::factory()->create([
        'managed_environment_id' => $this->tenant->id,
        'policy_id' => $this->policy->id,
        'version_number' => 1,
        'policy_type' => 'deviceCompliancePolicy',
        'platform' => 'all',
        'snapshot' => [
            '@odata.type' => '#microsoft.graph.windows10CompliancePolicy',
            'passwordRequired' => true,
        ],
    ]);

    $this->actingAs($this->user);

    $response = $this->get(PolicyVersionResource::getUrl('view', ['record' => $version, 'tab' => 'normalized-settings'], tenant: $this->tenant));

    $response->assertOk();
    $response->assertSee('Password & Access');
    $response->assertSee('Password required');
    $response->assertSee('Enabled');
});
