<?php

namespace App\Livewire\Admin;

use App\Http\Middleware\RestrictConsoleNetwork;
use App\Models\Operator;
use App\Services\Terminal\ServerTicket;
use Livewire\Attributes\Layout;
use Livewire\Component;
use Throwable;

/**
 * Eine Root-Sitzung auf dem CluPilot-Server selbst, im eigenen Fenster.
 *
 * Dieselbe Bühne wie beim Host-Terminal, dieselbe Brücke, dasselbe Ticket —
 * und eine Tür, die enger ist, weil dahinter mehr liegt. Ein Host-Terminal
 * reicht auf eine Maschine; dieses reicht auf Datenbank, Tresor, DNS-Token und
 * jede Kundeninstanz.
 *
 * DIE REIHENFOLGE IN mount() IST DIE FUNKTION:
 *
 * 1. `server.terminal` — eine eigene Fähigkeit, nicht `hosts.manage`.
 * 2. Das Netz. Und zwar OHNE `RestrictConsoleNetwork::isRestricted()` zu
 *    fragen: dieser Schalter darf die Konsole öffnen, aber nicht diese Tür.
 *    Wer ihn aus gutem Grund umlegt — ausgesperrt, muss von unterwegs ran —,
 *    öffnete sonst still auch eine Root-Schale ins Herz der Anlage.
 * 3. Erst dann die Frage, ob überhaupt eine Sitzung entstehen kann.
 *
 * Und wie beim Host-Terminal: DIESE SEITE WIRFT NIE. Ein Terminalfenster, das
 * mit Laravels Fehlerseite aufgeht — Klassenname, Dateipfad, Zeilennummer —,
 * ist ein Bruch mitten im Produkt.
 *
 * Kein Routenparameter, also auch nicht die Falle, die den Host-Ableger eine
 * Umbenennung gekostet hat (Livewires ImplicitRouteBinding). Hier gibt es
 * nichts nachzuschlagen: der Server ist der, auf dem das hier läuft.
 */
#[Layout('layouts.bare')]
class ServerTerminal extends Component
{
    public string $ticket = '';

    /**
     * Warum hier kein Terminal entstehen kann — ein Merkwort, oder leer, wenn
     * nichts im Weg steht.
     */
    public string $problem = '';

    public function mount(): void
    {
        $this->authorize('server.terminal');

        if (! RestrictConsoleNetwork::allows((string) request()->ip())) {
            $this->problem = 'off_network';

            return;
        }

        /** @var Operator $operator */
        $operator = auth('operator')->user();

        // Der Fangzaun liegt um BEIDE Schritte, nicht nur um das Ausstellen.
        // `blocker()` liest den Tresor und eine Datei — beides kann auf eine
        // Weise scheitern, mit der niemand gerechnet hat, und ein Wurf dort
        // wäre genau die Laravel-Fehlerseite, die dieses Fenster nie zeigen
        // soll. Die Antwort ist dieselbe wie beim Ausstellen: eine gestaltete
        // Seite, ohne Versprechen, woran es lag.
        try {
            $this->problem = ServerTicket::blocker() ?? '';

            if ($this->problem === '') {
                $this->ticket = ServerTicket::issue($operator);
            }
        } catch (Throwable $e) {
            report($e);
            $this->problem = 'unknown';
        }
    }

    public function render()
    {
        return view('livewire.admin.server-terminal')
            ->title(__('server.terminal.window_title'));
    }
}
