<?php

namespace App\Providers;

use App\Nova\Resources\Branch\Branch;
use App\Nova\Resources\Order\Loan\LoanOrder;
use App\Nova\Resources\Order\Loan\LoanType;
use App\Nova\Resources\System\Location\Province;
use App\Nova\Resources\System\Roles\Permission;
use App\Nova\Resources\System\Roles\Role;
use App\Nova\User;
use App\Repos\System\Nova\NovaRepo;
use Eolica\NovaLocaleSwitcher\LocaleSwitcher;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Laravel\Nova\Dashboards\Main;
use Laravel\Nova\Events\ServingNova;
use Laravel\Nova\Menu\Menu;
use Laravel\Nova\Menu\MenuGroup;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Menu\MenuSection;
use Laravel\Nova\Nova;
use Laravel\Nova\NovaApplicationServiceProvider;

class NovaServiceProvider extends NovaApplicationServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        parent::boot();

        Nova::withBreadcrumbs();
        Nova::footer(fn () => view('vendor.nova.partials.footer')->render());

        $this->setupNavigation();
        $this->setupUserNavigation();
        $this->setupUserSettings();
        $this->setupAssets();
    }

    /**
     * Register the Nova routes.
     */
    protected function routes(): void
    {
        Nova::routes()
            ->withAuthenticationRoutes()
            ->withPasswordResetRoutes()
            ->register();
    }

    /**
     * Register the Nova gate.
     *
     * This gate determines who can access Nova in non-local environments.
     */
    protected function gate(): void
    {
        Gate::define('viewNova', function ($user) {
            return in_array($user->email, [
                //
            ]);
        });
    }

    /**
     * Get the dashboards that should be listed in the Nova sidebar.
     */
    protected function dashboards(): array
    {
        return [
            new Main,
        ];
    }

    /**
     * Get the tools that should be listed in the Nova sidebar.
     */
    public function tools(): array
    {
        return [
            LocaleSwitcher::make()
                ->setLocales(config('app.locales'))
                ->onSwitchLocale(NovaRepo::localeSwitcherSave()),
        ];
    }

    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Setup navigation
     */
    public function setupNavigation(): void
    {
        Nova::mainMenu(function (Request $request) {
            return [
                MenuSection::dashboard(Main::class)->icon('chart-bar'),

                MenuSection::make(__('Orders'), [
                    MenuItem::resource(LoanOrder::class),
                ])->icon('collection')->collapsable(),

                MenuSection::make(__('System'), [
                    MenuGroup::make(__('User'), [
                        MenuItem::resource(User::class),
                        MenuItem::resource(Role::class),
                        MenuItem::resource(Permission::class),
                    ])->collapsable(),

                    MenuGroup::make(__('Loan'), [
                        MenuItem::resource(LoanType::class),
                    ])->collapsable(),

                    MenuGroup::make(__('Location'), [
                        MenuItem::resource(Province::class),
                        MenuItem::resource(Branch::class),
                    ])->collapsable(),
                ])->icon('cog')->collapsable(),
            ];
        });
    }

    /**
     * Setup user navigation (dropdown).
     */
    public function setupUserNavigation(): void
    {
        Nova::userMenu(function (Request $request, Menu $menu) {
            $menu->prepend(MenuItem::make(__('My Profile'), sprintf('/resources/users/%s', $request->user()->id)));

            return $menu;
        });
    }

    /**
     * Setup user settings
     */
    public function setupUserSettings(): void
    {
        Nova::serving(fn (ServingNova $event) => NovaRepo::serving($event));
    }

    /**
     * Setup Assets
     */
    public function setupAssets(): void
    {
        Nova::style('additional', resource_path('css/vendor/nova/css/additional.css'));
    }
}
