<?php

namespace App\Livewire\Admin;

use App\Models\Host;
use App\Support\HostEnrolment;
use App\Support\HostTakeoverCommand;
use LivewireUI\Modal\ModalComponent;

/**
 * Stellt die Übernahme-Befehlszeile für einen bestehenden Host neu aus.
 *
 * Es gab sie bis hierher genau EINMAL: auf der Seite direkt nach dem Anlegen.
 * Wer sie dort nicht kopierte — oder wem sie wegbrach, wie beim
 * WireGuard-Fehler bis 1.3.80 — hatte danach einen Host in der Liste, für den
 * es keinen Weg zu einer Befehlszeile mehr gab. Ein zweites Anlegen scheitert
 * an der eindeutigen IP, also blieb nur Entfernen und von vorn.
 *
 * `HostTakeoverCommand` behauptet in seinem Kopfkommentar, die Zeile werde „an
 * zwei Stellen gezeigt (beim Anlegen und beim Neuausstellen eines Codes)". Das
 * Zweite gab es nie — ein Kommentar, der eine Absicht beschreibt und wie eine
 * Beschreibung des Gebauten klingt.
 *
 * Bestätigt wird VOR dem Ausstellen (R23), denn der bisherige Code wird dabei
 * wertlos: eine Maschine, die gerade im Rettungssystem arbeitet, verlöre ihren
 * Ausweis mitten im Lauf.
 */
class ReissueTakeover extends ModalComponent
{
    public string $uuid;

    public string $name = '';

    /** Null, solange nur gefragt wird. Gesetzt heißt: ausgestellt, hier steht sie. */
    public ?string $command = null;

    /** Gesetzt, wenn nicht ausgestellt wurde — und warum. */
    public ?string $refusal = null;

    /**
     * Nur vor der Übernahme: angelegt, mitten in der Übernahme, gescheitert.
     *
     * Für einen laufenden Host wäre eine neue Befehlszeile kein Angebot,
     * sondern eine Falle: sie setzt die Maschine neu auf.
     *
     * `disabled` gehört NICHT dazu, obwohl es danach aussieht (Codex P1).
     * Es ist der Wartungszustand eines längst laufenden Hosts —
     * `HostDetail::toggleMaintenance()` schaltet aktiv → disabled, um ihn aus
     * der Platzierung zu nehmen. Wer einen Host zum Warten stilllegt, bekäme
     * sonst einen Knopf angeboten, der seine Produktionsmaschine neu aufsetzt.
     */
    public const ELIGIBLE = ['pending', 'onboarding', 'error'];

    /**
     * Eine Stelle für die Bedingung, gefragt von der Ansicht UND von `issue()`.
     *
     * Zwei Fassungen davon liefen auseinander, sobald jemand eine ändert — und
     * die, die dann noch gilt, ist die in der Ansicht, also gar keine.
     */
    public static function eligible(Host $host): bool
    {
        return in_array($host->status, self::ELIGIBLE, true);
    }

    public function mount(string $uuid): void
    {
        $this->uuid = $uuid;
        $this->name = Host::query()->where('uuid', $uuid)->value('name') ?? '';
    }

    /**
     * Ein Modal ist ohne die Route-Middleware der Seite erreichbar (R20) und
     * prüft die Berechtigung deshalb selbst — hier besonders, weil in der
     * Antwort ein privater WireGuard-Schlüssel steht.
     */
    public function issue(): void
    {
        $this->authorize('hosts.manage');

        $host = Host::query()->where('uuid', $this->uuid)->firstOrFail();

        // Der Knopf steht nur bei passendem Zustand — aber ein Modal, das offen
        // blieb, während der Host aktiv wurde, ruft diese Methode trotzdem, und
        // eine Livewire-Methode ist ohnehin von außen aufrufbar. Die
        // Sichtbarkeit eines Knopfes ist keine Prüfung (Codex P1): sonst
        // tauschte das hier den Schlüssel einer laufenden Maschine und schnitte
        // sie aus dem Tunnel.
        if (! self::eligible($host)) {
            $this->refusal = __('hosts.reissue.not_eligible');

            return;
        }

        // Dieselbe Prüfung wie in der Ansicht, aus demselben Grund (Codex P2).
        // Sonst wird ein gültiger Code entwertet und dafür eine Zeile
        // ausgegeben, der die Tunnel-Angaben fehlen — genau die kaputte Zeile,
        // vor der die Warnung daneben steht.
        if (HostTakeoverCommand::missingSettings() !== []) {
            $this->refusal = __('hosts.takeover.missing_title');

            return;
        }

        $this->refusal = null;
        $this->command = HostTakeoverCommand::for($host, HostEnrolment::issueWithKeys($host));
    }

    public function render()
    {
        return view('livewire.admin.reissue-takeover', [
            'missingSettings' => HostTakeoverCommand::missingSettings(),
        ]);
    }
}
