<?php

namespace Sargilla\FlatLab\Providers;

use Laracasts\Flash\Flash;
use Collective\Html\FormFacade;
use Collective\Html\HtmlFacade;
use Artdarek\Toastr\Facades\Toastr;
use Illuminate\Support\Facades\View;
use Sargilla\FlatLab\Facades\FlatLab;
use Illuminate\Support\ServiceProvider;
use Collective\Html\FormBuilder as Form;
use Collective\Html\HtmlServiceProvider;
use Laracasts\Flash\FlashServiceProvider;
use Creativeorange\Gravatar\Facades\Gravatar;
use Yajra\Datatables\DatatablesServiceProvider;
use Illuminate\Console\DetectsApplicationNamespace;
use Creativeorange\Gravatar\GravatarServiceProvider;
use Artdarek\Toastr\Providers\ToastrServiceProvider;
use \InfyOm\Generator\InfyOmGeneratorServiceProvider;
use Sargilla\User\Providers\GuestUserServiceProvider;
use Prettus\Repository\Providers\RepositoryServiceProvider;
use \InfyOm\AdminLTETemplates\AdminLTETemplatesServiceProvider;
use Sargilla\FlatLab\Services\ViewComposers\ActiveLinkComposer;
use Jlapp\Swaggervel\SwaggervelServiceProvider;

class FlatLabServiceProvider extends ServiceProvider
{

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        if (!defined('FLATLAB_PATH')) {
            define('FLATLAB_PATH', realpath(__DIR__.'/../../'));
        }

        // Registra clase FlatLab
        $this->app->bind('FlatLab', function () {
            return new \Sargilla\FlatLab\FlatLab();
        });

        // Registra clase GuesUser
        if (config('flatlab.guestuser', true)) {
            $this->registerGuestUserProvider();
        }

        // Registra clase Gravatar
        if (config('flatlab.gravatar', true)) {
            $this->registerGravatarServiceProvider();
        }

        // Registra clase LaravelCollective/Forms&Html
        $this->registerLaravelCollectiveServiceProvider();

        // Registro Laracasts Flash
        $this->registerLaracastsFlashProvider();

        // Registro Toastr
        $this->registerToastrServiceProvider();

        // Registro Datatables
        $this->registerDatatablesServiceProvider();

        // Registro Prettus Repository
        $this->registerPrettusServiceProvider();

        // Registro InfyOM
        $this->registerInfyOmServiceProvider();

        // Registro Swaggervel
        $this->registerSwaggervelServiceProvider();

        // Registra Comandos x consola
        if ($this->app->runningInConsole()) {
            $this->commands([\Sargilla\FlatLab\Console\PublishFlatLab::class]);
            $this->commands([\Sargilla\FlatLab\Console\InstallFlatLab::class]);
            //$this->commands([\Sargilla\FlatLab\Console\MakeRoute::class]);
            $this->commands([\Sargilla\FlatLab\Console\MakeV::class]);
        } 

