<?php

use App\Actions\BookAddon;
use App\Actions\OpenSubscription;
use App\Models\Order;
use App\Models\Subscription;
use App\Models\SubscriptionAddon;
use App\Services\Billing\AddonCatalogue;
use App\Services\Billing\StorageAllowance;

/**
 * Wie groß ein gekaufter Block ist.
 *
 * Die Größe stand in der Konfiguration und wurde bei jeder Anzeige neu gelesen.
 * Solange sie sich nie bewegte, fiel das nicht auf; sie bewegt sich jetzt von
 * 100 GB auf 20 GB. Ein Block, dessen Größe erst zur Anzeigezeit entsteht, ist
 * kein gekauftes Gut, sondern eine Ansicht.
 */
function packContract(string $plan = 'team'): Subscription
{
    $order = Order::factory()->create(['plan' => $plan, 'datacenter' => 'fsn', 'status' => 'paid']);

    return app(OpenSubscription::class)($order);
}

it('friert die Packungsgröße auf der Buchung ein', function () {
    config(['provisioning.storage_addon.gb' => 100, 'provisioning.storage_addon.disk_gb' => 100]);

    $subscription = packContract();
    app(BookAddon::class)($subscription, AddonCatalogue::STORAGE, 1);

    // Der Betreiber schneidet das Paket neu zu.
    config(['provisioning.storage_addon.gb' => 20, 'provisioning.storage_addon.disk_gb' => 22]);

    $allowance = StorageAllowance::forPlan(85, $subscription->refresh());

    expect($allowance->packGb())->toBe(100)
        ->and($allowance->packDiskGb())->toBe(100)
        ->and($allowance->totalGb())->toBe(185);
});

it('bucht neue Blöcke zur heutigen Größe', function () {
    config(['provisioning.storage_addon.gb' => 20, 'provisioning.storage_addon.disk_gb' => 22]);

    $subscription = packContract();
    app(BookAddon::class)($subscription, AddonCatalogue::STORAGE, 2);

    $allowance = StorageAllowance::forPlan(30, $subscription->refresh());

    expect($allowance->packs)->toBe(2)
        ->and($allowance->packGb())->toBe(40)
        ->and($allowance->packDiskGb())->toBe(44);
});

it('lässt die eingefrorene Größe nicht nachträglich ändern', function () {
    config(['provisioning.storage_addon.gb' => 100, 'provisioning.storage_addon.disk_gb' => 100]);

    $subscription = packContract();
    $addon = app(BookAddon::class)($subscription, AddonCatalogue::STORAGE, 1);

    expect(fn () => $addon->update(['pack_gb' => 20]))
        ->toThrow(RuntimeException::class);

    expect(SubscriptionAddon::query()->whereKey($addon->id)->value('pack_gb'))->toBe(100);
});
