<?php
/**
 * Created by PhpStorm.
 * User: radko
 * Date: 12.11.18
 * Time: 15:33
 */

namespace Seka\Vzdelavanie\Providers;

use ConsoleTVs\Charts\Registrar;
use Illuminate\Contracts\Foundation\CachesConfiguration;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\ServiceProvider;
use Livewire\Livewire;
use Seka\Vzdelavanie\Charts\UspesnostRieseniaTestovNaPekChart;
use Seka\Vzdelavanie\Commands\Console\ImportTestov;
use Seka\Vzdelavanie\Composers\Kniznica\ZoznamKategoriiComposer;
use Seka\Vzdelavanie\Composers\Kniznica\ZoznamOblubenychPoloziekPouzivatelaComposer;
use Seka\Vzdelavanie\Composers\Kniznica\ZoznamUcebnychMaterialovPodlaKategoriiComposer;
use Seka\Vzdelavanie\Composers\Testovanie\ZoznamTestovPodlaPopularnostiCompose;
use Seka\Vzdelavanie\Livewire\Components\Pracoviska;
use Seka\Vzdelavanie\Livewire\Components\SearchText;
use Seka\Vzdelavanie\Livewire\Components\Stav;
use Seka\Vzdelavanie\Livewire\Sprava\Testovanie\Pouzivatelia\Components\Zoznam;
use Seka\Vzdelavanie\Models\Kniznica\Sekcia;
use Seka\Vzdelavanie\Models\Kniznica\Ucebnica;
use Seka\Vzdelavanie\Models\Testovanie\Test;
use Seka\Vzdelavanie\Modul\VzdelavanieRolesPermissions;
use Seka\Vzdelavanie\Repositories\Contracts\KategoriaRepositoryInterface;
use Seka\Vzdelavanie\Repositories\Contracts\SekciaRepositoryInterface;
use Seka\Vzdelavanie\Repositories\Contracts\UcebnicaRepositoryInterface;
use Seka\Vzdelavanie\Repositories\Eloquent\KategoriaRepository;
use Seka\Vzdelavanie\Repositories\Eloquent\SekciaRepository;
use Seka\Vzdelavanie\Repositories\Eloquent\UcebnicaRepository;
use Seka\Vzdelavanie\Services\KategoriaService;
use Seka\Vzdelavanie\Services\KategoriaServiceInterface;
use Seka\Vzdelavanie\Services\SekciaService;
use Seka\Vzdelavanie\Services\SekciaServiceInterface;
use Seka\Vzdelavanie\Services\UcebnicaService;
use Seka\Vzdelavanie\Services\UcebnicaServiceInterface;

/**
 * Class VzdelavanieServiceProvider
 *
 * @package Seka\Vzdelavanie\Providers
 */
class VzdelavanieServiceProvider extends ServiceProvider
{
    /**
     * @return void
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function boot(): void
    {
        $this->app->bind(VzdelavanieRolesPermissions::class, function () {
            return new VzdelavanieRolesPermissions();
        });

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

        $this->app->booted(function () {
            $this->breadcrumbs();

            Relation::morphMap([
                Test::type() => Test::class,
                Sekcia::type() => Sekcia::class,
                Ucebnica::type() => Ucebnica::class,
            ]);
        });

        if ($this->app->runningInConsole()) {
            $this->commands([
                ImportTestov::class,
            ]);
        }

        $this->app->get(Registrar::class)->register([
            UspesnostRieseniaTestovNaPekChart::class,
        ]);

        $this->publishConfig();
        $this->publishViews();
        $this->publishAssets();
        $this->publishMigrations();
        $this->loadViewsFrom(__DIR__ . '/../../resources/views', 'Vzdelavanie');

        $this->loadLivewireComponents();
    }

    /**
     * @return void
     */
    protected function breadcrumbs(): void
    {
        if (class_exists('Breadcrumbs')) {
            // BACKEND
            require __DIR__ . '/../../routes/backend/breadcrumbs.php';
            require __DIR__ . '/../../routes/backend/testy/breadcrumbs.php';
            require __DIR__ . '/../../routes/backend/kniznica/breadcrumbs.php';

            // FRONTEND
            require __DIR__ . '/../../routes/frontend/breadcrumbs.php';
            require __DIR__ . '/../../routes/frontend/testy/breadcrumbs.php';
            require __DIR__ . '/../../routes/frontend/kniznica/breadcrumbs.php';
        }
    }

