<?php

declare(strict_types=1);

namespace Seka\Portal\Modul\Statistiky\Providers;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factory;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;
use Seka\Portal\Modul\Statistiky\Console\ImportZaznamovCommand;
use Seka\Portal\Modul\Statistiky\Console\KontrolaImportuZaznamovCommand;
use Seka\Portal\Modul\Statistiky\Repositories\Eloquent\Transformers\TransformerContract;
use Seka\Portal\Modul\Statistiky\RolesAndPermissions;

/**
 * Class StatistikyServiceProvider
 *
 * @package Seka\Portal\Modul\Statistiky\Providers
 */
final class StatistikyServiceProvider extends ServiceProvider
{
    /**
     * @return void
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function boot(): void
    {
        $this->registerModulesRolesAndPermissions();

        $this->app->bind(TransformerContract::class, function () {
            // nepouziva sa
        });

        $this->mergeConfigFrom(__DIR__ . '/../Config/config.php', 'statistiky');
        $this->loadDatabaseFactories();
        $this->publishMigrations();
        $this->publishSeeders();

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

        $this->validators();
    }

    /**
     * @return void
     */
    public function register(): void
    {
        $this->commands([
            ImportZaznamovCommand::class,
            KontrolaImportuZaznamovCommand::class,
        ]);
    }

    /**
     * @return void
     */
    protected function registerModulesRolesAndPermissions(): void
    {
        $this->app->bind(RolesAndPermissions::class, function () {
            return new RolesAndPermissions();
        });

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

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

            // FRONTEND
            require __DIR__ . '/../Routes/frontend/breadcrumbs.php';
        }
    }

    /**
     * @return void
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    private function loadDatabaseFactories(): void
    {
        $this->app->make(Factory::class)->load(__DIR__ . '/../Database/factories');
    }

    /**
     * @return void
     */
    protected function publishMigrations(): void
    {
        if ($this->app->runningInConsole()) {
            if (!class_exists('CreateModulStatistikyStatistickeUdajePracoviskaTable')) {
                $this->publishes([
                    __DIR__ . '/../Database/Migrations/2021_03_16_162200_create_modul_statistiky_statisticke_udaje_pracoviska_table.php' => database_path('migrations/2021_03_16_162200_create_modul_statistiky_statisticke_udaje_pracoviska_table.php'),
                ], 'migrations');
            }

            if (!class_exists('CreateModulStatistikyHistoriaImportovTable')) {
                $this->publishes([
                    __DIR__ . '/../Database/Migrations/2021_09_14_135000_create_modul_statistiky_historia_importov_table.php' => database_path('migrations/2021_09_14_135000_create_modul_statistiky_historia_importov_table.php'),
                ], 'migrations');
            }
        }
    }

    /**
     * @return void
     */
    private function publishSeeders(): void
    {
        $this->publishes([
            __DIR__ . '/../Database/Seeders/StatistikyPouzivatelRoleOpravneniaDatabaseSeeder.php' => database_path('seeds/StatistikyPouzivatelRoleOpravneniaDatabaseSeeder.php'),
        ], 'seeds');
    }

    /**
     * @return void
     */
    private function validators()
    {
        Validator::extend('date_months_difference', function ($attribute, $value, $parameters, $validator) {
            $dateFrom = Carbon::parse($parameters[0]);
            $dateTo = Carbon::parse($parameters[1]);
            $maxDifference = (int)$parameters[2];

            if ($dateFrom->floatDiffInRealMonths($dateTo) > $maxDifference) {
                return false;
            }

            return true;
        });
    }
}
