<?php

namespace App\Providers;

use App\Services\AddonService\IAddonService;
use App\Services\Menu\IMenuRegistrarService;
use Illuminate\Support\ServiceProvider;

class MenuServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        // Load base menu (Dashboard, etc.) for the dynamic menu system
        $this->loadBaseMenu();

        // Load legacy JSON menus for backward compatibility
        // These will be phased out as modules migrate to dynamic registration
        $verticalMenuData = $this->loadJsonMenu('resources/menu/verticalMenu.json');
        $hrMenuData = $this->loadJsonMenu('resources/menu/hrMenu.json');
        $employeeMenuData = $this->loadJsonMenu('resources/menu/employeeMenu.json');
        $horizontalMenuData = $this->loadJsonMenu('resources/menu/horizontalMenu.json');

        // Use a view composer to determine menu based on authenticated user
        // This runs when the view is rendered, after authentication
        $this->app->make('view')->composer('*', function ($view) use ($verticalMenuData, $hrMenuData, $employeeMenuData, $horizontalMenuData) {
            // Get the menu registrar service
            $menuService = app(IMenuRegistrarService::class);
            $addonService = app(IAddonService::class);

            // Load tenant menu only if MultiTenancyCore module is enabled
            $tenantMenuData = null;
            $tenantHorizontalMenuData = null;
            if ($addonService->isAddonEnabled('MultiTenancyCore')) {
                $tenantMenuPath = module_path('MultiTenancyCore', 'resources/menu/tenantMenu.json');
                if (file_exists($tenantMenuPath)) {
                    $tenantMenuData = $this->loadJsonMenu($tenantMenuPath, true);
                }
                $tenantHorizontalPath = module_path('MultiTenancyCore', 'resources/menu/tenantHorizontalMenu.json');
                if (file_exists($tenantHorizontalPath)) {
                    $tenantHorizontalMenuData = $this->loadJsonMenu($tenantHorizontalPath, true);
                }
            }

            // Determine which menu to use for the authenticated user
            $activeVerticalMenuData = $verticalMenuData;
            $activeHorizontalMenuData = $horizontalMenuData;

            if (auth()->check()) {
                $user = auth()->user();

                // Check if dynamic menus are registered
                $useDynamicMenus = $menuService->hasRegisteredMenus();

                if ($user->hasRole('tenant') && $tenantMenuData !== null) {
                    // Tenant users get the tenant-specific menu (only if MultiTenancyCore is enabled)
                    $activeVerticalMenuData = $tenantMenuData;
                    $activeHorizontalMenuData = $tenantHorizontalMenuData ?? $tenantMenuData;
                } elseif ($useDynamicMenus) {
                    // Use dynamic menus from the registrar service (role-filtered)
                    $dynamicMenu = $menuService->getForUser($user);
                    $activeVerticalMenuData = $this->convertToMenuObject($dynamicMenu);
                    $activeHorizontalMenuData = $activeVerticalMenuData;
                } elseif ($user->hasRole(['super_admin', 'admin'])) {
                    // Legacy: Super Admin and Admin get full menu
                    $activeVerticalMenuData = $verticalMenuData;
                    $activeHorizontalMenuData = $horizontalMenuData;
                } elseif ($user->hasRole(['hr', 'hr_manager', 'hr_executive'])) {
                    // Legacy: HR users get the HR-specific menu
                    $activeVerticalMenuData = $hrMenuData;
                    $activeHorizontalMenuData = $hrMenuData;
                } elseif ($user->hasRole(['employee', 'field_employee', 'office_employee', 'manager', 'team_leader'])) {
                    // Legacy: Employees get the employee menu
                    $activeVerticalMenuData = $employeeMenuData;
                    $activeHorizontalMenuData = $employeeMenuData;
                } else {
                    // Default to admin menu for any other roles
                    $activeVerticalMenuData = $verticalMenuData;
                    $activeHorizontalMenuData = $horizontalMenuData;
                }
            }

            // Share all menuData to all the views
            // Index 0: vertical menu (admin), Index 1: horizontal menu (role-based), Index 2: (removed), Index 3: active vertical menu (role-based)
            $view->with('menuData', [$verticalMenuData, $activeHorizontalMenuData, null, $activeVerticalMenuData]);
        });
    }

    /**
     * Load a JSON menu file and decode it.
     *
     * @param  string  $path  Relative path from base_path() or absolute path
     * @param  bool  $isAbsolute  Whether the path is absolute
     */
    private function loadJsonMenu(string $path, bool $isAbsolute = false): ?object
    {
        $fullPath = $isAbsolute ? $path : base_path($path);

        if (! file_exists($fullPath)) {
            return null;
        }

        $json = file_get_contents($fullPath);

        return json_decode($json);
    }

    /**
     * Convert an array menu to an object structure compatible with existing Blade templates.
     *
     * @param  array<array<string, mixed>>  $menu
     */
    private function convertToMenuObject(array $menu): object
    {
        return (object) ['menu' => json_decode(json_encode($menu))];
    }

    /**
     * Load the base menu (Dashboard, etc.) for the dynamic menu system.
     */
    private function loadBaseMenu(): void
    {
        $baseMenuPath = base_path('resources/menu/baseMenu.json');

        if (! file_exists($baseMenuPath)) {
            return;
        }

        $json = file_get_contents($baseMenuPath);
        $data = json_decode($json, true);

        if ($data && isset($data['menu']) && is_array($data['menu'])) {
            $menuService = app(IMenuRegistrarService::class);
            $menuService->setBaseMenu($data['menu']);
        }
    }
}
