<?php

declare(strict_types=1);

use App\Filament\Resources\AlertRuleResource;
use App\Filament\Resources\AlertRuleResource\Pages\CreateAlertRule;
use App\Filament\Resources\AlertRuleResource\Pages\EditAlertRule;
use App\Models\AlertDestination;
use App\Models\AlertRule;
use App\Support\Workspaces\WorkspaceContext;
use Livewire\Livewire;

it('creates and edits alert rules with attached destinations', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $workspaceId = (int) session()->get(\App\Support\Workspaces\WorkspaceContext::SESSION_KEY);

    $destinationA = AlertDestination::factory()->create([
        'workspace_id' => $workspaceId,
        'name' => 'Teams destination',
    ]);
    $destinationB = AlertDestination::factory()->email()->create([
        'workspace_id' => $workspaceId,
        'name' => 'Email destination',
    ]);

    $this->actingAs($user);

    Livewire::test(CreateAlertRule::class)
        ->fillForm([
            'name' => 'Critical drift alerts',
            'is_enabled' => true,
            'event_type' => 'high_drift',
            'minimum_severity' => 'high',
            'tenant_scope_mode' => 'allowlist',
            'tenant_allowlist' => [(int) $tenant->getKey()],
            'cooldown_seconds' => 900,
            'quiet_hours_enabled' => true,
            'quiet_hours_start' => '22:00',
            'quiet_hours_end' => '06:00',
            'quiet_hours_timezone' => 'UTC',
            'destination_ids' => [(int) $destinationA->getKey(), (int) $destinationB->getKey()],
        ])
        ->call('create')
        ->assertHasNoFormErrors();

    $rule = AlertRule::query()->where('name', 'Critical drift alerts')->first();
    expect($rule)->not->toBeNull();
    expect($rule->tenant_allowlist)->toBe([(int) $tenant->getKey()]);
    expect($rule->destinations()->count())->toBe(2);

    Livewire::test(EditAlertRule::class, ['record' => $rule->getRouteKey()])
        ->fillForm([
            'name' => 'Critical drift alerts updated',
            'is_enabled' => false,
            'destination_ids' => [(int) $destinationB->getKey()],
            'tenant_allowlist' => [],
            'tenant_scope_mode' => 'all',
        ])
        ->call('save')
        ->assertHasNoFormErrors();

    $rule->refresh();
    expect($rule->name)->toBe('Critical drift alerts updated');
    expect((bool) $rule->is_enabled)->toBeFalse();
    expect($rule->tenant_scope_mode)->toBe('all');
    expect($rule->destinations()->pluck('alert_destinations.id')->all())->toBe([(int) $destinationB->getKey()]);
});

it('shows targeting semantics labels and hides old scope labels on alert rule edit form', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $workspaceId = (int) session()->get(WorkspaceContext::SESSION_KEY);

    $destination = AlertDestination::factory()->create(['workspace_id' => $workspaceId]);

    $rule = AlertRule::factory()->create([
        'workspace_id' => $workspaceId,
        'tenant_scope_mode' => 'allowlist',
        'tenant_allowlist' => [(int) $tenant->getKey()],
    ]);
    $rule->destinations()->attach((int) $destination->getKey(), ['workspace_id' => $workspaceId]);

    $this->actingAs($user);

    $this->withSession([
        WorkspaceContext::SESSION_KEY => $workspaceId,
    ])->get(AlertRuleResource::getUrl('edit', ['record' => $rule], panel: 'admin'))
        ->assertOk()
        ->assertSee('Applies to tenants')
        ->assertSee('This rule is workspace-wide. Use this to limit where it applies.')
        ->assertSee('Selected tenants')
        ->assertSee('Only these tenants will trigger this rule.')
        ->assertDontSee('ManagedEnvironment scope mode')
        ->assertDontSee('ManagedEnvironment allowlist');
});

it('shows form section headings on alert rule edit form', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $workspaceId = (int) session()->get(WorkspaceContext::SESSION_KEY);

    $destination = AlertDestination::factory()->create(['workspace_id' => $workspaceId]);

    $rule = AlertRule::factory()->create([
        'workspace_id' => $workspaceId,
    ]);
    $rule->destinations()->attach((int) $destination->getKey(), ['workspace_id' => $workspaceId]);

    $this->actingAs($user);

    $this->withSession([
        WorkspaceContext::SESSION_KEY => $workspaceId,
    ])->get(AlertRuleResource::getUrl('edit', ['record' => $rule], panel: 'admin'))
        ->assertOk()
        ->assertSee('Rule')
        ->assertSee('Applies to')
        ->assertSee('Delivery');
});
