<?php

namespace App\Providers;

use App\Models\Informacia\Informacia;
use App\Models\Pouzivatel\PortalRolesPermissions;
use App\Models\Pouzivatel\RoleAndPermissionsAggregator;
use App\Models\Pouzivatel\RolesPermissions;
use App\Observers\InformaciaObserver;
use App\Observers\NotificationObserver;
use Carbon\Carbon;
use Dingo\Api\Transformer\Adapter\Fractal;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Notifications\DatabaseNotification;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;
use League\Fractal\Manager;
use League\Fractal\Serializer\JsonApiSerializer;
use Seka\AisekV3UserAuth\Authentication;

/**
 * Class AppServiceProvider
 */
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register(): void
    {
        $this->app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
            $fractal = new Manager();

            $fractal->setSerializer(new JsonApiSerializer(secure_url('/api')));

            return new Fractal($fractal);
        });
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot(): void
    {
        if ($this->app->environment('production')) {
            URL::forceScheme('https');
        }

        Carbon::setLocale(config('app.locale'));

        $this->app->bind(Authentication::class, function ($app) {
            return new Authentication(getenv('AISEKV3_AUTH_URI'));
        });

        $this->aggregateRolesAndPermissions();
        $this->registerModelsObservers();

        Paginator::useBootstrap();

        Relation::morphMap([
            'informacia' => Informacia::class,
        ]);
    }

    /**
     * Agregacia roli a opravneni pouzivatelov pre portal a vsetky jeho registrovane moduly
     */
    protected function aggregateRolesAndPermissions(): void
    {
        $this->app->bind(PortalRolesPermissions::class, function () {
            return new PortalRolesPermissions();
        });

        $this->app->tag([
            PortalRolesPermissions::class,
        ], 'roleaopravnenia');

        $this->app
            ->when(RoleAndPermissionsAggregator::class)
            ->needs(RolesPermissions::class)
            ->giveTagged('roleaopravnenia');
    }

    /**
     * Register models observers.
     *
     * @return void
     */
    public function registerModelsObservers(): void
    {
        DatabaseNotification::observe(NotificationObserver::class);
        Informacia::observe(InformaciaObserver::class);
    }
}
