@props([
    // [[route, icon, translation key], …] or [['label' => …, 'items' => [...]], …]
    'groups',
    // dot-prefix for the labels, e.g. 'dashboard.nav' or 'admin.nav'
    'prefix',
    // console routes are matched through AdminArea so recovery hostnames still
    // highlight; the portal uses the router directly
    'console' => false,
    'footer' => null,
])
@php
    // Die Zahlen fuer den Block „Braucht dich". Einmal je Seitenaufruf geholt,
    // nicht je Eintrag — und dahinter ein Zwischenspeicher, weil diese Leiste
    // auf JEDER Konsolenseite rendert. Das Portal hat keine, dort bleibt es
    // ein leeres Feld ohne Abfrage.
    $counts = $console ? \App\Support\Navigation::attentionCounts() : [];
@endphp
{{--
    The sidebar, shared by both shells.

    Light, like everything else. The console used to be dark, which made it a
    second product: two ideas of what a card is, two oranges, two status
    palettes. What actually differs between an operator and a customer is
    density, and that lives in the tokens — not here.
--}}
<aside
    class="fixed inset-y-0 left-0 z-50 flex w-[15.5rem] flex-col border-r border-line bg-surface px-3 py-4 shadow-md transition-transform lg:static lg:h-screen lg:translate-x-0 lg:shadow-none"
    :class="nav ? 'translate-x-0' : '-translate-x-full'"
