<?php

namespace Daylight\Core\Providers;

use Daylight\Core\Http\Controllers\Content\PageController;
use Daylight\Core\Http\Controllers\DashboardController;
use Daylight\Core\Http\Controllers\Settings\CountryController;
use Daylight\Core\Http\Controllers\Settings\GeneralSettingsController;
use Daylight\Core\Http\Controllers\Settings\RoleController;
use Daylight\Core\Http\Controllers\Settings\ShippingClassController;
use Daylight\Core\Http\Controllers\Settings\ShippingZoneController;
use Daylight\Core\Http\Controllers\Settings\TaxClassController;
use Daylight\Core\Http\Controllers\Store\AttributeController;
use Daylight\Core\Http\Controllers\Store\BrandController;
use Daylight\Core\Http\Controllers\Store\CategoryController;
use Daylight\Core\Http\Controllers\Store\CustomerController;
use Daylight\Core\Http\Controllers\Store\CustomerGroupController;
use Daylight\Core\Http\Controllers\Store\LabelController;
use Daylight\Core\Http\Controllers\Store\OrderController;
use Daylight\Core\Http\Controllers\Store\ProductController;
use Daylight\Core\Http\Controllers\Store\UserController;
use Daylight\Core\Http\Controllers\Store\VariantController;
use Daylight\Core\Http\Middleware\EnsureTwoFactorAuthenticated;
use Daylight\Core\Http\Middleware\PopulatePricingContext;
use Daylight\Core\Modules\MediaLibrary\Http\Controllers\MediaController;
use Daylight\Core\Modules\MenuBuilder\Http\Controllers\MenuController;
use Daylight\Core\Modules\MenuBuilder\Http\Controllers\NavigationSettingsController;
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
use Spatie\ResponseCache\Middlewares\DoNotCacheResponse;

class RouteServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        //
    }

    public function boot(): void
    {
        $this
            ->registerMiddleware()
            ->registerModelBindings()
            ->registerRouteMacros();
    }

    public function registerMiddleware(): self
    {
        $router = $this->app->make(Router::class);

        $router->aliasMiddleware('no-cache', DoNotCacheResponse::class);
        $router->aliasMiddleware('two-factor', EnsureTwoFactorAuthenticated::class);
        $router->aliasMiddleware('pricing-context', PopulatePricingContext::class);

        return $this;
    }

    public function registerRouteMacros(): self
    {
        Route::macro('daylight', function (string $path = 'admin') {
            Route::get('store/users/leave-impersonation', [UserController::class, 'leaveImpersonation'])
                ->name('daylight.impersonate.leave');

            Route::middleware(['web', 'auth', 'can:view:administration', 'two-factor', 'no-cache'])
                ->name('daylight.')
                ->prefix($path)
                ->group(function () {
                    Route::get('/', DashboardController::class)->name('index');

                    Route::prefix('store')
                        ->as('store.')
                        ->group(function () {
                            Route::resource('orders', OrderController::class);
                            Route::resource('users', UserController::class);
                            Route::resource('customers', CustomerController::class);
                            Route::resource('customer-groups', CustomerGroupController::class);
                            Route::resource('products', ProductController::class);
                            Route::resource('variants', VariantController::class);
                            Route::resource('brands', BrandController::class);
                            Route::resource('categories', CategoryController::class);
                            Route::resource('labels', LabelController::class);
                            Route::resource('attributes', AttributeController::class);
                        });

                    Route::prefix('content')
                        ->as('content.')
                        ->group(function () {
                            Route::resource('menus', MenuController::class);
                            Route::resource('pages', PageController::class);
                            Route::post('pages/{page}/duplicate', [PageController::class, 'duplicate'])
                                ->name('pages.duplicate');
                        });

                    Route::prefix('settings')
                        ->as('settings.')
                        ->group(function () {
                            Route::get('/', [GeneralSettingsController::class, 'index'])->name('general.index');
                            Route::put('/', [GeneralSettingsController::class, 'update'])->name('general.update');

                            Route::get('/navigation', [NavigationSettingsController::class, 'index'])->name('navigation.index');
                            Route::put('/navigation', [NavigationSettingsController::class, 'update'])->name('navigation.update');

                            Route::resource('countries', CountryController::class)->except(['show']);
                            Route::resource('tax-classes', TaxClassController::class)->except(['show']);
                            Route::resource('shipping-classes', ShippingClassController::class)->except(['show']);
                            Route::resource('shipping-zones', ShippingZoneController::class)->except(['show']);
                            Route::resource('roles', RoleController::class)->except(['show']);
                        });

                    Route::prefix('media')
                        ->as('media.')
                        ->group(function () {
                            Route::get('/', MediaController::class)->name('index');
                        });

                    // For creating JS variable with base route
                    Route::get('api', function () {
                        return response(null);
                    })->name('api');

                    Route::prefix('api')
                        ->as('api.')
                        ->group(function () {
                            Route::get('translations/{locale?}', \Daylight\Core\Http\Controllers\API\TranslationsController::class)
                                ->name('translations');
                            //
                            Route::post('variants/search', \Daylight\Core\Http\Controllers\Store\API\VariantSearchController::class);

                            Route::get('search', \Daylight\Core\Http\Controllers\API\SearchController::class)
                                ->name('search');
                        });

                });
        });

        return $this;
    }

    public function registerModelBindings(): self
    {
        $models = (array) config('daylight.models', []);

        foreach ($models as $parameter => $class) {
            if (is_string($parameter) && is_string($class) && class_exists($class)) {
                // Bind route parameter name (e.g. 'product', 'shipping_class') to the configured model class
                Route::model($parameter, $class);
            }
        }

        return $this;
    }
}
