<?php

namespace App\Http\Controllers;

use App\Models\Empleador;
use App\Models\TokenApiCorreo;
use App\Models\User;
use App\Models\Usuario;
use App\Models\UsuarioLog;
use App\Notifications\NotificacionViaCorreoSes;
use Illuminate\Support\Facades\Notification;

class Helpers
{

    public static function logger($data) {
        $output = $data;
        echo "<script>console.log('Log: " . $output . "' );</script>";
    }

    public static function menuLinkItem($text, $href, $parentTag = 'li')
    {

        $html = sprintf('<a href="%s">%s</a>', url($href), $text);

        if ($parentTag) {
            $extra = (\Request::is($href) || \Request::is($href . '/*')) ? ' class="active"' : '';
            $html = sprintf('<%s%s>%s</%s>', $parentTag, $extra, $html, $parentTag);
        }

        return $html;
    }

    public static function menuLinkItemL_Fv2($text, $href, $parentTag = 'li')
    {
        $icon = '<i class="fa fa-user-circle"></i>';

        switch ($href) {
            case 'admin/cargos-pasivos':
                $icon = '<i class="fa fa-user-circle"></i>';
            break;
            case 'admin/solicitudes-cargos-pasivos':
                $icon = '<i class="fa fa-user-circle"></i>';
            break;
            case 'admin/solicitudes-cargos-pasivos/editar':
                $icon = '<i class="fa fa-user-circle"></i>';
            break;
            case 'admin/cargos-activos':
                $icon = '<i class="fa fa-user-plus"></i>';
            break;
            case 'cargos-activos/propios':
                $icon = '<i class="fa fa-users"></i>';
            break;
            case 'cargos-activos/inscripciones':
                $icon = '<i class="fa fa-pencil-square-o"></i>';
            break;
            case 'cargos-activos/empleadores':
                $icon = '<i class="fa fa-users"></i>';
            break;
            default:
                $icon = '<i class="fa fa-user-circle"></i>';
                break;
        }
        $extra = (\Request::is($href) || \Request::is($href . '/*')) ? ' class="active"' : '';
        $html = sprintf('<a%s href="%s">%s%s</a>', $extra, url($href), $icon, $text);

        if ($parentTag) {
            $html = sprintf('<%s>%s</%s>', $parentTag, $html, $parentTag);
        }

        return $html;
    }


    public static function select($items, $selected = false)
    {

        $html = '';

        foreach ($items as $key => $value) {
            $sel = ($selected != false && (int)$selected == $key) ? 'selected' : '';
            $html .= sprintf('<option value="%s" %s>%s</option>', $key, $sel, $value);
        }

        return $html;

    }


    public static function selectGroup($items, $groupBy, $selected = null)
    {

        $groups = array();

        foreach ($items as $item) {
            $groups[$item->{$groupBy}][] = $item;
        }

        $html = '';

        foreach ($groups as $label => $items) {

            $html .= sprintf('<optgroup label="%s">', $label);

            foreach ($items as $item) {
                if ($item->id == $selected) {
                    $html .= sprintf('<option value="%s" selected>%s</option>', $item->id, $item->nombre);
                } else {
                    $html .= sprintf('<option value="%s">%s</option>', $item->id, $item->nombre);
                }
            }

            $html .= '</optgroup>';
        }

        return $html;

    }

    public static function ngModel($name, $value)
    {
        return sprintf('ng-model="%s" ng-init="%s = \'%s\'"', $name, $name, $value);
    }

    public static function json($obj, $pretty = false)
    {
        $flag = $pretty ? JSON_HEX_QUOT | JSON_PRETTY_PRINT | JSON_NUMERIC_CHECK: JSON_HEX_QUOT | JSON_NUMERIC_CHECK;
        return str_replace("'", "", json_encode($obj, $flag));
    }

