<?php

use App\Actions\GrantAddon;
use App\Actions\OpenSubscription;
use App\Models\Operator;
use App\Models\Order;
use App\Models\Subscription;
use App\Services\Billing\AddonCatalogue;

/**
 * "Ein Plugin schenken" — a module given for free or at a discount, booked
 * through the same BookAddon a paid order uses.
 */
function subscriptionForGrant(): Subscription
{
    $order = Order::factory()->create(['plan' => 'team', 'datacenter' => 'fsn', 'status' => 'paid']);

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

it('books a module at zero cost, with provenance on the row', function () {
    $subscription = subscriptionForGrant();
    $owner = Operator::factory()->create();

    $addon = app(GrantAddon::class)(
        subscription: $subscription,
        grantedBy: $owner,
        addonKey: 'priority_support',
        priceCents: 0,
        note: 'Entschuldigung für die Störung',
    );

    $catalogue = app(AddonCatalogue::class)->priceCents('priority_support');

    expect($addon->price_cents)->toBe(0)
        ->and($addon->isGranted())->toBeTrue()
        ->and($addon->granted_by)->toBe($owner->id)
        ->and($addon->grant_note)->toBe('Entschuldigung für die Störung')
        ->and($addon->catalogue_price_cents)->toBe($catalogue)
        ->and($addon->order->stripe_event_id)->toBeNull()
        ->and($addon->order->amount_cents)->toBe(0);
});

it('books a discounted module below the catalogue price', function () {
    $subscription = subscriptionForGrant();
    $owner = Operator::factory()->create();
    $catalogue = app(AddonCatalogue::class)->priceCents('collabora_pro');

    $addon = app(GrantAddon::class)(
        subscription: $subscription,
        grantedBy: $owner,
        addonKey: 'collabora_pro',
        priceCents: $catalogue - 500,
    );

    expect($addon->price_cents)->toBe($catalogue - 500)
        ->and($addon->isGranted())->toBeTrue();
});

it('refuses to charge more for a granted module than it actually costs', function () {
    $subscription = subscriptionForGrant();
    $owner = Operator::factory()->create();
    $catalogue = app(AddonCatalogue::class)->priceCents('extra_backups');

    expect(fn () => app(GrantAddon::class)(
        subscription: $subscription,
        grantedBy: $owner,
        addonKey: 'extra_backups',
        priceCents: $catalogue + 1,
    ))->toThrow(RuntimeException::class);
});
