<?php

namespace App\Providers;

use App\Models\Bug;
use App\Models\Profesional;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Paginator::useBootstrapFive();

        RateLimiter::for('login-cliente-web', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('login-personal-web', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('login-cliente-api', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('login-personal-api', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('login-api-general', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('recuperar-cliente', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('recuperar-personal', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('recuperar-admin', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('recuperar-admin-pregunta', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('reportar-bugs', fn (Request $request) => Limit::perHour(5)->by($request->ip()));
        RateLimiter::for('asistente-chat', fn (Request $request) => Limit::perMinute(20)->by($request->ip()));

        View::composer('profesional.*', function ($view): void {
            $credencialId = (int) session('personal_credencial_id', 0);
            $profesionalId = 0;

            if ($credencialId > 0) {
                $profesionalId = (int) Profesional::query()
                    ->where('credencialprofesional_id', $credencialId)
                    ->value('id');
            }

            $formulariosPendientesCount = 0;

            if ($profesionalId > 0) {
                $formulariosPendientesCount = DB::table('profesionales_formularios as pf')
                    ->join('formularios as f', 'f.id', '=', 'pf.formulario_id')
                    ->where('pf.profesional_id', $profesionalId)
                    ->whereRaw("LOWER(TRIM(pf.estado)) = 'pendiente'")
                    ->whereRaw("LOWER(TRIM(f.estado)) = 'pendiente'")
                    ->count();
            }

            $view->with('formulariosPendientesCount', $formulariosPendientesCount);

            $notificacionesClaves = [];
            if ($profesionalId > 0) {
                $hoy    = now()->toDateString();
                $manana = now()->addDay()->toDateString();

                $turnosHoy = DB::table('turnos as t')
                    ->where('t.profesional_id', $profesionalId)
                    ->whereDate('t.inicio', $hoy)
                    ->select('t.nombrecompleto', 't.inicio')
                    ->get();

                foreach ($turnosHoy as $turno) {
                    $nombre = trim((string) ($turno->nombrecompleto ?? 'Sin nombre'));
                    $hora   = $turno->inicio ? \Illuminate\Support\Carbon::parse((string) $turno->inicio)->format('H:i') : '-';
                    $titulo = 'Turno hoy a las ' . $hora . ' — ' . $nombre;
                    $fecha  = 'Hoy ' . $hora;
                    $notificacionesClaves[] = base64_encode('turno_hoy|' . $titulo . '|' . $fecha);
                }

                $turnosManana = DB::table('turnos as t')
                    ->where('t.profesional_id', $profesionalId)
                    ->whereDate('t.inicio', $manana)
                    ->select('t.nombrecompleto', 't.inicio')
                    ->get();

                foreach ($turnosManana as $turno) {
                    $nombre = trim((string) ($turno->nombrecompleto ?? 'Sin nombre'));
                    $hora   = $turno->inicio ? \Illuminate\Support\Carbon::parse((string) $turno->inicio)->format('H:i') : '-';
                    $titulo = 'Turno mañana a las ' . $hora . ' — ' . $nombre;
                    $fecha  = 'Mañana ' . $hora;
                    $notificacionesClaves[] = base64_encode('turno_manana|' . $titulo . '|' . $fecha);
                }

                $estadoCanceladoId = (int) DB::table('estadosturnos')->whereRaw('LOWER(TRIM(descripcion)) = ?', ['cancelado'])->value('id');
                if ($estadoCanceladoId > 0) {
                    $turnosCancelados = DB::table('turnos as t')
                        ->where('t.profesional_id', $profesionalId)
                        ->where('t.estadoturno_id', $estadoCanceladoId)
                        ->where('t.updated_at', '>=', now()->subDays(7))
                        ->select('t.nombrecompleto', 't.inicio', 't.updated_at')
                        ->get();

                    foreach ($turnosCancelados as $turno) {
                        $nombre = trim((string) ($turno->nombrecompleto ?? 'Sin nombre'));
                        $fecha  = $turno->updated_at
                            ? \Illuminate\Support\Carbon::parse((string) $turno->updated_at)->format('d/m/Y')
                            : '-';
                        $titulo = 'Turno cancelado — ' . $nombre;
                        $notificacionesClaves[] = base64_encode('turno_cancelado|' . $titulo . '|' . $fecha);
                    }
                }
            }

            $notificacionesCount = count($notificacionesClaves);
            $view->with('notificacionesCount', $notificacionesCount);
            $view->with('notificacionesClaves', $notificacionesClaves);
        });

        View::composer('administrador.*', function ($view): void {
            $bugsPendientesCount = Bug::query()
                ->whereRaw("LOWER(TRIM(estado)) = 'pendiente'")
                ->count();

            $view->with('bugsPendientesCount', $bugsPendientesCount);
        });
    }
}
