<?php

namespace App\Livewire;

use App\Livewire\Concerns\ResolvesCustomer;
use App\Services\Billing\AddonCatalogue;
use App\Services\Billing\CustomDomainAccess;
use LivewireUI\Modal\ModalComponent;

/**
 * Confirmation before several storage packs go into the cart at once (R23).
 *
 * The offer comes from a card that has just told the customer their downgrade is
 * blocked, and it answers with a recurring charge — three packs is thirty euros
 * a month, every month, until they cancel them. That is not something a stray
 * click on a card about SAVING money should do, and the dialog that says so is
 * drawn by this product rather than by the browser.
 *
 * No mutation here. Billing::bookStoragePacks() keeps the work and the customer
 * resolution it already had; this only says yes, with the number it was opened
 * for.
 */
class ConfirmBookStorage extends ModalComponent
{
    use ResolvesCustomer;

    public int $packs = 1;

    public int $packGb = 0;

    /** Warum es hier nichts zu kaufen gibt. Leer, solange es etwas gibt. */
    public string $refusal = '';

    public function mount(int $packs = 1): void
    {
        $catalogue = app(AddonCatalogue::class);

        // Der eigene Vertrag, aufgelöst wie in jedem anderen Bestätigungs-Modal
        // (siehe ConfirmCancelAddon, ConfirmRevokeSeat) — nicht aus dem Markup
        // übernommen, denn ein Modal ist ohne die Middleware der Seite
        // erreichbar. Dieselbe Auflösung, die Billing::purchase() nachher
        // tatsächlich bucht (CustomDomainAccess::contractOf()): sonst könnte
        // der Dialog eine Zahl versprechen, die die Aktion nicht einhält.
        $subscription = app(CustomDomainAccess::class)->contractOf($this->customer());

        // Geklemmt an der tatsächlich noch buchbaren Menge, nicht an der
        // absoluten Grenze: ein Vertrag, der schon einen Block hält, darf im
        // Dialog nicht mehr versprechen, als purchase() nachher wirklich in
        // den Warenkorb legt.
        //
        // Kein `max(1, …)` mehr darum herum: bei null buchbaren Blöcken —
        // Deckel erreicht oder Modul für dieses Paket nicht vorgesehen — machte
        // das daraus wieder einen. Dieselbe Falle, die in purchase() schon
        // behoben ist ($lines floorte auf eine Bestellzeile), hatte im Fenster
        // überlebt: ein direkt geöffnetes oder veraltetes Fenster versprach
        // einen Block und schickte eine Bestellung los, die purchase() danach
        // ablehnt. Nach oben wird weiter geklemmt, nach unten nur noch auf
        // null.
        $max = $catalogue->bookableQuantity($subscription, AddonCatalogue::STORAGE);
        $this->packs = min($max, max(1, $packs));
        $this->packGb = $catalogue->packGb();

        // Absage statt geschlossenem Fenster: der Kunde hat gerade auf eine
        // Karte geklickt, die ihm diesen Ausweg angeboten hat, und ein Dialog,
        // der sich wortlos wieder schließt, ist von einem kaputten Knopf nicht
        // zu unterscheiden. In dem Satz, den er zu dieser Grenze überall sonst
        // liest — derselbe, mit dem purchase() und BookAddon ablehnen.
        $this->refusal = $this->packs > 0 ? '' : (string) (
            $catalogue->availabilityRefusal($subscription, AddonCatalogue::STORAGE)
            ?? $catalogue->quantityRefusal($subscription, AddonCatalogue::STORAGE, 1)
        );
    }

    public function proceed(): void
    {
        // Nichts buchbar, nichts losgeschickt — der Knopf, der hier ankommt,
        // ist bei einer Absage gar nicht gezeichnet. Die Menge steht in einer
        // öffentlichen Eigenschaft und damit im Browser, deshalb ist das hier
        // nicht die Grenze, sondern nur die Ehrlichkeit des Fensters: gehalten
        // wird sie in purchase() und in BookAddon, wo das Geld fließt.
        if ($this->packs < 1) {
            $this->closeModal();

            return;
        }

        $this->dispatch('storage-packs-confirmed', packs: $this->packs);
        $this->closeModal();
    }

    public function render()
    {
        return view('livewire.confirm-book-storage');
    }
}