    public static function primerDiaHabilMes($ano = null, $mes = null)
    {

        // \Log::info('primerDiaHabilMess');
        try {

            if (!$mes)
                $mes = (new \DateTime())->format('n');

            if (!$ano)
                $ano = (new \DateTime())->format('Y');

            $date = new \DateTime();
            $date->setDate($ano, $mes, 1);
            $date->setTime(0, 0, 0);

            $cacheKey = 'feriados-' . $ano . '-' . $mes;
            $feriados = \Cache::get($cacheKey);

            if (!$feriados) {
                $res = json_decode(file_get_contents('https://apis.digital.gob.cl/fl/feriados/' . $ano . '/' . $mes));
                $feriados = array();

                if (is_array($res)) {
                    foreach ($res as $r) {
                        $feriados[] = $r->fecha;
                    }
                }

                \Cache::put($cacheKey, $feriados, 60 * 24 * 7);
            }

            while (true) {
                if ($date->format('w') == 0) {
                    $date->add(new \DateInterval('P1D'));
                } elseif (in_array($date->format('Y-m-d'), $feriados)) {
                    $date->add(new \DateInterval('P1D'));
                } else {
                    break;
                }
            }
            return $date;

        } catch (Exception $e) {
           // \Log::info('Error - primerDiaHabilMes: '.$e->getMessage());
        }

    }

    public static function fechaLimiteParaPublicacion()
    {
        $primerDiaHabilMesActual = self::primerDiaHabilMes();
        $fecha = new \DateTime();
        if ($fecha < $primerDiaHabilMesActual)
            $fecha->modify('-1 month')->modify('first day of this month');
        else
            $fecha->modify('first day of this month');

        return $fecha;
    }

    public static function headColumn($sort, $label)
    {
        $order = \Request::get('order', false);

        if ($order) {
            if ($order == 'ASC') {
                $order = 'DESC';
            } else {
                $order = 'ASC';
            }
        } else {
            $order = 'ASC';
        }

        $page = \Request::get('page', 1);
        $params = array_merge(\Request::all(), array('sort' => $sort, 'order' => $order, 'page' => $page));
        $url = \URL::route(\Route::currentRouteName(), $params);

        $class = '';

        if (\Request::get('sort', false) == $sort) {
            $class = ($order == 'DESC') ? 'fa-chevron-up' : 'fa-chevron-down';
        }

        return '<a class="order-table-label" href="' . $url . '">' . $label . '&nbsp;<i class="fa ' . $class . '"></i></a>';
    }

    //Available formats = 'text', 'select'
    public static function filterForm($fields, $idCargoSelector = false)
    {
        //$out = '<div class="row">'; //DIV A OPEN

        $out = '<form class="" role="form" action="' . \URL::route(\Route::currentRouteName()) . '" method="GET">';

        if ($idCargoSelector != false) {
            $out .= Helpers::cargoSelector($idCargoSelector);
        }

        foreach ($fields as $key => $value) {
            $default = (\Request::has('filter-' . $key)) ? \Request::get('filter-' . $key) : '';

            $out .= '<div class="row">'; //DIV B OPEN
            //$out .= '    <label class="form-label" for="input' . $key . '">' . $value['label'] . '</label>';
            $out .= '    <div class="col-6">'; //DIV C OPEN

            if (is_array(value['options'] ?? null)) {
                //$out .= '<div class="col-sm-12">'; //DIV D OPEN
                $out .= '<select name="filter-' . $key . '" class="form-select">';
                $out .= '<option value="">Seleccione ' . $value['label'] . '</option>';

                foreach ($value['options'] as $opValue => $opLabel) {
                    $selected = ($opValue == $default) ? 'selected' : '';
                    $out .= '<option value="' . $opValue . '" ' . $selected . '>' . $opLabel . '</option>';
                }

                $out .= '</select>';
                //$out .= '</div>'; //DIV D CLOSE
            } else {
                $out .= '<input type="text" class="form-control" placeholder=" '.$value['label'].'" id="input' . $key . '" name="filter-' . $key . '" value="' . $default . '"/>';
            }

            $out .= '    </div>'; //DIV C CLOSE
            //$out .= '</div>'; //DIV B CLOSE

        }

        $out .= '<div class="col-6">';
        $out .= '    <div class="text-left">';
        $out .= '        <button type="submit" class="btn btn-outline-primary me-2">Buscar</button>';
        $out .= '        <a href="' . \URL::route(\Route::currentRouteName()) . '" class="btn btn-outline-primary">Limpiar</a>';
        $out .= '    </div>';
        $out .= '</div>';
        $out .= '</div>'; //DIV B CLOSE v2

        $out .= "</form>";

        //$out .= '</div>'; //DIV A CLOSE

        return $out;
    }

