<?php
declare(strict_types=1);

namespace App\Core;

final class Pagination
{
    public static function paginate(int $totalItems, int $perPage, int $currentPage): array
    {
        $perPage = max(1, $perPage);
        $lastPage = max(1, (int) ceil($totalItems / $perPage));
        $currentPage = max(1, min($currentPage, $lastPage));
        $from = ($currentPage - 1) * $perPage + 1;
        $to = min($currentPage * $perPage, $totalItems);

        if ($totalItems === 0) {
            $from = 0;
            $to = 0;
        }

        $pages = self::buildPageNumbers($currentPage, $lastPage);

        return [
            'total'        => $totalItems,
            'per_page'     => $perPage,
            'current_page' => $currentPage,
            'last_page'    => $lastPage,
            'from'         => $from,
            'to'           => $to,
            'has_prev'     => $currentPage > 1,
            'has_next'     => $currentPage < $lastPage,
            'prev_page'    => $currentPage > 1 ? $currentPage - 1 : null,
            'next_page'    => $currentPage < $lastPage ? $currentPage + 1 : null,
            'pages'        => $pages,
        ];
    }

    private static function buildPageNumbers(int $current, int $last): array
    {
        if ($last <= 7) {
            return range(1, $last);
        }

        $pages = [1];

        $start = max(2, $current - 2);
        $end = min($last - 1, $current + 2);

        if ($start > 2) {
            $pages[] = '...';
        }

        for ($i = $start; $i <= $end; $i++) {
            $pages[] = $i;
        }

        if ($end < $last - 1) {
            $pages[] = '...';
        }

        $pages[] = $last;

        return $pages;
    }
}