<x-app-layout>

    <x-module-hero title="Assign Permissions" description="Right-click any permission to assign or revoke it from roles. Permissions are grouped by module." icon="fa-key">
        <x-slot name="tabs">
            @can('view users')
            <a href="{{ route('users.index') }}"
               class="module-hero-tab {{ request()->routeIs('users.index') ? 'border-b-2 border-[#1e293b]' : 'opacity-70 hover:opacity-100 transition-opacity' }}
                      inline-flex items-center gap-2 px-4 py-3 text-[#1e293b] text-sm font-medium
                      md:w-auto w-full border-b border-[#cbd5e1] md:border-b-0">
                <i class="fas fa-users text-sm"></i> All Users
            </a>
            @endcan
            @role('Super Manager')
            <a href="{{ route('roles.index') }}"
               class="module-hero-tab {{ request()->routeIs('roles.index') ? 'border-b-2 border-[#1e293b]' : 'opacity-70 hover:opacity-100 transition-opacity' }}
                      inline-flex items-center gap-2 px-4 py-3 text-[#1e293b] text-sm font-medium
                      md:w-auto w-full border-b border-[#cbd5e1] md:border-b-0">
                <i class="fas fa-user-tag text-sm"></i> Roles
            </a>
            <a href="{{ route('roles.assign') }}"
               class="module-hero-tab {{ request()->routeIs('roles.assign') ? 'border-b-2 border-[#1e293b]' : 'opacity-70 hover:opacity-100 transition-opacity' }}
                      inline-flex items-center gap-2 px-4 py-3 text-[#1e293b] text-sm font-medium
                      md:w-auto w-full border-b border-[#cbd5e1] md:border-b-0">
                <i class="fas fa-key text-sm"></i> Assign Permissions
            </a>
            @endrole
            @can('manage themes')
            <a href="{{ route('admin.themes.index') }}"
               class="module-hero-tab {{ request()->routeIs('admin.themes.index') ? 'border-b-2 border-[#1e293b]' : 'opacity-70 hover:opacity-100 transition-opacity' }}
                      inline-flex items-center gap-2 px-4 py-3 text-[#1e293b] text-sm font-medium
                      md:w-auto w-full border-b border-[#cbd5e1] md:border-b-0">
                <i class="fas fa-palette text-sm"></i> Themes
            </a>
            @endcan
        </x-slot>
    </x-module-hero>

    {{-- Pass PHP data to Alpine via JSON --}}
    @php
        $rolesJson = $roles->map(fn($r) => [
            'id'    => $r->id,
            'name'  => $r->name,
            'theme' => $r->theme ?? 'default',
            'count' => $r->permissions->count(),
            'permIds' => $r->permissions->pluck('id')->toArray(),
        ])->values()->toJson();

        $permRoleMapJson = collect($permissionRoleMap)->toJson();
    @endphp

    <div class="p-4 md:p-6" x-data="permissionAssignment({{ $rolesJson }}, {{ $permRoleMapJson }})">

        {{-- Toast notification --}}
        <div x-show="toast.show"
             x-transition:enter="transition ease-out duration-300"
             x-transition:enter-start="opacity-0 translate-y-2"
             x-transition:enter-end="opacity-100 translate-y-0"
             x-transition:leave="transition ease-in duration-200"
             x-transition:leave-start="opacity-100 translate-y-0"
             x-transition:leave-end="opacity-0 translate-y-2"
             :class="toast.type === 'success' ? 'bg-green-600' : 'bg-red-600'"
             class="fixed bottom-6 right-6 z-[9999] flex items-center gap-3 px-5 py-3 rounded-xl shadow-2xl text-white text-sm font-medium"
             style="display:none;">
            <i :class="toast.type === 'success' ? 'fas fa-check-circle' : 'fas fa-exclamation-circle'"></i>
            <span x-text="toast.message"></span>
        </div>

        {{-- Right-click context menu --}}
        <div x-show="ctxMenu.show"
             x-transition:enter="transition ease-out duration-150"
             x-transition:enter-start="opacity-0 scale-95"
             x-transition:enter-end="opacity-100 scale-100"
             x-transition:leave="transition ease-in duration-100"
             x-transition:leave-start="opacity-100 scale-100"
             x-transition:leave-end="opacity-0 scale-95"
             :style="`position:fixed; top:${ctxMenu.y}px; left:${ctxMenu.x}px; z-index:9998;`"
             @click.outside="ctxMenu.show = false"
             @keydown.escape.window="ctxMenu.show = false"
             class="bg-white rounded-xl shadow-2xl border border-gray-200 overflow-hidden min-w-[220px] max-w-[280px]"
             style="display:none;">
            {{-- Context menu header --}}
            <div class="px-4 py-3 bg-gradient-to-r from-slate-700 to-slate-800 text-white">
                <p class="text-xs font-semibold uppercase tracking-wider text-slate-300 mb-0.5">Assign to Role</p>
                <p class="text-sm font-bold truncate" x-text="ctxMenu.permName"></p>
            </div>
            {{-- Role list --}}
            <div class="py-1 max-h-72 overflow-y-auto">
                <template x-for="role in roles" :key="role.id">
                    <button
                        @click="togglePermission(ctxMenu.permId, role.id)"
                        :disabled="isLoading"
                        :class="hasPermission(ctxMenu.permId, role.id)
                            ? 'opacity-50 cursor-not-allowed bg-gray-50'
                            : 'hover:bg-blue-50 cursor-pointer'"
                        class="w-full flex items-center justify-between px-4 py-2.5 text-sm transition-colors duration-150 text-left">
                        <span class="flex items-center gap-2.5">
                            <span class="w-2 h-2 rounded-full flex-shrink-0"
                                  :class="getRoleColor(role.theme)"></span>
                            <span class="font-medium text-gray-800" x-text="role.name"></span>
                        </span>
                        <span x-show="hasPermission(ctxMenu.permId, role.id)"
                              class="flex items-center gap-1 text-xs text-green-600 font-semibold">
                            <i class="fas fa-check-circle"></i> Assigned
                        </span>
                        <span x-show="!hasPermission(ctxMenu.permId, role.id)"
                              class="text-xs text-blue-500 font-medium">
                            + Assign
                        </span>
                    </button>
                </template>
            </div>
            <div class="border-t border-gray-100 px-4 py-2 bg-gray-50">
                <p class="text-xs text-gray-400 italic">Click an assigned role to revoke</p>
            </div>
        </div>


        {{-- ================================================================ --}}
        {{-- TOP STATS BAR --}}
        {{-- ================================================================ --}}
        <div class="grid grid-cols-2 md:grid-cols-4 gap-3 mb-6">
            <div class="bg-white rounded-xl border border-gray-200 shadow-sm p-4 flex items-center gap-3">
                <div class="w-10 h-10 rounded-lg bg-blue-100 flex items-center justify-center flex-shrink-0">
                    <i class="fas fa-user-tag text-blue-600"></i>
                </div>
                <div>
                    <p class="text-xs text-gray-500 font-medium">Total Roles</p>
                    <p class="text-xl font-bold text-gray-900">{{ $roles->count() }}</p>
                </div>
            </div>
            <div class="bg-white rounded-xl border border-gray-200 shadow-sm p-4 flex items-center gap-3">
                <div class="w-10 h-10 rounded-lg bg-green-100 flex items-center justify-center flex-shrink-0">
                    <i class="fas fa-key text-green-600"></i>
                </div>
                <div>
                    <p class="text-xs text-gray-500 font-medium">Total Permissions</p>
                    <p class="text-xl font-bold text-gray-900">{{ \Spatie\Permission\Models\Permission::count() }}</p>
                </div>
            </div>
            <div class="bg-white rounded-xl border border-gray-200 shadow-sm p-4 flex items-center gap-3">
                <div class="w-10 h-10 rounded-lg bg-purple-100 flex items-center justify-center flex-shrink-0">
                    <i class="fas fa-layer-group text-purple-600"></i>
                </div>
                <div>
                    <p class="text-xs text-gray-500 font-medium">Modules</p>
                    <p class="text-xl font-bold text-gray-900">{{ $permissions->count() }}</p>
                </div>
            </div>
            <div class="bg-white rounded-xl border border-gray-200 shadow-sm p-4 flex items-center gap-3">
                <div class="w-10 h-10 rounded-lg bg-amber-100 flex items-center justify-center flex-shrink-0">
                    <i class="fas fa-circle-info text-amber-600"></i>
                </div>
                <div>
                    <p class="text-xs text-gray-500 font-medium">How to use</p>
                    <p class="text-xs font-semibold text-gray-700">Right-click any permission</p>
                </div>
            </div>
        </div>


        {{-- ================================================================ --}}
        {{-- ROLE SUMMARY CARDS --}}
        {{-- ================================================================ --}}
        <div class="mb-6">
            <h2 class="text-sm font-bold text-gray-700 uppercase tracking-wider mb-3 flex items-center gap-2">
                <i class="fas fa-user-tag text-blue-500"></i> Roles Overview
            </h2>
            <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3">
                @foreach($roles as $role)
                @php
                    $themeColors = [
                        'midnight-dark'  => ['bg' => 'bg-slate-800',  'text' => 'text-white',      'badge' => 'bg-slate-600'],
                        'ocean-blue'     => ['bg' => 'bg-sky-600',    'text' => 'text-white',      'badge' => 'bg-sky-400'],
                        'arctic-white'   => ['bg' => 'bg-gray-100',   'text' => 'text-gray-800',   'badge' => 'bg-gray-300'],
                        'desert-sand'    => ['bg' => 'bg-amber-600',  'text' => 'text-white',      'badge' => 'bg-amber-400'],
                        'forest-green'   => ['bg' => 'bg-emerald-600','text' => 'text-white',      'badge' => 'bg-emerald-400'],
                        'royal-purple'   => ['bg' => 'bg-violet-700', 'text' => 'text-white',      'badge' => 'bg-violet-500'],
                        'sunset-orange'  => ['bg' => 'bg-orange-500', 'text' => 'text-white',      'badge' => 'bg-orange-300'],
                        'corporate-gray' => ['bg' => 'bg-slate-500',  'text' => 'text-white',      'badge' => 'bg-slate-400'],
                        'cherry-blossom' => ['bg' => 'bg-pink-500',   'text' => 'text-white',      'badge' => 'bg-pink-300'],
                        'crimson-red'    => ['bg' => 'bg-red-600',    'text' => 'text-white',      'badge' => 'bg-red-400'],
                        'default'        => ['bg' => 'bg-gray-600',   'text' => 'text-white',      'badge' => 'bg-gray-400'],
                    ];
                    $tc = $themeColors[$role->theme ?? 'default'] ?? $themeColors['default'];
                @endphp
                <div class="rounded-xl overflow-hidden shadow-sm border border-gray-200 hover:shadow-md transition-shadow">
                    <div class="{{ $tc['bg'] }} {{ $tc['text'] }} px-3 py-2.5">
                        <p class="font-bold text-sm truncate">{{ $role->name }}</p>
                        <p class="text-xs opacity-75 capitalize">{{ str_replace('-', ' ', $role->theme ?? 'default') }}</p>
                    </div>
                    <div class="bg-white px-3 py-2 flex items-center justify-between">
                        <span class="text-xs text-gray-500">Permissions</span>
                        <span class="text-sm font-bold text-gray-800">{{ $role->permissions->count() }}</span>
                    </div>
                    {{-- Theme selector --}}
                    <form method="POST" action="{{ route('roles.update', $role) }}" class="border-t border-gray-100">
                        @csrf
                        @method('PUT')
                        <select name="theme"
                            class="w-full px-2 py-1.5 text-xs border-0 bg-gray-50 text-gray-700 focus:ring-1 focus:ring-blue-400 cursor-pointer"
                            onchange="this.form.submit()"
                            title="Change theme for {{ $role->name }}">
                            @foreach($themes as $theme)
                                <option value="{{ $theme->slug }}" {{ ($role->theme ?? '') === $theme->slug ? 'selected' : '' }}>
                                    {{ $theme->name }}
                                </option>
                            @endforeach
                        </select>
                    </form>
                </div>
                @endforeach
            </div>
        </div>


        {{-- ================================================================ --}}
        {{-- SEARCH + FILTER BAR --}}
        {{-- ================================================================ --}}
        <div class="bg-white rounded-xl border border-gray-200 shadow-sm p-4 mb-5 flex flex-col sm:flex-row gap-3 items-start sm:items-center">
            <div class="relative flex-1">
                <i class="fas fa-search absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-sm"></i>
                <input type="text"
                       x-model="search"
                       placeholder="Search permissions..."
                       class="w-full pl-9 pr-4 py-2 border border-gray-300 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent">
            </div>
            <div class="flex items-center gap-2 flex-wrap">
                <button @click="filterRole = null"
                        :class="filterRole === null ? 'bg-slate-700 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'"
                        class="px-3 py-1.5 rounded-lg text-xs font-semibold transition-colors">
                    All
                </button>
                <template x-for="role in roles" :key="role.id">
                    <button @click="filterRole = (filterRole === role.id ? null : role.id)"
                            :class="filterRole === role.id ? 'text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'"
                            :style="filterRole === role.id ? `background:${getRoleHex(role.theme)}` : ''"
                            class="px-3 py-1.5 rounded-lg text-xs font-semibold transition-colors"
                            x-text="role.name">
                    </button>
                </template>
            </div>
            <div class="flex items-center gap-2 text-xs text-gray-500 flex-shrink-0">
                <button @click="expandAll = !expandAll"
                        class="flex items-center gap-1.5 px-3 py-1.5 bg-gray-100 hover:bg-gray-200 rounded-lg font-medium transition-colors">
                    <i :class="expandAll ? 'fas fa-compress-alt' : 'fas fa-expand-alt'"></i>
                    <span x-text="expandAll ? 'Collapse All' : 'Expand All'"></span>
                </button>
            </div>
        </div>


        {{-- ================================================================ --}}
        {{-- PERMISSIONS GROUPED BY MODULE --}}
        {{-- ================================================================ --}}
        <div class="space-y-4">
            @foreach($permissions as $module => $modulePermissions)
            @php
                [$moduleGroup, $moduleLabel] = str_contains($module, ' › ')
                    ? explode(' › ', $module, 2)
                    : [$module, $module];

                $moduleIcons = [
                    'Administration'         => 'fa-shield-halved text-slate-600',
                    'Membership & Loans'     => 'fa-id-card text-blue-600',
                    'Health Directory'       => 'fa-hospital text-teal-600',
                    'Payments'               => 'fa-credit-card text-green-600',
                    'Training'               => 'fa-chalkboard-user text-orange-600',
                    'Mentorship'             => 'fa-people-arrows text-purple-600',
                    'Research & Advocacy'    => 'fa-flask text-indigo-600',
                    'Partnership'            => 'fa-handshake text-cyan-600',
                    'Knowledge Sharing'      => 'fa-lightbulb text-yellow-600',
                    'Communication'          => 'fa-envelope text-pink-600',
                    'System Config'          => 'fa-gear text-gray-600',
                    'Organization & Governance' => 'fa-building text-emerald-600',
                    'Content Management'     => 'fa-file-alt text-rose-600',
                    'Self-Paced Learning'    => 'fa-graduation-cap text-violet-600',
                    'General'                => 'fa-circle-dot text-gray-500',
                ];
                $iconClass = $moduleIcons[$moduleGroup] ?? 'fa-circle-dot text-gray-500';
            @endphp

            <div class="bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden"
                 x-show="isModuleVisible('{{ addslashes($module) }}')"
                 x-data="{ open: true }"
                 x-init="$watch('$root.expandAll', val => open = val)"
                 :class="{ 'ring-2 ring-blue-300': filterRole !== null }">

                {{-- Module header --}}
                <button @click="open = !open"
                        class="w-full flex items-center justify-between px-5 py-3.5 bg-gradient-to-r from-gray-50 to-white hover:from-gray-100 transition-colors text-left border-b border-gray-100">
                    <div class="flex items-center gap-3">
                        <div class="w-8 h-8 rounded-lg bg-white shadow-sm border border-gray-200 flex items-center justify-center flex-shrink-0">
                            <i class="fas {{ $iconClass }} text-sm"></i>
                        </div>
                        <div>
                            <span class="text-xs font-semibold text-gray-400 uppercase tracking-wider">{{ $moduleGroup }}</span>
                            <h3 class="text-sm font-bold text-gray-800 leading-tight">{{ $moduleLabel }}</h3>
                        </div>
                    </div>
                    <div class="flex items-center gap-3">
                        <span class="px-2.5 py-0.5 bg-gray-100 text-gray-600 rounded-full text-xs font-semibold">
                            {{ $modulePermissions->count() }} permissions
                        </span>
                        <i class="fas fa-chevron-down text-gray-400 text-xs transition-transform duration-200"
                           :class="open ? 'rotate-180' : ''"></i>
                    </div>
                </button>

                {{-- Permissions grid --}}
                <div x-show="open" x-transition:enter="transition ease-out duration-200"
                     x-transition:enter-start="opacity-0 -translate-y-1"
                     x-transition:enter-end="opacity-100 translate-y-0">
                    <div class="p-4 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-2">
                        @foreach($modulePermissions as $permission)
                        <div
                            x-show="isPermissionVisible({{ $permission->id }}, '{{ addslashes($permission->name) }}')"
                            @contextmenu.prevent="openCtxMenu($event, {{ $permission->id }}, '{{ addslashes($permission->name) }}')"
                            @click="openCtxMenu($event, {{ $permission->id }}, '{{ addslashes($permission->name) }}')"
                            :class="getPermissionCardClass({{ $permission->id }})"
                            class="group relative flex items-start gap-2 p-2.5 rounded-lg border cursor-pointer select-none transition-all duration-150 hover:shadow-md"
                            title="Click or right-click to assign/revoke roles">

                            {{-- Assignment indicator dots --}}
                            <div class="flex flex-col gap-0.5 mt-0.5 flex-shrink-0">
                                <template x-for="role in getRolesForPermission({{ $permission->id }})" :key="role.id">
                                    <span class="w-2 h-2 rounded-full flex-shrink-0"
                                          :class="getRoleColor(role.theme)"
                                          :title="role.name"></span>
                                </template>
                                <span x-show="getRolesForPermission({{ $permission->id }}).length === 0"
                                      class="w-2 h-2 rounded-full bg-gray-200 flex-shrink-0"></span>
                            </div>

                            <div class="flex-1 min-w-0">
                                <p class="text-xs font-semibold text-gray-800 leading-tight truncate">{{ $permission->name }}</p>
                                <p class="text-[10px] text-gray-400 mt-0.5" x-text="getAssignmentLabel({{ $permission->id }})"></p>
                            </div>

                            {{-- Hover action hint --}}
                            <div class="absolute inset-0 rounded-lg flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity bg-blue-600/10 pointer-events-none">
                                <i class="fas fa-mouse-pointer text-blue-600 text-xs"></i>
                            </div>
                        </div>
                        @endforeach
                    </div>
                </div>
            </div>
            @endforeach
        </div>

        {{-- No results message --}}
        <div x-show="noResults()" class="text-center py-16 text-gray-400">
            <i class="fas fa-search text-4xl mb-3"></i>
            <p class="text-lg font-semibold">No permissions found</p>
            <p class="text-sm">Try a different search term or clear the filter</p>
        </div>

    </div>{{-- end x-data --}}


    {{-- ================================================================ --}}
    {{-- LEGEND --}}
    {{-- ================================================================ --}}
    <div class="mx-4 md:mx-6 mb-6 bg-white rounded-xl border border-gray-200 shadow-sm p-4">
        <h4 class="text-xs font-bold text-gray-500 uppercase tracking-wider mb-3">Role Color Legend</h4>
        <div class="flex flex-wrap gap-3">
            @foreach($roles as $role)
            @php
                $dotColors = [
                    'midnight-dark'  => 'bg-slate-800',
                    'ocean-blue'     => 'bg-sky-500',
                    'arctic-white'   => 'bg-gray-400',
                    'desert-sand'    => 'bg-amber-500',
                    'forest-green'   => 'bg-emerald-500',
                    'royal-purple'   => 'bg-violet-600',
                    'sunset-orange'  => 'bg-orange-500',
                    'corporate-gray' => 'bg-slate-500',
                    'cherry-blossom' => 'bg-pink-500',
                    'crimson-red'    => 'bg-red-600',
                    'default'        => 'bg-gray-500',
                ];
                $dot = $dotColors[$role->theme ?? 'default'] ?? 'bg-gray-500';
            @endphp
            <div class="flex items-center gap-1.5">
                <span class="w-3 h-3 rounded-full {{ $dot }}"></span>
                <span class="text-xs text-gray-600 font-medium">{{ $role->name }}</span>
                <span class="text-xs text-gray-400">({{ $role->permissions->count() }})</span>
            </div>
            @endforeach
        </div>
    </div>


    @push('scripts')
    <script>
    function permissionAssignment(rolesData, permRoleMapData) {
        return {
            roles: rolesData,
            permRoleMap: permRoleMapData,  // { permId: [roleId, ...] }
            search: '',
            filterRole: null,
            expandAll: true,
            isLoading: false,
            ctxMenu: { show: false, x: 0, y: 0, permId: null, permName: '' },
            toast: { show: false, message: '', type: 'success', timer: null },

            // ── Context menu ──────────────────────────────────────────────
            openCtxMenu(event, permId, permName) {
                const vw = window.innerWidth;
                const vh = window.innerHeight;
                let x = event.clientX;
                let y = event.clientY;
                // Keep menu inside viewport (approximate menu size 240×320)
                if (x + 260 > vw) x = vw - 270;
                if (y + 340 > vh) y = vh - 350;
                this.ctxMenu = { show: true, x, y, permId, permName };
            },

            // ── Permission state ──────────────────────────────────────────
            hasPermission(permId, roleId) {
                const assigned = this.permRoleMap[permId] || [];
                return assigned.includes(roleId);
            },

            getRolesForPermission(permId) {
                const assigned = this.permRoleMap[permId] || [];
                return this.roles.filter(r => assigned.includes(r.id));
            },

            getAssignmentLabel(permId) {
                const count = (this.permRoleMap[permId] || []).length;
                if (count === 0) return 'Not assigned';
                if (count === 1) return '1 role';
                return count + ' roles';
            },

            getPermissionCardClass(permId) {
                const count = (this.permRoleMap[permId] || []).length;
                if (count === 0) return 'border-gray-200 bg-gray-50 hover:border-blue-300 hover:bg-blue-50';
                if (count >= this.roles.length) return 'border-green-300 bg-green-50 hover:border-green-400';
                return 'border-blue-200 bg-blue-50 hover:border-blue-400';
            },

            // ── Toggle (assign / revoke) ──────────────────────────────────
            async togglePermission(permId, roleId) {
                if (this.isLoading) return;
                const alreadyAssigned = this.hasPermission(permId, roleId);
                this.ctxMenu.show = false;
                this.isLoading = true;

                const url    = alreadyAssigned
                    ? `/roles/${roleId}/permissions/remove`
                    : `/roles/${roleId}/permissions/assign`;
                const method = alreadyAssigned ? 'DELETE' : 'POST';

                try {
                    const resp = await fetch(url, {
                        method,
                        headers: {
                            'Content-Type': 'application/json',
                            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
                            'Accept': 'application/json',
                        },
                        body: JSON.stringify({ permission_id: permId }),
                    });

                    if (!resp.ok) throw new Error('HTTP ' + resp.status);
                    const data = await resp.json();

                    if (data.success) {
                        // Update local state without page reload
                        if (alreadyAssigned) {
                            this.permRoleMap[permId] = (this.permRoleMap[permId] || []).filter(id => id !== roleId);
                            // Update role count
                            const role = this.roles.find(r => r.id === roleId);
                            if (role) role.count = Math.max(0, role.count - 1);
                        } else {
                            if (!this.permRoleMap[permId]) this.permRoleMap[permId] = [];
                            this.permRoleMap[permId].push(roleId);
                            const role = this.roles.find(r => r.id === roleId);
                            if (role) role.count++;
                        }
                        this.showToast(
                            alreadyAssigned ? 'Permission revoked successfully' : 'Permission assigned successfully',
                            'success'
                        );
                    } else {
                        this.showToast(data.message || 'Operation failed', 'error');
                    }
                } catch (err) {
                    console.error(err);
                    this.showToast('Network error — please try again', 'error');
                } finally {
                    this.isLoading = false;
                }
            },

            // ── Filtering ─────────────────────────────────────────────────
            isPermissionVisible(permId, permName) {
                const matchesSearch = !this.search ||
                    permName.toLowerCase().includes(this.search.toLowerCase());
                const matchesRole = this.filterRole === null ||
                    (this.permRoleMap[permId] || []).includes(this.filterRole);
                return matchesSearch && matchesRole;
            },

            isModuleVisible(module) {
                // A module is visible if at least one of its permissions is visible.
                // We can't easily check this from here without the full list, so always show.
                // The individual permission cards handle their own visibility.
                return true;
            },

            noResults() {
                // Simple heuristic — if search is set and nothing matches
                if (!this.search && this.filterRole === null) return false;
                return false; // Alpine can't easily count across all modules here
            },

            // ── Role color helpers ────────────────────────────────────────
            getRoleColor(theme) {
                const map = {
                    'midnight-dark':  'bg-slate-800',
                    'ocean-blue':     'bg-sky-500',
                    'arctic-white':   'bg-gray-400',
                    'desert-sand':    'bg-amber-500',
                    'forest-green':   'bg-emerald-500',
                    'royal-purple':   'bg-violet-600',
                    'sunset-orange':  'bg-orange-500',
                    'corporate-gray': 'bg-slate-500',
                    'cherry-blossom': 'bg-pink-500',
                    'crimson-red':    'bg-red-600',
                    'default':        'bg-gray-500',
                };
                return map[theme] || 'bg-gray-500';
            },

            getRoleHex(theme) {
                const map = {
                    'midnight-dark':  '#1e293b',
                    'ocean-blue':     '#0ea5e9',
                    'arctic-white':   '#9ca3af',
                    'desert-sand':    '#f59e0b',
                    'forest-green':   '#10b981',
                    'royal-purple':   '#7c3aed',
                    'sunset-orange':  '#f97316',
                    'corporate-gray': '#64748b',
                    'cherry-blossom': '#ec4899',
                    'crimson-red':    '#dc2626',
                    'default':        '#6b7280',
                };
                return map[theme] || '#6b7280';
            },

            // ── Toast ─────────────────────────────────────────────────────
            showToast(message, type = 'success') {
                if (this.toast.timer) clearTimeout(this.toast.timer);
                this.toast = { show: true, message, type, timer: null };
                this.toast.timer = setTimeout(() => { this.toast.show = false; }, 3000);
            },
        };
    }
    </script>
    @endpush

</x-app-layout>
