<?php

namespace App\Services\Menu;

use App\Models\User;

/**
 * Interface for the Menu Registrar Service.
 *
 * This service collects menu items from all modules and provides
 * methods to retrieve filtered menus based on roles and permissions.
 */
interface IMenuRegistrarService
{
    /**
     * Register menu items for a module.
     *
     * @param  string  $module  Module name (e.g., 'Payroll')
     * @param  array<MenuItemDTO|array<string, mixed>>  $items  Menu items to register
     * @param  int  $priority  Sort priority (lower = higher in menu)
     */
    public function register(string $module, array $items, int $priority = 100): void;

    /**
     * Register a menu header/section.
     *
     * @param  string  $module  Module name
     * @param  string  $header  Header text
     * @param  int  $priority  Sort priority
     */
    public function registerHeader(string $module, string $header, int $priority = 100): void;

    /**
     * Get all registered menu items (unfiltered).
     *
     * @return array<array<string, mixed>>
     */
    public function getAll(): array;

    /**
     * Get menu items filtered for a specific role.
     *
     * @param  string  $role  Role name
     * @return array<array<string, mixed>>
     */
    public function getForRole(string $role): array;

    /**
     * Get menu items filtered for a user (based on their roles).
     *
     * @return array<array<string, mixed>>
     */
    public function getForUser(User $user): array;

    /**
     * Get menu items formatted for navbar search.
     *
     * @return array<array{name: string, url: string, icon: string|null}>
     */
    public function toSearchArray(User $user): array;

    /**
     * Check if any menus have been registered.
     */
    public function hasRegisteredMenus(): bool;

    /**
     * Set base menu items (Dashboard, etc.).
     *
     * @param  array<array<string, mixed>>  $items
     */
    public function setBaseMenu(array $items): void;

    /**
     * Clear all registered menus (useful for testing).
     */
    public function clear(): void;
}