    /**
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function register(): void
    {
        $this->registerRepositoryBindings();
        $this->registerServiceBindings();
        $this->registerConfig();
        $this->registerComposers();
        $this->registerEvents();
        $this->registerAuths();
        $this->registerRoutes();
    }

    /**
     * @return void
     */
    protected function registerRepositoryBindings(): void
    {
        $this->app->bind(
            KategoriaRepositoryInterface::class,
            KategoriaRepository::class,
        );
        $this->app->bind(
            UcebnicaRepositoryInterface::class,
            UcebnicaRepository::class,
        );
        $this->app->bind(
            SekciaRepositoryInterface::class,
            SekciaRepository::class,
        );
    }

    /**
     * @return void
     */
    protected function registerServiceBindings(): void
    {
        $this->app->bind(
            KategoriaServiceInterface::class,
            KategoriaService::class,
        );
        $this->app->bind(
            UcebnicaServiceInterface::class,
            UcebnicaService::class,
        );
        $this->app->bind(
            SekciaServiceInterface::class,
            SekciaService::class,
        );
    }

    /**
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    protected function registerConfig(): void
    {
        $this->mergeConfigFrom(__DIR__ . '/../../config/vzdelavanie.php', 'vzdelavanie');
        $this->mergeConfigFrom(__DIR__ . '/../../config/charts.php', 'charts');
        $this->mergeConfigFrom(__DIR__ . '/../../config/lfm.php', 'lfm');
    }

    /**
     * Prepisuje hodnoty klucov existujucej konfiguracie
     * Povodna metoda neprepisuje hodnoty klucov existujucu konfiguracie, len ju doplna v pripade absencie klucov,
     * reps. ich hodnot
     *
     * @param $path
     * @param $key
     *
     * @return void
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    protected function mergeConfigFrom($path, $key): void
    {
        if (!($this->app instanceof CachesConfiguration && $this->app->configurationIsCached())) {
            $config = $this->app->make('config');

            $config->set(
                $key,
                array_merge(
                    $config->get($key, []),
                    require $path,
                ),
            );
        }
    }

    /**
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function registerComposers(): void
    {
        // frontend
        view()->composer(
            ['Vzdelavanie::pages.kniznica.index'],
            ZoznamKategoriiComposer::class,
        );
        view()->composer(
            ['Vzdelavanie::pages.kniznica.index'],
            ZoznamUcebnychMaterialovPodlaKategoriiComposer::class,
        );
        view()->composer(
            ['Vzdelavanie::pages.testovanie.index'],
            ZoznamTestovPodlaPopularnostiCompose::class,
        );
        view()->composer(
            ['Vzdelavanie::pages.kniznica.index'],
            ZoznamOblubenychPoloziekPouzivatelaComposer::class,
        );

        // backend
        view()->composer(
            ['Vzdelavanie::pages.sprava.kniznica.index'],
            ZoznamKategoriiComposer::class,
        );
        view()->composer(
            ['Vzdelavanie::pages.sprava.kniznica.index'],
            ZoznamOblubenychPoloziekPouzivatelaComposer::class,
        );
    }

    /**
     * @return void
     */
    public function registerEvents(): void
    {
        $this->app->register(EventServiceProvider::class);
    }

    /**
     * @return void
     */
    public function registerAuths(): void
    {
        $this->app->register(AuthServiceProvider::class);
    }

    /**
     * @return void
     */
    public function registerRoutes(): void
    {
        $this->app->register(RouteServiceProvider::class);
    }

    /**
     * @return void
     */
    private function publishConfig(): void
    {
        if ($this->app->runningInConsole()) {
            $this->publishes([
                __DIR__ . '/../../config/vzdelavanie.php' => config_path('vzdelavanie.php'),
            ], 'config');
        }
    }

    /**
     * @return void
     */
    private function publishViews(): void
    {
        $this->publishes([
            __DIR__ . '/../../resources/views' => resource_path('views/vendor/seka/vzdelavanie'),
        ], 'views');
    }