>
    <div class="flex shrink-0 items-center justify-between gap-2 px-2.5 pb-5">
        <a href="{{ $console ? \App\Support\AdminArea::home() : route('dashboard') }}" class="flex items-center gap-2.5">
            <x-ui.brand :size="$console ? 'sm' : 'md'" />
            @if ($console)
                <span class="rounded-sm bg-accent-subtle px-1.5 py-0.5 font-mono text-[9.5px] font-semibold uppercase tracking-[0.1em] text-accent-text">{{ __('admin.badge') }}</span>
            @endif
        </a>
        <button type="button" class="lg:hidden -mr-1 inline-flex min-h-11 min-w-11 items-center justify-center rounded text-muted"
                @click="nav = false" aria-label="{{ __('dashboard.close_nav') }}">
            <x-ui.icon name="x" />
        </button>
    </div>

    {{-- The only scroll region in the sidebar: header above and footer below
         stay put (operator requirement), only the nav list itself scrolls
         when it is taller than the viewport. overflow-y-auto (not -hidden)
         on a flex-1 child resolves its automatic min-height to 0, which is
         what lets it shrink to the available space instead of stretching the
         aside past the viewport — same mechanism <main> already relies on. --}}
    <div class="min-h-0 flex-1 overflow-y-auto">
        @foreach ($groups as $group)
            @php
                // Sichtbarkeit EINMAL je Gruppe entscheiden, nicht erst je
                // Eintrag. Vorher wurde die Überschrift bedingungslos gedruckt
                // und stand deshalb auch über einer Gruppe, von der dieser
                // Betreiber keinen einzigen Eintrag sehen darf — eine
                // Überschrift mit nichts darunter liest sich wie ein
                // Ladefehler, nicht wie eine Berechtigung.
                //
                // Bis zur Neuordnung der Konsolen-Navigation fiel das nicht
                // auf, weil jede Gruppe mindestens einen ungeschützten Eintrag
                // trug. „Post" tut das nicht.
                //
                // $capability ist ein einzelner Fähigkeitsname, ein Array von
                // Namen im Sinne von „irgendeine davon" (App\Support\Navigation
                // hält fest, welche Einträge das benutzen), oder null für
                // „alle". Laravels eigenes can() liest ein Array als „alle
                // davon" — die falsche Logik für einen Eintrag, den man mit
                // der einen ODER der anderen Fähigkeit erreicht. Daher die
                // ausgeschriebene Verzweigung statt eines bloßen ->can().
                $visible = collect($group['items'])->filter(function (array $item) {
                    $capability = $item[3];

                    if ($capability === null) {
                        return true;
                    }

                    return is_array($capability)
                        ? collect($capability)->contains(fn ($one) => auth()->user()?->can($one))
                        : (bool) auth()->user()?->can($capability);
                });
            @endphp
            @continue($visible->isEmpty())
            @if (! empty($group['label']))
                <p class="px-3 pb-2 pt-5 lbl">{{ $group['label'] }}</p>
            @endif
            <nav class="space-y-0.5">
                @foreach ($visible as $item)
                    @php
                        [$route, $icon, $key] = $item;
                        // Fuenftes Feld, optional: der Schluessel, unter dem
                        // Navigation::attentionCounts() die Zahl fuehrt. Als
                        // Index gelesen statt destrukturiert — das Portal hat
                        // vier Felder je Eintrag, und eine Destrukturierung auf
                        // fuenf warnte dort bei jedem einzelnen.
                        $count = isset($item[4]) ? ($counts[$item[4]] ?? 0) : 0;
                    @endphp
                    <x-ui.nav-item
                        :href="route($route)"
                        :active="\App\Support\Navigation::isCurrent($route, $console)"
                        @click="nav = false"
                    >
                        <x-slot:icon><x-ui.icon :name="$icon" class="size-[1.15rem]" /></x-slot:icon>
                        {{ __($prefix.'.'.$key) }}
                        {{-- Bei null KEINE Plakette, der Eintrag bleibt aber
                             stehen: eine Seite, die verschwindet, sobald nichts
                             offen ist, ist genau dann nicht erreichbar, wenn man
                             nachsehen will, ob wirklich nichts offen ist. --}}
                        @if ($count > 0)
                            <x-slot:badge>
                                <span class="rounded-pill bg-accent px-2 py-0.5 text-xs font-semibold text-on-accent">{{ $count }}</span>
                            </x-slot:badge>
                        @endif
                    </x-ui.nav-item>
                @endforeach
            </nav>
        @endforeach
    </div>

    {{-- Die laufende Version — und, wenn es eine neuere gibt, dass es sie gibt.
         Sie stand hier schon, aber als toter Text: die Seite, auf der man
         etwas damit tun kann, liegt seit dem Umbau der Leiste im
         Einrichtungsbereich. Der Betreiber hat genau das gemeldet — „man sieht
         es nicht, ohne genau hinzuklicken".

         Also bleibt die Zeile, wo sie war, und wird zum Weg dorthin. Ist etwas
         verfuegbar, sagt sie es in der Akzentfarbe statt in Grau; ist nichts
         verfuegbar, bleibt sie so leise wie vorher. Eine Zeile, die immer
         ruft, ruft nie. --}}
    @if ($footer)
        @php $updateWaiting = ($counts['update'] ?? 0) > 0; @endphp
        @if ($console)
            <a href="{{ route('admin.settings') }}?tab=installation"
               @class([
                   'shrink-0 rounded px-3 py-2 mt-6 block font-mono text-[11px] leading-relaxed transition-colors',
                   'bg-accent-subtle text-accent-text hover:bg-accent-subtle/70' => $updateWaiting,
                   'text-muted hover:text-ink hover:bg-surface-hover' => ! $updateWaiting,
               ])>
                {{ $footer }}
                @if ($updateWaiting)
                    <span class="mt-0.5 block font-sans font-semibold">{{ __('admin.nav_update_waiting') }}</span>
                @endif
            </a>
        @else
            <p class="shrink-0 px-3 pt-6 font-mono text-[11px] leading-relaxed text-muted">{{ $footer }}</p>
        @endif
    @endif
</aside>

{{-- Backdrop. Tapping it closes the drawer, which is the behaviour every
     phone user tries first. --}}
<div x-show="nav" x-cloak @click="nav = false" class="fixed inset-0 z-40 bg-[color-mix(in_srgb,var(--plate)_42%,transparent)] lg:hidden"></div>
