<?php

namespace Tests\Feature;

use App\Livewire\Help\Index;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Attributes\Url;
use Livewire\Livewire;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;

class HelpPageTest extends TestCase
{
    use RefreshDatabase;

    private function actAsAdmin(): void
    {
        $this->actingAs(User::factory()->create(['must_change_password' => false]));
    }

    public function test_help_route_loads_for_an_authenticated_admin(): void
    {
        $this->actAsAdmin();
        $this->get('/help')->assertOk();
    }

    public function test_default_topic_is_overview(): void
    {
        $this->actAsAdmin();
        Livewire::test(Index::class)
            ->assertSet('topic', 'overview')
            ->assertSee(__('help.topic_overview'));
    }

    public function test_unknown_topic_falls_back_to_overview(): void
    {
        $this->actAsAdmin();
        Livewire::test(Index::class, ['topic' => 'bogus'])->assertSet('topic', 'overview');
    }

    public function test_domain_tls_topic_has_the_reverse_proxy_guide(): void
    {
        $this->actAsAdmin();
        Livewire::test(Index::class)
            ->set('topic', 'domain-tls')
            ->assertSee('X-Forwarded-Proto')
            ->assertSee('TRUSTED_PROXY_CIDR')
            ->assertDontSee('Zoraxy'); // generic — no product names
    }

    public function test_security_topic_explains_the_2fa_access_paths(): void
    {
        $this->actAsAdmin();
        Livewire::test(Index::class)
            ->set('topic', 'security')
            ->assertSee('Backup-Code')
            ->assertSee('TOTP');
    }

    public function test_topic_property_is_url_bound(): void
    {
        $attrs = (new \ReflectionProperty(Index::class, 'topic'))->getAttributes(Url::class);
        $this->assertNotEmpty($attrs, 'Help topic must be #[Url]-bound for deep links / reload');
    }

    public function test_recovery_shows_the_short_host_command_not_the_long_compose_one(): void
    {
        $this->actAsAdmin();
        Livewire::test(Index::class)
            ->set('topic', 'recovery')
            ->assertSee('clusev reset-admin')
            ->assertDontSee('docker-compose.prod.yml');
    }

    public function test_commands_topic_lists_the_cli(): void
    {
        $this->actAsAdmin();
        Livewire::test(Index::class)
            ->set('topic', 'commands')
            ->assertSee('clusev reset-admin')
            ->assertSee('sudo clusev update')
            ->assertDontSee('docker-compose.prod.yml');
    }

    #[DataProvider('topicProvider')]
    public function test_each_topic_renders_its_own_partial(string $topic, string $marker): void
    {
        $this->actAsAdmin();
        Livewire::test(Index::class)->set('topic', $topic)->assertSee($marker);
    }

    public static function topicProvider(): array
    {
        return [
            ['updates', 'clusev update'],
            ['servers', 'SSH'],
            ['sessions', 'Sitzung'],
            ['email', 'SMTP'],
            ['audit', 'Audit'],
            ['recovery', 'clusev reset-admin'],
            ['commands', 'clusev ps'],
        ];
    }
}
