<?php

namespace App\Services;

use App\Models\Group;
use App\Models\Menu;
use App\Models\MenuType;
use App\Models\User;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;

/**
 * Menyusun menu sidebar dinamis dari database (RPD FR-AUT-07, BR-10, FR-USR-05/06).
 *
 * Menu difilter berdasarkan grup user (pivot menu_groups) dan route yang sudah
 * terdaftar. Hasil di-cache per grup agar tidak query DB tiap request.
 */
class NavigationService
{
    /**
     * Susun menu untuk user tertentu, dikelompokkan per section.
     *
     * @return array<int, array{label: string, items: array<int, array{label: string, route: string, href: string, icon: string}>}>
     */
    public function forUser(User $user): array
    {
        $groupNames = $user->groupNames()->values()->all();
        if (empty($groupNames)) {
            return [];
        }

        $groupIds = Group::whereIn('name', $groupNames)->pluck('id')->all();
        sort($groupNames);

        // Versi cache dibump saat menu/grup berubah; key = versi + kombinasi grup.
        $version = Cache::get('nav:version', 0);
        $cacheKey = 'nav:'.$version.':'.implode('-', $groupNames);

        return Cache::remember($cacheKey, now()->addHour(), function () use ($groupIds) {
            $sideType = MenuType::where('type', 'Side menu')->first();
            if (! $sideType) {
                return [];
            }

            $menus = Menu::where('menu_type_id', $sideType->id)
                ->where('status', true)
                ->whereNull('parent_id')
                ->whereHas('groups', fn ($q) => $q->whereIn('group_id', $groupIds))
                ->orderBy('section')
                ->orderBy('sort_order')
                ->get();

            $sections = [];
            foreach ($menus as $menu) {
                $href = $this->resolveHref($menu);
                if ($href === null) {
                    continue; // route belum terdaftar, lewati
                }

                $sectionLabel = $menu->section ?? 'Utama';
                $sections[$sectionLabel][] = [
                    'label' => $menu->label,
                    'route' => $menu->route ?? '',
                    'href' => $href,
                    'icon' => $menu->icon ?? 'layout-grid',
                ];
            }

            return collect($sections)
                ->sortBy(fn (array $items, string $label) => $label === 'Utama' ? 0 : 1)
                ->map(fn (array $items, string $label) => ['label' => $label, 'items' => $items])
                ->values()
                ->all();
        });
    }

    /**
     * Resolve URL menu: named route bila ada, jika tidak pakai link absolut.
     * Kembalikan null bila tidak bisa diresolve (agar dilewati).
     */
    protected function resolveHref(Menu $menu): ?string
    {
        if ($menu->route && Route::has($menu->route)) {
            return route($menu->route);
        }

        if ($menu->link) {
            return $menu->link;
        }

        return null;
    }

    /**
     * Invalidate cache nav (panggil setelah menu/grup berubah) dengan bump versi.
     */
    public function clearCache(): void
    {
        Cache::increment('nav:version');
    }
}