    /**
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    private function publishAssets(): void
    {
        $this->publishes([
            __DIR__ . '/../../public/assets' => public_path('vendor/seka/vzdelavanie'),
        ], 'assets');
    }

    /**
     * @return void
     */
    private function publishMigrations(): void
    {
        if ($this->app->runningInConsole()) {
            if (!class_exists('CreateVzdelavanieKniznicaKategorieTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_kniznica_kategorie_table.php.stub' => database_path(
                        'migrations/2020_09_06_010201_create_vzdelavanie_kniznica_kategorie_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavanieKniznicaUcebniceTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_kniznica_ucebnice_table.php.stub' => database_path(
                        'migrations/2020_09_06_010202_create_vzdelavanie_kniznica_ucebnice_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavanieKniznicaSekcieTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_kniznica_sekcie_table.php.stub' => database_path(
                        'migrations/2020_09_06_010203_create_vzdelavanie_kniznica_sekcie_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavanieTestovanieTestyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_testovanie_testy_table.php.stub' => database_path(
                        'migrations/2020_09_06_010204_create_vzdelavanie_testovanie_testy_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavanieTestovanieOtazkyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_testovanie_otazky_table.php.stub' => database_path(
                        'migrations/2020_09_06_010205_create_vzdelavanie_testovanie_otazky_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavanieTestovanieOdpovedeTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_testovanie_odpovede_table.php.stub' => database_path(
                        'migrations/2020_09_06_010206_create_vzdelavanie_testovanie_odpovede_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavaniePouzivatelTestovanieTestyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_pouzivatel_testovanie_testy_table.php.stub' => database_path(
                        'migrations/2020_09_06_010207_create_vzdelavanie_pouzivatel_testovanie_testy_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavaniePouzivatelTestovanieOtazkyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_pouzivatel_testovanie_otazky_table.php.stub' => database_path(
                        'migrations/2020_09_06_010208_create_vzdelavanie_pouzivatel_testovanie_otazky_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavaniePouzivatelTestovanieOdpovedeTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_pouzivatel_testovanie_odpovede_table.php.stub' => database_path(
                        'migrations/2020_09_06_010209_create_vzdelavanie_pouzivatel_testovanie_odpovede_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavaniePouzivatelKniznicaOblubeneTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_pouzivatel_kniznica_oblubene_table.php.stub' => database_path(
                        'migrations/2020_09_06_010210_create_vzdelavanie_pouzivatel_kniznica_oblubene_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('CreateVzdelavaniePopularitaTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/create_popularita_table.php.stub' => database_path(
                        'migrations/2020_09_06_010211_create_vzdelavanie_popularita_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('UpdateVzdelavanieKniznicaUcebniceTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/update_kniznica_ucebnice_table.php.stub' => database_path(
                        'migrations/2020_09_06_010212_update_vzdelavanie_kniznica_ucebnice_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('UpdateVzdelavanieTestovanieTestyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/update_testovanie_testy_table.php.stub' => database_path(
                        'migrations/2020_09_06_010213_update_vzdelavanie_testovanie_testy_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('UpdateVzdelavanieTestovanieOtazkyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/update_testovanie_otazky_table.php.stub' => database_path(
                        'migrations/2020_09_06_010214_update_vzdelavanie_testovanie_otazky_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('UpdateVzdelavanieTestovanieOdpovedeTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/update_testovanie_odpovede_table.php.stub' => database_path(
                        'migrations/2020_09_06_010215_update_vzdelavanie_testovanie_odpovede_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('OdstranenyNazovKategorieVzdelavaniePouzivatelTestovanieTestyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/odstraneny_nazov_kategorie_pouzivatel_testovanie_testy_table.php.stub' => database_path(
                        'migrations/2020_09_11_110000_odstraneny_nazov_kategorie_vzdelavanie_pouzivatel_testovanie_testy_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('PremenovanyStlpecDruhVzdelavaniePouzivatelTestovanieOtazkyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/premenovany_stlpec_druh_pouzivatel_testovanie_otazky_table.php.stub' => database_path(
                        'migrations/2020_09_11_111000_premenovany_stlpec_druh_vzdelavanie_pouzivatel_testovanie_otazky_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('PremenovanyStlpecSpravnaVzdelavaniePouzivatelTestovanieOdpovedeTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/premenovany_stlpec_spravna_pouzivatel_testovanie_odpovede_table.php.stub' => database_path(
                        'migrations/2020_09_11_112000_premenovany_stlpec_spravna_vzdelavanie_pouzivatel_testovanie_odpovede_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('PridaneStlpceVyhodnoteniaVzdelavaniePouzivatelTestovanieTestyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/pridane_stlpce_vyhodnotenia_pouzivatel_testovanie_testy_table.php.stub' => database_path(
                        'migrations/2020_09_11_114000_pridane_stlpce_vyhodnotenia_vzdelavanie_pouzivatel_testovanie_testy_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('PridanyStlpecCasovejZnackySpusteniaTestuVzdelavaniePouzivatelTestovanieTestyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/pridany_stlpec_casovej_znacky_spustenia_testu_pouzivatel_testovanie_testy_table.php.stub' => database_path(
                        'migrations/2020_09_21_084000_pridany_stlpec_casovej_znacky_spustenia_testu_vzdelavanie_pouzivatel_testovanie_testy_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('PridanyStlpecStavuVyhodnoteniaTestuVzdelavaniePouzivatelTestovanieTestyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/pridany_stlpec_stavu_vyhodnotenia_testu_pouzivatel_testovanie_testy_table.php.stub' => database_path(
                        'migrations/2021_01_29_142000_pridany_stlpec_stavu_vyhodnotenia_testu_vzdelavanie_pouzivatel_testovanie_testy_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('PridaneIndexyPreStlpceStavUpdatedAtPouzivatelTestovanieTestyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/2021_09_17_100000_pridane_indexy_pre_stlpce_stav_updated_at_pouzivatel_testovanie_testy_table.php.stub' => database_path(
                        'migrations/2021_09_17_100000_pridane_indexy_pre_stlpce_stav_updated_at_pouzivatel_testovanie_testy_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists(
                'PridanyIndexPreStlpecPouzivatelTestovanieTestIdVzdelavaniePouzivatelTestovanieOtazkyTable',
            )) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/2021_10_21_125500_pridany_index_pre_stlpec_pouzivatel_testovanie_test_id_vzdelavanie_pouzivatel_testovanie_otazky_table.php.stub' => database_path(
                        'migrations/2021_10_21_125500_pridany_index_pre_stlpec_pouzivatel_testovanie_test_id_vzdelavanie_pouzivatel_testovanie_otazky_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists(
                'PridanyIndexPreStlpecPouzivatelTestovanieOtazkaIdVzdelavaniePouzivatelTestovanieOdpovedeTable',
            )) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/2021_10_21_125700_pridany_index_pre_stlpec_pouzivatel_testovanie_otazka_id_vzdelavanie_pouzivatel_testovanie_odpovede_table.php.stub' => database_path(
                        'migrations/2021_10_21_125700_pridany_index_pre_stlpec_pouzivatel_testovanie_otazka_id_vzdelavanie_pouzivatel_testovanie_odpovede_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('PridanyIndexPreStlpecPouzivatelIdVzdelavaniePouzivatelTestovanieTestyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/2021_10_21_130000_pridany_index_pre_stlpec_pouzivatel_id_vzdelavanie_pouzivatel_testovanie_testy_table.php.stub' => database_path(
                        'migrations/2021_10_21_130000_pridany_index_pre_stlpec_pouzivatel_id_vzdelavanie_pouzivatel_testovanie_testy_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('PridanyIndexPreStlpecTestovanieTestyIdVzdelavanieTestovanieOtazkyTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/2021_10_21_131500_pridany_index_pre_stlpec_testovanie_testy_id_vzdelavanie_testovanie_otazky_table.php.stub' => database_path(
                        'migrations/2021_10_21_131500_pridany_index_pre_stlpec_testovanie_testy_id_vzdelavanie_testovanie_otazky_table.php',
                    ),
                ], 'migrations');
            }

            if (!class_exists('PridanyIndexPreStlpecTestovanieOtazkyIdVzdelavanieTestovanieOdpovedeTable')) {
                $this->publishes([
                    __DIR__ . '/../../database/migrations/2021_10_21_131900_pridany_index_pre_stlpec_testovanie_otazky_id_vzdelavanie_testovanie_odpovede_table.php.stub' => database_path(
                        'migrations/2021_10_21_131900_pridany_index_pre_stlpec_testovanie_otazky_id_vzdelavanie_testovanie_odpovede_table.php',
                    ),
                ], 'migrations');
            }
        }
    }

    /**
     * @return void
     */
    private function loadLivewireComponents(): void
    {
        Livewire::component('Vzdelavanie::components.stav', Stav::class);
        Livewire::component('Vzdelavanie::components.pracoviska', Pracoviska::class);
        Livewire::component('Vzdelavanie::components.searchtext', SearchText::class);
        Livewire::component('Vzdelavanie::sprava.testovanie.pouzivatelia.components.zoznam', Zoznam::class);
    }
}
