<?php // tests/Feature/Cancellation/CancelAsksAboutExportTest.php

use App\Livewire\ConfirmCancelPackage;
use App\Models\Customer;
use App\Models\Instance;
use App\Models\Order;
use App\Models\User;
use Livewire\Livewire;

/**
 * Abweichung vom Zettel: keine der drei Prüfungen unten setzt im Original
 * `reason`. Im Bestand verlangt ConfirmCancelPackage::cancelPackage() aber
 * schon länger einen gültigen Grund (Subscription::CANCEL_REASONS) und
 * bricht sonst VOR jeder Schreibaktion mit einem eigenen Fehler ab — das war
 * so, bevor diese Aufgabe begann, und diese Aufgabe ändert daran nichts. Ohne
 * `->set('reason', ...)` würde jede der drei Prüfungen an dieser
 * vorgelagerten Stelle scheitern, nicht an der Exportfrage, die hier geprüft
 * werden soll. Alle drei setzen deshalb zusätzlich einen gültigen Grund.
 */

/**
 * Ein aktives Paket, dessen Besitzer den Kündigungsdialog erreichen kann —
 * nach dem Muster von settingsSetup() (tests/Feature/SettingsTest.php) und
 * cancellablePackage() (tests/Feature/Billing/PackageCancellationTest.php):
 * Nutzer, Kunde, Bestellung, aktive Instanz. Bewusst OHNE eigenen
 * Subscription-Datensatz: ConfirmCancelPackage::contractFor() findet dann
 * keinen Vertrag, und stopBilling(null) gibt ungefragt true zurück (derselbe
 * Weg wie bei einem geschenkten Paket) — Stripe bleibt außen vor, weil es in
 * dieser Aufgabe ausschließlich um die Exportfrage geht.
 *
 * @return array{0: User, 1: Instance}
 */
function kuendbareInstanz(): array
{
    $user = User::factory()->create(['email' => 'kuendigt@example.test', 'email_verified_at' => now()]);

    $customer = Customer::factory()->create([
        'email' => 'kuendigt@example.test',
        'user_id' => $user->id,
        'status' => 'active',
    ]);

    $order = Order::factory()->create(['customer_id' => $customer->id, 'plan' => 'team']);

    $instance = Instance::factory()->create([
        'customer_id' => $customer->id,
        'order_id' => $order->id,
        'plan' => 'team',
        'status' => 'active',
        'subdomain' => 'kuendigt',
    ]);

    return [$user, $instance->refresh()];
}

it('schreibt die Antwort des Kunden an die Instanz', function () {
    [$user, $instance] = kuendbareInstanz();

    Livewire::actingAs($user)->test(ConfirmCancelPackage::class)
        ->set('confirmName', $instance->subdomain)
        ->set('reason', 'no_longer_needed')
        ->set('exportWish', true)
        ->call('cancelPackage')
        ->assertHasNoErrors();

    expect($instance->fresh()->export_wish)->toBeTrue();
});

it('nimmt auch ein Nein als Antwort — und nicht als fehlende Antwort', function () {
    // Das ist die Zusicherung, um die es geht: wer bewusst nein sagt, soll
    // nicht wie jemand behandelt werden, den niemand gefragt hat. Nur das
    // erspart ihm die Erinnerungen und uns die Arbeit.
    [$user, $instance] = kuendbareInstanz();

    Livewire::actingAs($user)->test(ConfirmCancelPackage::class)
        ->set('confirmName', $instance->subdomain)
        ->set('reason', 'no_longer_needed')
        ->set('exportWish', false)
        ->call('cancelPackage')
        ->assertHasNoErrors();

    expect($instance->fresh()->export_wish)->toBeFalse()
        ->and($instance->fresh()->export_wish)->not->toBeNull();
});

it('kündigt nicht ohne eine Antwort auf die Frage', function () {
    // Eine Frage, die man überspringen kann, ist keine Frage — und die
    // Kündigung ist der einzige Moment, in dem der Kunde ohnehin über seine
    // Daten nachdenkt.
    [$user, $instance] = kuendbareInstanz();

    Livewire::actingAs($user)->test(ConfirmCancelPackage::class)
        ->set('confirmName', $instance->subdomain)
        ->set('reason', 'no_longer_needed')
        ->call('cancelPackage')
        ->assertHasErrors('exportWish');

    expect($instance->fresh()->status)->toBe('active');
});
