<?php

namespace App\Services;

use Illuminate\Support\ServiceProvider;
use JetBrains\PhpStorm\ArrayShape;

class PaginatorService extends ServiceProvider {

    /**
     * Crea una lista asociativa que indica como paginar una lista de elementos.
     * @param $perPage int Cuantos elementos se van a mostrar por pagina
     * @param $page int Que pagina se va a mostrar ahora
     * @param $total int Cuantos elementos en total hay
     * @return array Una lista asociativa conteniendo todos los datos a saber para realizar la paginación
     */
    #[ArrayShape([
        'per_page' => "int",
        'from' => "int",
        'to' => "int",
        'total' => "int",
        'current_page' => "int",
        'last_page' => "int",
        'links' => 'array'
    ])]
    public function paginate(int $perPage, int $page, int $total, string $route, array $data = []) {
        // Se mostraran entre 1 o mas elementos por pagina
        $perPage = max(1, $perPage);

        // Se necesita saber cuantas paginas son, no recuerdo porque la formula funciona, pero lo hace
        $lastPage = floor(($total + $perPage - 1) / $perPage);

        // Se necesita la pagina, la cual debe estar entre 1 y el numero de paginas calculadas previamente
        $currentPage = min($lastPage, max(1, $page));

        // Cuantos elementos se van a saltar para empezar a tomar usuarios
        $skip = ($currentPage - 1) * $perPage;

        return [
            'per_page' => $perPage,
            'from' => max(0, $skip + 1),
            'to' => min($total, $skip + $perPage),
            'total' => $total,
            'current_page' => $currentPage,
            'last_page' => $lastPage,
            'links' => [
                'first' => route($route, array_merge(['page' => 1, 'per_page' => $perPage], $data)),
                'prev' => $currentPage - 1 >= 1 ? route($route, array_merge(['page' => $currentPage - 1, 'per_page' => $perPage], $data)) : null,
                'current' => route($route, array_merge(['page' => $currentPage, 'per_page' => $perPage], $data)),
                'next' => $currentPage + 1 <= $lastPage ? route($route, array_merge(['page' => $currentPage + 1, 'per_page' => $perPage], $data)) : null,
                'last' => route($route, array_merge(['page' => $lastPage, 'per_page' => $perPage], $data)),
            ]
        ];
    }
}
