<?php

namespace App\Traits;

use App\Services\Menu\IMenuRegistrarService;

/**
 * Trait for module service providers to register menu items.
 *
 * Usage in module ServiceProvider:
 *
 * use App\Traits\RegistersMenuItems;
 *
 * class PayrollServiceProvider extends ServiceProvider
 * {
 *     use RegistersMenuItems;
 *
 *     protected string $name = 'Payroll';  // Uses existing $name property
 *
 *     public function boot(): void
 *     {
 *         // ... existing boot code ...
 *         $this->registerMenuItems();
 *     }
 *
 *     protected function getMenuItems(): array
 *     {
 *         return [
 *             [
 *                 'name' => 'Payroll',
 *                 'icon' => 'menu-icon bx bx-money',
 *                 'slug' => 'payroll',
 *                 'roles' => ['admin', 'hr'],
 *                 'submenu' => [
 *                     ['name' => 'Dashboard', 'url' => '/payroll/dashboard', 'slug' => 'payroll.dashboard'],
 *                 ],
 *             ],
 *         ];
 *     }
 * }
 */
trait RegistersMenuItems
{
    /**
     * Register the module's menu items with the menu service.
     */
    protected function registerMenuItems(): void
    {
        // Skip if no menu items defined
        if (! method_exists($this, 'getMenuItems')) {
            return;
        }

        $items = $this->getMenuItems();
        if (empty($items)) {
            return;
        }

        // Get the menu registrar service
        $menuService = app(IMenuRegistrarService::class);

        // Get module name from property or derive from class name
        $moduleName = $this->getModuleName();

        // Register menu items with priority
        $menuService->register(
            $moduleName,
            $items,
            $this->getMenuPriority()
        );
    }

    /**
     * Get the module name for menu registration.
     * Uses the $name or $moduleName property if available,
     * otherwise derives from the class name.
     */
    protected function getModuleName(): string
    {
        // Check for $name property (standard in nwidart/laravel-modules service providers)
        if (property_exists($this, 'name') && ! empty($this->name)) {
            return $this->name;
        }

        // Check for $moduleName property (used in some modules)
        if (property_exists($this, 'moduleName') && ! empty($this->moduleName)) {
            return $this->moduleName;
        }

        // Try to derive from class name (e.g., PayrollServiceProvider -> Payroll)
        $className = class_basename(static::class);
        if (str_ends_with($className, 'ServiceProvider')) {
            return str_replace('ServiceProvider', '', $className);
        }

        return $className;
    }

    /**
     * Get the menu priority for this module.
     * Lower values appear higher in the menu.
     * Override this in your service provider for custom ordering.
     *
     * Suggested priority ranges:
     * - 10: Dashboard
     * - 20: Operations (SystemCore)
     * - 30: Finance (AccountingCore, ExpenseManagement)
     * - 40: CRM/Sales (CRMCore, SalesTarget)
     * - 50: HR Core (HRCore, Payroll, Leave, Attendance)
     * - 60: HR Extended (Recruitment, Performance, Loans)
     * - 70: Projects (PMCore, TaskSystem)
     * - 80: Inventory (WMS, ProductInventory)
     * - 90: Utilities (DocumentManagement, NoticeBoard)
     * - 100: Admin (Settings, Audit, Backup) - Default
     */
    protected function getMenuPriority(): int
    {
        return 100;
    }

    /**
     * Get the menu items for this module.
     * Override this in your service provider.
     *
     * @return array<array<string, mixed>>
     *
     * Example return format:
     * [
     *     [
     *         'name' => 'Module Name',           // Required: Display name
     *         'icon' => 'menu-icon bx bx-icon',  // Optional: Icon class
     *         'slug' => 'route.prefix',          // Optional: Route for active state
     *         'url' => '/module/page',           // Optional: Direct URL (for leaf items)
     *         'roles' => ['admin', 'hr'],        // Optional: Restrict to roles
     *         'permission' => 'module.view',     // Optional: Permission check
     *         'badge' => ['danger', 'New'],      // Optional: Badge [color, text]
     *         'submenu' => [                     // Optional: Nested items
     *             ['name' => 'Submenu', 'url' => '/module/sub', 'slug' => 'route.sub'],
     *         ],
     *     ],
     * ]
     */
    protected function getMenuItems(): array
    {
        return [];
    }

    /**
     * Register a section header before the module's menu items.
     */
    protected function registerMenuHeader(string $header): void
    {
        $menuService = app(IMenuRegistrarService::class);
        $menuService->registerHeader(
            $this->getModuleName(),
            $header,
            $this->getMenuPriority()
        );
    }
}
