<?php

namespace Sargilla\FlatLab\Providers;

use Artdarek\Toastr\Facades\Toastr;
use Artdarek\Toastr\Providers\ToastrServiceProvider;
use Collective\Html\FormBuilder as Form;
use Collective\Html\FormFacade;
use Collective\Html\HtmlFacade;
use Collective\Html\HtmlServiceProvider;
use Creativeorange\Gravatar\Facades\Gravatar;
use Creativeorange\Gravatar\GravatarServiceProvider;
use Illuminate\Console\DetectsApplicationNamespace;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use Intervention\Image\Facades\Image;
use Intervention\Image\ImageServiceProvider;
use Krucas\Settings\Facades\Settings;
use Krucas\Settings\Providers\SettingsServiceProvider;
use Laracasts\Flash\Flash;
use Laracasts\Flash\FlashServiceProvider;
use Prettus\Repository\Providers\RepositoryServiceProvider;
use Sargilla\FlatLab\Facades\FlatLab;
use Sargilla\FlatLab\Services\ViewComposers\ActiveLinkComposer;
use Sargilla\User\Providers\GuestUserServiceProvider;
use Spatie\Menu\Laravel\MenuFacade;
use Spatie\Menu\Laravel\MenuServiceProvider;
use Yajra\Datatables\DatatablesServiceProvider;
use Yajra\Datatables\Facades\Datatables;

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 Intervention Image
        $this->registerInterventionImageServiceProvider();

        //Registro Spatie Menu
        $this->registerSpatieMenuServiceProvider();


        //Registro Settings
        $this->registerSettingsServiceProvider();

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

        // 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\MakeAdminUserSeeder::class]);
        } 
        
    }   

    /**
     * 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 Prettus Repository.
     *
     * @return \Illuminate\Http\Response
     */
    protected function registerPrettusServiceProvider()
    {
        $this->app->register(RepositoryServiceProvider::class);
    }

    /**
     *  registerDatatablesServiceProvider
     */
    public function registerDatatablesServiceProvider()
    {
        $this->app->register(DatatablesServiceProvider::class);
        if (!class_exists('Datatables')) {
            class_alias(Datatables::class, 'Datatables');
        }
    }

     /**
     * Register Intervention Image Service Provider.
     */
    protected function registerInterventionImageServiceProvider()
    {
        $this->app->register(ImageServiceProvider::class);

        if (!class_exists('Ìmage')) {
            class_alias(Image::class, 'Image');
        }
        
    }
    /**
     * Register Intervention Image Service Provider.
     */
    protected function registerSettingsServiceProvider()
    {
        $this->app->register(SettingsServiceProvider::class);

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

    /**
     * Register Spatie Menu Service Provider.
     */
    protected function registerSpatieMenuServiceProvider()
    {
        $this->app->register(MenuServiceProvider::class);

        if (!class_exists('Menu')) {
            class_alias(MenuFacade::class, 'Menu');
        }
        
    }
  
    /**
     * 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>"; 
        });

        Form::macro('fl_uploads', function($name, $text, $value, $path, $optionsLabel = [],$optionsFileUpload = [], $uploaded = []){
            return "<div class='form-group'>" .
                        Form::label($name, $text , $optionsLabel) .
                        "<div class='col-lg-9'>
                            <p id='cargando_$name'></p>
                            <div id= 'progress_$name' class='progress progress-striped progress-sm hidden'>
                                <div class= 'progress-bar progress-bar-success' role= 'progressbar' style= 'width: 0%'>
                                      <span class= 'sr-only'></span>
                                </div>  
                            </div>
                            <div id='lista_v'>
                                @if(count($uploaded))
                                    @foreach ($uploaded as $key => $archivo)
                                        <article class='media'>
                                            <a class='pull-left thumb p-thumb'>
                                                <img src='" . $path . $archivo['name']. "' />
                                            </a> 
                                            <div class='media-body'>  
                                                <p>Archivo ". $archivo['name']. "</p>
                                                <div class='input-group'> 
                                                    <input name='" . $name[$key]['title']. "' class='form-control' type='text' placeholder='Ingrese un título' value='" . $archivo['title']. "'/>
                                                    <span class='input-group-btn'>
                                                        <button class='btn btn-danger borrar' type='button' data-archivo='$name/" . $archivo['name']. "'>
                                                        <i class='fa fa-times'></i></button>
                                                    </span>
                                                </div>
                                            </div>
                                            <input name='" . $name[$key][name]. "' type='hidden' value='" . $archivo['name']. "' />
                                        </article>  
                                    @endforeach
                                @endif
                            </div>
                            <span class='btn btn-primary active fileinput-button'>
                                <i class= 'glyphicon glyphicon-plus'></i>
                                <span>Agregar $name</span>" .
                                Form::file($name, $optionsFileUpload ) .
                            "</span>
                        </div>
                    </div>";
        });
    }
    /**
     *  registerActiveLinkComposer
     */
    private function registerActiveLinkComposer()
    {
        View::composer('flatlab::partials.sidebar', ActiveLinkComposer::class);
    }
    
    
    
}