    public static function cargoSelector($idCargo)
    {
        $out = '';

        $cargos = array();

        if (\Auth::user()->root) {
            $cargos = Pertenencia::cargosPasivos()->get();
        } elseif (\Auth::user()->hasRol('admin', 'auditor', 'digitador')) {
            $cargos = \Auth::user()->selectedPertenencia()->institucion->pertenencias()->cargosPasivos()->get();
        } else {
            $cargos = array();
        }

        if (count($cargos) > 1) {
            $final = array();

            foreach ($cargos as $key => $value) {
                if(!is_null($value->usuario)){
                    $final[$value->id] = \Str::limit($value->institucion->nombre,40) . ' - ' . \Str::limit($value->cargo,40).' - '.$value->usuario->nombres.' '.$value->usuario->apellidos;
                }
                else{
                    $final[$value->id] = \Str::limit($value->institucion->nombre,40) . ' - ' . \Str::limit($value->cargo,40);
                }
            }

            asort($final);

            $out = '<div class="form-group col-sm-12">';
            $out .= '    <label class="col-sm-3" for="input">Institución / Cargo</label>';

            $out .= '<div class="col-sm-9"><select name="filter-' . $idCargo . '" class="form-control">' .
                '<option value="">Seleccione una institución / cargo</option>' .
                \Helpers::select($final, \Request::has('filter-' . $idCargo) ? \Request::get('filter-' . $idCargo) : false) .
                '</select></div>';

            $out .= '</div>';

        } else {
            $out = '';
        }


        return $out;
    }

    public static function getHumanRol($pasivo, $jefe, $rol)
    {
        $resp = array();

        if ($pasivo) {
            $resp[] = 'Sujeto Pasivo';
        }

        if ($jefe) {
            $resp[] = 'Jefe de Servicio';
        }

        if (count($resp) > 0) {
            return implode(' ', $resp);
        }

        if ($rol == 'Admin') {
            return 'Administrador Institucional';
        }

        return $rol;
    }

    public static function cleanRUT($value)
    {
        return preg_replace('/[^0-9k\-]/i', '', strtolower($value));
    }

