<?php

namespace App\Modules\Navigation\Services;

use App\Models\User;
use App\Modules\Admin\Tenancy\Services\ModuleAccessService;
use Illuminate\Support\Facades\Cache;

class NavigationService
{
    private const CACHE_TTL_SECONDS = 120;

    public function __construct(
        private readonly ModuleAccessService $moduleAccess,
        private readonly NavigationMenuBuilder $menuBuilder,
    ) {}

    /**
     * @return list<array{label: string, icon: string, items: list<array<string, mixed>>}>
     */
    public function filteredGroups(?User $user): array
    {
        if ($user === null) {
            return [];
        }

        $user->loadMissing('tenant');

        /** @var list<array<string, mixed>> $groups */
        $groups = config('admin-nav.groups', []);

        if ($user->isAdmin()) {
            return $this->menuBuilder->build($groups, $user, true, []);
        }

        return Cache::remember(
            $this->cacheKey($user),
            self::CACHE_TTL_SECONDS,
            function () use ($groups, $user): array {
                return $this->menuBuilder->build(
                    $groups,
                    $user,
                    false,
                    $this->tenantModuleSlugs($user),
                );
            }
        );
    }

    /**
     * @return list<string>
     */
    private function tenantModuleSlugs(User $user): array
    {
        $tenant = $user->tenant;
        if ($tenant === null || ! $tenant->is_active) {
            return [];
        }

        return $this->moduleAccess->activeModuleSlugsFor($tenant);
    }

    public static function forgetForUser(User $user): void
    {
        foreach (['en', 'ar'] as $locale) {
            Cache::forget('navigation:user:'.$user->id.':tenant:'.($user->tenant_id ?? '0').':locale:'.$locale);
        }
        NavigationMegaMenuSignalService::forgetForUser($user);
    }

    private function cacheKey(User $user): string
    {
        return 'navigation:user:'.$user->id
            .':tenant:'.($user->tenant_id ?? '0')
            .':locale:'.app()->getLocale();
    }
}
