<?php

declare(strict_types=1);

namespace Apexl\Io\Menu\Interfaces;

use Apexl\Io\User\Entities\UserEntity;

/**
 * Phase 5 (quiet mode) seam — a filter that narrows the already-built,
 * already permission-checked top-level menu item list before it's
 * returned to the caller.
 *
 * `MenuManager::getAllItemsAsMenu()` runs every hook-collected
 * NavFilterInterface (via `menu.collectNavFilters`, see NavFilterRegistry)
 * in registration order, each seeing the previous filter's output. This
 * lets a downstream package (e.g. `apexl/io-page-layouts`'s workspace
 * nav-allowlist) narrow the visible top-level groups WITHOUT io-menu
 * knowing anything about workspaces, and without the provider package
 * needing to fork or wrap menu-building itself.
 *
 * ⚠ The application point is deliberately MenuManager, NOT
 * `menuEntity::getAllItemsAsMenu()`. Every `menuEntity` instance's
 * `->name` is the hardcoded `'navigation'` constructor default (see that
 * class) regardless of which logical menu it backs — MenuManager builds
 * one `menuEntity` per menu KEY via `addToMenu()`/`getAllItemsAsMenu()`
 * without ever calling `loadByName()`, so the entity itself carries no
 * information about which menu it is. Only MenuManager knows that (the
 * resolved key it looked the entity up by) — that's what's passed as
 * `$menuName` below.
 *
 * Implementations should be defensive: a broken/empty filter result is
 * indistinguishable from "user has access to nothing", so callers doing
 * something workspace-shaped should fail OPEN (return $menuItems
 * unchanged) rather than closed when their own data is missing/invalid.
 */
interface NavFilterInterface
{
    /**
     * @param array<int, object> $menuItems Top-level menu item objects
     *        (menuItem|stdClass) as produced by menuEntity::checkAccess() —
     *        each carries at least ->name (the dot-normalised routeName)
     *        and, for parent groups, ->links (already permission-filtered
     *        children). Return the same shape, narrowed and/or reordered.
     * @param UserEntity $user The user the menu is being built for.
     * @param string $menuName The RESOLVED MenuManager menu key (always
     *        UPPERCASE — `MenuManager::resolveMenuName()` uppercases every
     *        key before lookup/storage), e.g. 'NAVIGATION' for the primary
     *        sidebar (`MenuManager::DEFAULT_MENU`). This is NOT
     *        menuEntity::$name (see class docblock) — it's the key the
     *        caller passed to `MenuManager::getAllItemsAsMenu()` /
     *        `addToMenu()`. Filters that only apply to one menu MUST check
     *        this themselves; io-menu applies every registered filter to
     *        every menu key it's asked to resolve.
     * @return array<int, object>
     */
    public function filter(array $menuItems, UserEntity $user, string $menuName): array;
}