    public static function getPersona($pais, $rut,$forceRegistroCivil = false)
    {

        $url = env('registro_civil_url');
        $token = env('registro_civil_token');
        $user = env('registro_civil_user');
        $password = env('registro_civil_password');
        $u = null;
        if ($pais != 'CHL' || (Usuario::isRUNValid($rut) && $pais == 'CHL')) {
            $usuario = ($forceRegistroCivil)?null:Usuario::where('pasaporte', '=', $rut)->where('pais_id', '=', $pais)->first();

            if (($forceRegistroCivil || $usuario == null) && $pais == 'CHL') {

                $rut = preg_replace('/[^0-9k]/i', '', $rut);
                $rut = strtoupper($rut);
                if (strlen($rut) < 2) {
                    throw new \LobbyHTTPException(404, 'El Rut/Pasaporte ingresado no es válido');
                }
                $dv = substr($rut, -1);
                $number = substr($rut, 0, strlen($rut) - 1);
                $url = $url . '?rut=' . $number . '&dv=' . $dv . '&pisee_token=' . $token;
                $handler = curl_init($url);
                curl_setopt($handler, CURLOPT_HTTPGET, true);
                curl_setopt($handler, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($handler, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
                curl_setopt($handler, CURLOPT_USERPWD, $user.":".$password);
                curl_setopt($handler, CURLOPT_FRESH_CONNECT, true);

                //curl_setopt($handler, CURLOPT_CAINFO, storage_path()."/2017_pisee.pem");
                curl_setopt($handler, CURLOPT_SSL_VERIFYPEER, false);
                /*if (getenv('debug')) {
                    curl_setopt($handler, CURLOPT_SSL_VERIFYPEER, true);
                }*/


                $exec = curl_exec($handler);
                $response = json_decode($exec);
                if ($response != null && $response->rut !== null) {
                    $u = new \stdClass();
                    $usuario = $response;
                    $u->nombres = $usuario->nombres;
                    $u->apellidos = $usuario->apellidoPaterno . ' ' . $usuario->apellidoMaterno;
                    $u->pasaporte = $usuario->rut . '-' . $usuario->dv;
                    $u->pais_id = $pais;
                }
            } else if ($usuario != null) {
                $u = new \stdClass();
                $u->id = $usuario->id;
                $u->nombres = $usuario->nombres;
                $u->apellidos = $usuario->apellidos;
                $u->pasaporte = $usuario->pasaporte;
                $u->pais_id = $usuario->pais_id;
                $u->email = $usuario->email;
                $u->telefono = $usuario->telefono;
                $u->otro_contacto = $usuario->otro_contacto;
            }
            if ($u != null) {
                return $u;
            } else {
                throw new \LobbyHTTPException(404, 'No existe usuario asociado al Rut/Pasaporte ingresado');
            }
        } else {
            throw new \LobbyHTTPException(404, 'El Rut/Pasaporte ingresado no es válido');
        }
    }

    public static function getEmpleador($pais, $rut)
    {
        $usuarioRegistrado = \Auth::user();
        if ($pais != 'CHL' || (Usuario::isRUNValid($rut) && $pais == 'CHL')) {
            $empleador = Empleador::where('pasaporte', '=', $rut)->where('pais_id', '=', $pais)->first();
            if ($empleador != null) {
                $e = new \stdClass();
                $e->id = $empleador->id;
                $e->nombre = $empleador->nombre;
                $e->pasaporte = $empleador->pasaporte;
                $e->pais_id = $empleador->pais_id;
                $e->actividades = $empleador->actividades;
                $e->giro = $empleador->giro;
                $e->domicilio = $empleador->domicilio;
                $e->representante_legal = $empleador->representante_legal;
                $e->naturaleza = $empleador->naturaleza;
                $e->directorio = $empleador->directorio;
                return $e;
            } else {
                throw new \LobbyHTTPException(404, 'No existe empresa asociada al Rut/Pasaporte ingresado');
            }
        } else {
            throw new \LobbyHTTPException(404, 'El Rut/Pasaporte ingresado no es válido');
        }
    }

    public static function my_ucfirst($string, $e ='utf-8') {
        if (function_exists('mb_strtoupper') && function_exists('mb_substr') && !empty($string)) {
            $string = mb_strtolower($string, $e);
            $upper = mb_strtoupper($string, $e);
                preg_match('#(.)#us', $upper, $matches);
                $string = $matches[1] . mb_substr($string, 1, mb_strlen($string, $e), $e);
        }
        else {
            $string = ucfirst($string);
        }
        return $string;
    }

    public static function sendEmail($email, $subject, $template, $data = null, $files = null)
    {

        $contenido = \View::make($template)->with($data)->render();

        $contenido_encode = base64_encode( \Helpers::tildesHtml($contenido));

        if (strpos($email, ',') !== false) {
           $destinatarios = explode(',', env('email_reporte_cplt'));
        }
        else{
            $destinatarios = array($email);
        }

        //is_array($email) ?  $destinatarios = $email :  $destinatarios = array($email) ;

        $arrayName = array('from' => env('from_api_correo'),
                            'to' => $destinatarios,
                            'subject' => base64_encode($subject),
                            'body' => $contenido_encode,
                            'token_app' => env('token_app_api_correo')
                            );


        if(isset(env('test_email_receiver')) && !is_null(env('test_email_receiver')) && env('debug') &&  \Request::root()!='https://www.leylobby.gob.cl' ){

            $arrayName['test_email_receiver' ] = [env('test_email_receiver')];
        }

        if(!is_null($files)){
            //adjuntar archivo
            $arrayName['files'] = [ $files ];

        }
        $url = env('url_api_correo').'/'.env('path_api_correo');

        $token = \Helpers::getAPiCorreosAuth();

        if($token){

            $authorization = "Authorization: Bearer ".$token;

            $ch = curl_init( $url );

            $payload = json_encode( $arrayName);

            try {
                curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "POST");
                curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
                curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json; charset=utf-8', $authorization));
                curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );

                $result = curl_exec($ch);
                $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                curl_close($ch);

                $result = json_decode($result);

                if($httpcode == '200'){

                    $log_data = array('mensaje_id' => $result->MessageId, 'destinatario' => $email, 'asunto' => $subject, 'contenido' => $contenido_encode);
                    $log_data = json_encode( $log_data);

                    if(!is_null(\Auth::user())){
                        \Auth::user()->log('send_email', 'no-aplica', 0, $log_data);
                    }
                    else{
                        \Log::info('Envio correo - Mensaje id: '.$result->MessageId.', Email: '.$email.', Template: '.$template.', Subject: '.$subject.', Contenido '.$contenido);
                    }

                }
                else{

                    if($httpcode == '202'){
                        \Log::info('Code : '.$httpcode.', Email: '.$email.', Template: '.$template.', Subject: '.$subject.', Contenido '.$contenido);
                    }
                    else{
                        \Log::error('Error envio correo - Email: '.$email.', Code : '.$httpcode.', Template: '.$template.', DATA: '.json_encode($data).', Response mensaje: '.$result->error );
                    }

                }

            } catch (Exception $e) {
                \Log::error('Error envio correo - Email: '.$email.', Template: '.$template.', DATA: '.json_encode($data).', Mensaje error: '.$e->getMessage() );
            }


        }
        else{

            \Log::error('Error envio correo - Email: '.$email.', Template: '.$template.', DATA: '.json_encode($data).', Mensaje error: No es posible obtener token de acceso' );
        }


    }

