<?php

namespace App\Support;

use App\Support\Readiness\BillingChecks;
use App\Support\Readiness\Check;
use App\Support\Readiness\DeliveryChecks;
use App\Support\Readiness\OnboardingChecks;
use App\Support\Readiness\OperationChecks;
use App\Support\Readiness\SecurityChecks;
use App\Support\Readiness\ProvisioningChecks;

/**
 * Jedes Pflichtfeld dieser Installation an einer Stelle, gruppiert nach dem,
 * was es blockiert — nicht danach, wo der Wert gespeichert ist.
 *
 * Ein Betreiber, der eine Installation befüllt, denkt in „was kann ich noch
 * nicht", nicht in „liegt das im Tresor oder in den Einstellungen".
 *
 * Diese Klasse SPERRT NICHTS. Die harten Sperren bleiben, wo sie stehen —
 * IssueInvoice bei unvollständigen Firmendaten, VerifyVmTemplate bei fehlender
 * Vorlage, die Kasse bei fehlendem Stripe-Schlüssel. Eine Bereitschaftsseite,
 * die selbst sperrt, wäre eine zweite Wahrheit neben diesen Prüfungen.
 */
final class Readiness
{
    /**
     * Die Gruppen, angehängt. Jede Gruppe kennt nur ihre eigenen
     * Abhängigkeiten (Stripe, Proxmox, DNS, Mail) — eine Datei, die alle
     * Gruppen importiert, wäre in jedem einzelnen Gruppentest die ganze Welt.
     *
     * @return array<int, Check>
     */
    public static function all(): array
    {
        return [
            ...BillingChecks::all(),
            ...OnboardingChecks::all(),
            ...ProvisioningChecks::all(),
            ...DeliveryChecks::all(),
            ...OperationChecks::all(),
            ...SecurityChecks::all(),
        ];
    }

    /** @return array<int, Check> */
    public static function blocking(): array
    {
        return array_values(array_filter(self::all(), fn (Check $c) => $c->isBlocking()));
    }

    public static function isReady(): bool
    {
        return self::blocking() === [];
    }

    /** @return array<string, array<int, Check>> */
    public static function byGroup(): array
    {
        $grouped = [];

        foreach (self::all() as $check) {
            $grouped[$check->group][] = $check;
        }

        return $grouped;
    }
}