        /**
         * Register Migrations
         */
        $this->loadMigrationsFrom(FLATLAB_PATH .'/database/migrations');

        
    }   

    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->publishConfig();
        $this->publishLanguages();
        $this->publishViews();
        $this->viewsToOverwrite();
        $this->publishGravatar();
        $this->publishPublicAssets();
        $this->publishResourceAssets();
        $this->changeLoginController();
        $this->changeForgotPasswordController();
        $this->changeRegisterController();
        $this->changeResetPasswordController();
        $this->changeResetPasswordNotification();
        $this->changeUserModel();
        $this->publishHomeController();
        $this->publishWebRoutes();
        $this->publishApiRoutes();
        $this->publishMacrosLaravelCollective();
        $this->registerActiveLinkComposer();
    }


    /**
     * Register Guest User Provider.
     */
    protected function registerGuestUserProvider()
    {
        $this->app->register(GuestUserServiceProvider::class);
    }

    /**
     * Register LaracastsFlash Service Provider.
     */
    protected function registerLaracastsFlashProvider()
    {
        $this->app->register(FlashServiceProvider::class);
         if (!class_exists('Flash')){
            class_alias(Flash::class, 'Flash');
        }
    }

    /**
     * Register Gravatar Service Provider.
     */
    protected function registerGravatarServiceProvider()
    {
        $this->app->register(GravatarServiceProvider::class);
        if (!class_exists('Gravatar')) {
            class_alias(Gravatar::class, 'Gravatar');
        }
    }

    /**
     * Register Laravel Collective Service Provider.
     */
    protected function registerLaravelCollectiveServiceProvider()
    {
        $this->app->register(HtmlServiceProvider::class);

        if (!class_exists('Form')) {
            class_alias(FormFacade::class, 'Form');
        }
        if (!class_exists('Html')) {
            class_alias(HtmlFacade::class, 'Html');
        }
    }

    /**
     *  registerToastrServiceProvider
     */
    protected function registerToastrServiceProvider()
    {
        $this->app->register(ToastrServiceProvider::class);

        if (!class_exists('Toastr')){
            class_alias(Toastr::class, 'Toastr');
        }
    }

    /**
     *  Registro de InfyOm.
     *
     * @return \Illuminate\Http\Response
     */
    protected function registerInfyOmServiceProvider()
    {
        $this->app->register(InfyOmGeneratorServiceProvider::class);
        $this->app->register(AdminLTETemplatesServiceProvider::class);

    }

    /**
     *  Registro de Prettus Repository.
     *
     * @return \Illuminate\Http\Response
     */
    protected function registerPrettusServiceProvider()
    {
        $this->app->register(RepositoryServiceProvider::class);
    }

    /**
     * Registro Swager.
     *
     * @return \Illuminate\Http\Response
     */
    protected function registerSwaggervelServiceProvider()
    {
        $this->app->register(SwaggervelServiceProvider::class);
    }
    

    /**
     *  registerDatatablesServiceProvider
     */
    public function registerDatatablesServiceProvider()
    {
        $this->app->register(DatatablesServiceProvider::class);
    }
    
    /**
     * Publish FlatLab package config.
     */
    private function publishConfig()
    {
        $this->publishes(FlatLab::config(), 'config-flatlab');
    }

    /**
     * Publish package language to Laravel project.
     */
    private function publishLanguages()
    {
        $this->loadTranslationsFrom(FLATLAB_PATH.'/resources/lang/', 'flatlab');

        $this->publishes(FlatLab::languages(), 'lang-flatlab');
    }

    /**
     * Publish package views to Laravel project.
     */
    private function publishViews()
    {
        $this->loadViewsFrom(FLATLAB_PATH.'/resources/views/flatlab/', 'flatlab');
        $this->loadViewsFrom(FLATLAB_PATH.'/resources/views/mail/', 'flatlab');
        $this->loadViewsFrom(FLATLAB_PATH.'/resources/views/notifications/', 'flatlab');

        $this->publishes(FlatLab::views(), 'views-flatlab');
    }

    /**
     *  Overwrite Views.
     */
    private function viewsToOverwrite()
    {
        $this->publishes(FlatLab::viewsToOverwrite(), 'overwriteviews-flatlab');
    }

    /**
     * Publish config Gravatar file using group.
     */
    private function publishGravatar()
    {
        $this->publishes(FlatLab::gravatar(), 'gravatar');
    }

    /**
     * Publish public resource assets to Laravel project.
     */
    private function publishPublicAssets()
    {
        $this->publishes(Flatlab::publicAssets(), 'flatlab');
    }
    
    /**
     * Publish package resource assets to Laravel project.
     */
    private function publishResourceAssets()
    {
        $this->publishes(FlatLab::resourceAssets(), 'flatlab');
    }

    /**
     * Change default Laravel LoginController.
     */
    private function changeLoginController()
    {
        $this->publishes(FlatLab::loginController(), 'flatlab');
    }

    /**
     * Change default Laravel forgot password Controller.
     */
    private function changeForgotPasswordController()
    {
        $this->publishes(FlatLab::forgotPasswordController(), 'flatlab');
    }

    /**
     * Change default Laravel RegisterController.
     */
    private function changeRegisterController()
    {
        $this->publishes(FlatLab::registerController(), 'flatlab');
    }

    /**
     * Change default Laravel reset password Controller.
     */
    private function changeResetPasswordController()
    {
        $this->publishes(FlatLab::resetPasswordController(), 'flatlab');
    }

    /**
     * Change default Laravel reset password Controller.
     */
    private function changeResetPasswordNotification()
    {
        $this->publishes(FlatLab::PasswordResetNotification(), 'flatlab');
    }

    /**
     * Change default Laravel reset password Controller.
     */
    private function changeUserModel()
    {
        $this->publishes(FlatLab::UserModel(), 'flatlab');
    }
    
    /**
     * Publish Home Controller.
     */
    private function publishHomeController()
    {
        $this->publishes(FlatLab::homeController(), 'flatlab');
    }

    /**
     * Publish routes/web.php file.
     */
    private function publishWebRoutes()
    {
        $this->publishes(FlatLab::webroutes(), 'flatlab');
    }

    /**
     * Publish routes/api.php file.
     */
    private function publishApiRoutes()
    {
        $this->publishes(FlatLab::apiroutes(), 'flatlab');
    }
    /**
     *  publisMacrosLaravelCollective
     *  Carga las macros para Laravel Collective
     */
    private function publishMacrosLaravelCollective()
    {

        Form::macro('fl_labelCheck',function($name, $text, $value, $options = []){
            return "<div class='form-group'>
                        <div class='col-lg-9 col-lg-offset-3'>".
                            Form::checkbox($name, $value, null, ['id'=>$name]) .
                            "<div class='btn-group'>" .
                            "<label for='" . $name . "' class='" . $options['class']. "'><span class='glyphicon glyphicon-ok'></span><span> <span></label> " .
                            Form::label($name, $text, $options). 
                            "</div>
                        </div>
                    </div>";
        });

        Form::macro('fl_textarea',function($name, $text, $value, $optionsLabel = [] ,$optionsTextarea = []){
           return "<div class='form-group'>".
                       Form::label($name, $text ,$optionsLabel) .  
                       "<div class='col-lg-9'>".
                       Form::textarea($name, $value , $optionsTextarea) .
                       "</div>
                   </div>"; 
        });

        Form::macro('fl_text',function($name, $text, $value, $optionsLabel = [],$optionsText = [], $errors = []){

            $errorLabel = $clase = '';

            if($errors->has($name)){
                $clase = ' has-error';
                $errorLabel =  '<label for='.$name.' class="error">'. $errors->first($name).'</label>';
            }

            return "<div class='form-group" . $clase . "'>" .
                        Form::label($name, $text, $optionsLabel) .
                        "<div class='col-lg-9'>".
                            Form::text($name, $value , $optionsText) . $errorLabel .
                        "</div>
                    </div>"; 
        });
    }
    /**
     *  registerActiveLinkComposer
     */
    private function registerActiveLinkComposer()
    {
        View::composer('flatlab::partials.sidebar', ActiveLinkComposer::class);
    }
    
    
}