    public static function sendEmailv2($recipient, $subject, $template, $data = null, $files = null)
    {
        $uniqueID = \Str::random(30);

        if (strpos($recipient, ',') !== false) {
            $destinatarios = explode(',', env('email_reporte_cplt'));
        }
        else{
            $destinatarios = array($recipient);
        }

        //CORREO
        try{
            Notification::route('mail', $destinatarios)->notify(new NotificacionViaCorreoSes($uniqueID, $recipient, $subject, $template, $data, $files));
        }
        catch(\Exception $e){
            \Log::error('Error envio correo - Email: '.$recipient.', Template: '.$template.', DATA: '.json_encode($data).', Mensaje error: '.$e->getMessage() );
        }
    }

    public static function getAPiCorreosAuth()
    {
        try {

            //Preguntar por token almacenado
            $token  = TokenApiCorreo::where('expires_date', '>', (new \DateTime())->format('Y-m-d H:i:s') )->first();

            if(!is_null ($token)){
                return $token->access_token;

            }else{
                //Almacenar token en la base de datos
                return null; //HCM Temporalmente para permitir guardar usuario
                $curl   = curl_init( env('url_token_oauth2'));
                curl_setopt( $curl, CURLOPT_POST, true );
                curl_setopt( $curl, CURLOPT_POSTFIELDS, array(
                    'client_id' => env('client_id_api_correos'),
                    'client_secret' => env('client_secret_api_correos'),
                    'grant_type' => 'client_credentials',
                    'scope' => 'sendmail',
                ) );
                curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1);
                $auth = curl_exec( $curl );
                $auth = json_decode($auth);
                $access_key = $auth->access_token;
                $old_token = TokenApiCorreo::whereNotNull('id')->delete();
                $token = new TokenApiCorreo();
                $token->access_token    = $auth->access_token;
                $token->expires_in      = $auth->expires_in;
                $fecha                  = \Carbon\Carbon::now();

                $token->expires_date    = $fecha->addSeconds($token->expires_in - 800)->toDateTimeString();
                $token->save();
                return $access_key;
            }

        } catch (Exception $e) {
            \Log::error('Error getAPiCorreosAuth: '.$e->getMessage() );
            return false;
        }

    }

    public static function tildesHtml($cadena)
    {
        return str_replace(array("á","é","í","ó","ú","ñ","Á","É","Í","Ó","Ú","Ñ"),
                                         array("&aacute;","&eacute;","&iacute;","&oacute;","&uacute;","&ntilde;",
                                                    "&Aacute;","&Eacute;","&Iacute;","&Oacute;","&Uacute;","&Ntilde;"), $cadena);
    }

    public static function horaChile($fecha, $formato)
    {
        if(!is_null($fecha)){

            if( ($fecha >= "2016-05-14" && $fecha < "2016-08-14") ||  ($fecha >= "2017-05-14" && $fecha < "2017-08-12") ||  ($fecha >= "2018-05-13" && $fecha < "2018-08-11"))
            {
                //Horario invierno
                $fecha = date($formato,strtotime($fecha." - 4 hours"));

            }
            else{
                //Horario verano
                $fecha = date($formato,strtotime($fecha." - 3 hours"));
            }

        }

        return $fecha;
    }

    public static function calculaFechaPublicacion($id, $materia, $conexion)
    {
        $fecha_publicacion = null;

        ($materia == 'audiencia')? $estado = 'publicada' : $estado = 'publicado';

        $log = UsuarioLog::on($conexion)->where('objeto_id', '=', $id)
                            ->where('tipo', '=', $materia)
                            ->where('antes','ilike', '%"estado":"borrador"%')
                            ->where('despues', 'ilike', '%"estado":"'.$estado.'"%')
                            ->orWhere(function($query) use ($materia, $id, $estado)
                            {
                                $query->where('objeto_id', '=', $id)
                                    ->where('tipo', '=', $materia)
                                    ->where('antes','=', 'null')
                                    ->where('despues', 'ilike', '%"estado":"'.$estado.'"%');
                            })
                            ->first();

        //Aplicar la zona horaria a la fecha
        if(!is_null($log)){

            if($log->created_at < "2016-05-14" || $log->created_at >= "2016-08-14" ){

               $fecha_publicacion  =  $log->created_at->timezone('America/Argentina/Buenos_Aires')->format('Y-m-d');
            }
            else
            {
                 $fecha_publicacion  =  $log->created_at->timezone('America/Santiago')->format('Y-m-d');
            }

        }

        //if(is_null($fecha_publicacion)) \Log::info('calculaFechaPublicacion - Fecha publicación nula - ID : '.$id." , Materia: ".$materia);

        return $fecha_publicacion;

    }

    public static function enviarCorreoAdmin($periodo, $subject )
    {
        //Obtener administradores institucionales

        $admins = Pertenencia::where('rol', '=', 'admin')->validos()->get();

        foreach ($admins as $admin) {

            if(!is_null($admin->usuario)){
                echo $admin->usuario->email.'------';
                // \Helpers::sendEmail($admin->usuario->email, $subject, 'admin/reporte-cplt/template_email_termino',  ['periodo' => $periodo, 'error' => true] );
            }
        }

    }

    public static function diasHabiles($fecha_ingreso = null, $fecha_final = null)
    {
        $fecha_ingreso = \Carbon\Carbon::parse($fecha_ingreso)->format('Y-m-d');
        $fecha_actual = '';
        if(!$fecha_final !== null) {
            $fecha_actual = \Carbon\Carbon::now('America/Santiago')->format('Y-m-d');
        }
        else {
            $fecha_actual = \Carbon\Carbon::parse($fecha_final)->format('Y-m-d');
        }

        $dia = \Carbon\Carbon::parse($fecha_actual)->day;
        $mes = \Carbon\Carbon::parse($fecha_actual)->month;
        $ano = \Carbon\Carbon::parse($fecha_actual)->year;
        $cacheKey = 'feriados-' . $ano . '-' . $mes;

        // Código para debub: \Cache::forget($cacheKey);
        if(\Cache::has($cacheKey)) {
            $feriados = \Cache::get($cacheKey);
        }
        else {
            $sJsonDatos = @file_get_contents('https://apis.digital.gob.cl/fl/feriados/'.$ano.'/'.$mes);
            if(!$sJsonDatos) { // Si no fue posible obtener datos
                return -404;
            }
            else {

                $res = json_decode($sJsonDatos);
                $feriados = array();
                if (is_array($res)) {
                    foreach ($res as $r) {
                        $feriados[] = $r->fecha;
                    }
                }
                \Cache::put($cacheKey, $feriados, 60 * 24 * 7);
            }
        }
        return self::getWorkingDays($fecha_ingreso,$fecha_actual,$feriados);
    }

    public static function getWorkingDays($startDate,$endDate,$holidays)
    {
        // do strtotime calculations just once
        $endDate = strtotime($endDate);
        $startDate = strtotime($startDate);


        //The total number of days between the two dates. We compute the no. of seconds and divide it to 60*60*24
        //We add one to inlude both dates in the interval.
        $days = ($endDate - $startDate) / 86400 + 1;

        $no_full_weeks = floor($days / 7);
        $no_remaining_days = fmod($days, 7);

        //It will return 1 if it's Monday,.. ,7 for Sunday
        $the_first_day_of_week = date("N", $startDate);
        $the_last_day_of_week = date("N", $endDate);

        //---->The two can be equal in leap years when february has 29 days, the equal sign is added here
        //In the first case the whole interval is within a week, in the second case the interval falls in two weeks.
        if ($the_first_day_of_week <= $the_last_day_of_week) {
            if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) $no_remaining_days--;
            if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) $no_remaining_days--;
        }
        else {
            // (edit by Tokes to fix an edge case where the start day was a Sunday
            // and the end day was NOT a Saturday)

            // the day of the week for start is later than the day of the week for end
            if ($the_first_day_of_week == 7) {
                // if the start date is a Sunday, then we definitely subtract 1 day
                $no_remaining_days--;

                if ($the_last_day_of_week == 6) {
                    // if the end date is a Saturday, then we subtract another day
                    $no_remaining_days--;
                }
            }
            else {
                // the start date was a Saturday (or earlier), and the end date was (Mon..Fri)
                // so we skip an entire weekend and subtract 2 days
                $no_remaining_days -= 2;
            }
        }

        //The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder
        //---->february in none leap years gave a remainder of 0 but still calculated weekends between first and last day, this is one way to fix it
        $workingDays = $no_full_weeks * 5;
        if ($no_remaining_days > 0 )
        {
          $workingDays += $no_remaining_days;
        }

        //We subtract the holidays
        foreach($holidays as $holiday){
            $time_stamp=strtotime($holiday);
            //If the holiday doesn't fall in weekend
            if ($startDate <= $time_stamp && $time_stamp <= $endDate && date("N",$time_stamp) != 6 && date("N",$time_stamp) != 7)
                $workingDays--;
        }

        return $workingDays;
    }

    public static function isWeekend($date)
    {
        $weekDay = date('w', strtotime($date));
        return ($weekDay == 0 || $weekDay == 6);
    }

    public static function getPuntosRut($originalRut, $incluyeDigitoVerificador = true)
    {
        $originalRut = trim($originalRut);
        $originalRut = ltrim($originalRut, '0');
        $input      = str_split($originalRut);
        $cleanedRut = '';

        foreach ($input as $key => $chr) {

            //Digito Verificador
            if ((($key + 1) == count($input)) && ($incluyeDigitoVerificador)){
                if (is_numeric($chr) || ($chr == 'k') || ($chr == 'K'))
                    $cleanedRut .= '-'.strtoupper($chr);
                else
                    return false;
            }

            //Números del RUT
            elseif (is_numeric($chr))
                    $cleanedRut .= $chr;
        }

        if (strlen($cleanedRut) < 3)
            return false;

        $rutTmp = explode("-",$cleanedRut);
        return number_format($rutTmp[0], 0, "", ".") . '-' . $rutTmp[1];
    }


    /**
     * Agrega filtro where a un objeto QueryBuilder Eloquent de
     * una grilla a partir de los filtros (campos) del
     * formulario html de búsqueda correspondiente.
     *
     * @param  Illuminate\Database\Eloquent\Model  $oObjetoQueryBuilderLaravel
     * @param  String  $sNombreCampoDeBaseDatos
     * @param  String  $sComparadorWhere
     * @param  String  $sNombreCampoHtmlDelFiltroEnLaVista
     * @param  Array  $aArregloDatosParaLaVista
     * @return App\Models\CargoActivo
     */
    public static function AgregarFiltroAConsultaDeGrilla(
        $oObjetoQueryBuilderLaravel,
        $sNombreCampoDeBaseDatos,
        $sComparadorWhere,
        $sNombreCampoHtmlDelFiltroEnLaVista,
        &$aArregloDatosParaLaVista = null,
    ) {
        $bExisteFiltro = \Request::has($sNombreCampoHtmlDelFiltroEnLaVista);

        $sValorFiltro = '';
        if($bExisteFiltro) {
            $sValorFiltro = trim(strip_tags(
                \Request::get($sNombreCampoHtmlDelFiltroEnLaVista)
            ));
            $bExisteFiltro = strlen($sValorFiltro); // Si el valor del filtro no es vacio
        }

        if($bExisteFiltro) {

            // Agregar filtro persona a la consulta SQL
            $aComparadoresValidos = [ // futuras implementaciones: '%like', 'like%'
                '=', '>=', '<=', 'ilike', 'f>=', 'f<=', 'r='
            ];

            $sComparadorWhere = trim($sComparadorWhere);
            $sValorFiltroFormateado = $sValorFiltro;
            if(!in_array($sComparadorWhere, $aComparadoresValidos))
            {
                throw new \LobbyHTTPException(
                    500, 'Comparador no soportado. (' . __LINE__ . ')'
                );
            }
            else if($sComparadorWhere == 'like') {
                $sValorFiltroFormateado = '%' . $sValorFiltro . '%';
            }
            else if($sComparadorWhere == 'f>=') {
                $sValorFiltroFormateado = $sValorFiltro . ' 00:00:00';
                $sComparadorWhere = '>=';
            }
            else if($sComparadorWhere == 'f<=') {
                $sValorFiltroFormateado = $sValorFiltro . ' 23:59:59';
                $sComparadorWhere = '<=';
            }
            else if($sComparadorWhere == 'r=' ) {
                    $sNombreCampoDeBaseDatos = \DB::raw($sNombreCampoDeBaseDatos);
                    $sComparadorWhere = '=';
            }

            $oObjetoQueryBuilderLaravel->where(
                $sNombreCampoDeBaseDatos,
                $sComparadorWhere,
                $sValorFiltroFormateado
            );
        }

        $aArregloDatosParaLaVista[
            $sNombreCampoHtmlDelFiltroEnLaVista
        ] = $sValorFiltro;

        return $oObjetoQueryBuilderLaravel;
    }
}

?>
