<?php

use App\Livewire\Admin\CheckResult;
use App\Livewire\Admin\Integrations;
use App\Support\Settings;
use Illuminate\Support\Facades\Http;
use Livewire\Livewire;

/**
 * Zweimal gemeldet, und beide Male war es dieselbe Ursache: die Antwort der
 * Verbindungsprüfung stand am SEITENENDE, hinter allen Karten und hinter dem
 * Speichern-Knopf. Der Knopf sitzt oben in der Karte.
 *
 *   „der Verbindung-testen-Knopf macht irgendwie nichts"
 *   „runterscrollen tut niemand, wenn man es nicht weiss"
 *
 * Eine Antwort, die man suchen muss, ist für den Betreiber keine. Jetzt geht
 * ein Modal auf.
 */
beforeEach(function () {
    config()->set('admin_access.secrets_key', 'base64:'.base64_encode(random_bytes(32)));
    withStripeSecret();
    Http::preventStrayRequests();
});

function integrationsUnlockedForCheck()
{
    return Livewire::actingAs(operator('Owner'), 'operator')
        ->test(Integrations::class)
        ->set('confirmablePassword', 'password')
        ->call('confirmPassword');
}

it('produces a result at all when the button is pressed', function () {
    Http::fake(['api.stripe.com/v1/account' => Http::response([
        'id' => 'acct_1', 'settings' => ['dashboard' => ['display_name' => 'CluPilot']],
    ])]);

    expect(integrationsUnlockedForCheck()->call('test', 'stripe.secret')->get('check'))->not->toBeNull();
});

it('opens the answer in a modal instead of leaving it at the foot of the page', function () {
    Http::fake(['api.stripe.com/v1/account' => Http::response([
        'id' => 'acct_1', 'settings' => ['dashboard' => ['display_name' => 'CluPilot']],
    ])]);

    integrationsUnlockedForCheck()
        ->call('test', 'stripe.secret')
        ->assertDispatched('openModal', function (string $event, array $params) {
            return $params['component'] === 'admin.check-result'
                && $params['arguments']['entryKey'] === 'stripe.secret'
                && is_array($params['arguments']['result']);
        });
});

it('shows the Stripe answer in that modal', function () {
    $result = [
        'ok' => true, 'account' => 'acct_1', 'business' => 'CluPilot',
        'live' => false, 'restricted' => false, 'webhooks' => [],
    ];

    Livewire::actingAs(operator('Owner'), 'operator')
        ->test(CheckResult::class, ['entryKey' => 'stripe.secret', 'result' => $result])
        ->assertOk()
        ->assertSee(__('secrets.check_webhooks_none'));
});

it('shows a DNS answer in that modal without reaching for Stripe fields', function () {
    // Der Ergebnisblock las `account`, `live`, `webhooks` — alles nur bei
    // Stripe vorhanden. Seit der DNS-Token einen eigenen Testknopf hat, kommt
    // hier auch ein DnsTokenCheck-Ergebnis an, und dessen Erfolg heisst
    // `writable`, läuft also in genau denselben Zweig.
    $result = ['ok' => true, 'reason' => 'writable', 'probe_removed' => true];

    Livewire::actingAs(operator('Owner'), 'operator')
        ->test(CheckResult::class, ['entryKey' => 'dns.token', 'result' => $result])
        ->assertOk()
        ->assertSee(__('secrets.check_writable'));
});

it('runs the DNS check against the value that was typed, not the stored one', function () {
    // Der Grund, warum das Ergebnis hereingereicht und nicht im Modal erhoben
    // wird: geprüft wird der EINGETIPPTE, noch nicht gespeicherte Token. Ein
    // Modal, das selbst prüfte, sähe ihn nicht — und DnsTokenCheck legte bei
    // jedem Öffnen einen neuen Probeeintrag in der echten Zone an.
    Settings::set('provisioning.dns_zone', 'probe.example');
    Http::fake([
        'api.hetzner.cloud/v1/zones' => Http::response(['zones' => [['id' => 42, 'name' => 'probe.example']]]),
        'api.hetzner.cloud/v1/zones/probe.example/rrsets' => Http::response(['rrset' => ['id' => 'x/TXT']], 201),
        'api.hetzner.cloud/v1/zones/probe.example/rrsets/*' => Http::response([], 201),
    ]);

    integrationsUnlockedForCheck()
        ->set('entered.dns_token', 'frisch-eingetippt')
        ->call('test', 'dns.token');

    Http::assertSent(fn ($request) => $request->hasHeader('Authorization', 'Bearer frisch-eingetippt'));
});

it('does not open the modal for somebody without the capability', function () {
    // Ein Modal ist OHNE die Route-Middleware der Seite erreichbar.
    Livewire::actingAs(operator('Support'), 'operator')
        ->test(CheckResult::class, ['entryKey' => 'stripe.secret', 'result' => ['ok' => true]])
        ->assertForbidden();
});
