<?php

declare(strict_types=1);

namespace App\Module\Core\Infrastructure\ApiPlatform\Pagination;

use ApiPlatform\State\Pagination\PaginatorInterface;
use ArrayIterator;
use IteratorAggregate;
use Traversable;

/**
 * Paginator pour resources alimentees par DBAL (pas par Doctrine ORM).
 *
 * Implemente PaginatorInterface : API Platform l'introspecte pour generer
 * automatiquement la section `hydra:view` (first / next / previous / last)
 * dans la reponse JSON-LD. Aucun calcul manuel de liens.
 *
 * @template T of object
 *
 * @implements PaginatorInterface<T>
 */
final readonly class DbalPaginator implements PaginatorInterface, IteratorAggregate
{
    /**
     * @param list<T> $items        Items deja decoupes sur la page courante
     * @param int     $currentPage  Page courante (1-indexee)
     * @param int     $itemsPerPage Limite appliquee a la requete SQL
     * @param int     $totalItems   Resultat du COUNT(*) sans limite
     */
    public function __construct(
        private array $items,
        private int $currentPage,
        private int $itemsPerPage,
        private int $totalItems,
    ) {}

    public function getCurrentPage(): float
    {
        return (float) $this->currentPage;
    }

    public function getLastPage(): float
    {
        if ($this->itemsPerPage <= 0) {
            return 1.0;
        }

        return (float) max(1, (int) ceil($this->totalItems / $this->itemsPerPage));
    }

    public function getItemsPerPage(): float
    {
        return (float) $this->itemsPerPage;
    }

    public function getTotalItems(): float
    {
        return (float) $this->totalItems;
    }

    public function count(): int
    {
        return count($this->items);
    }

    /**
     * @return Traversable<int, T>
     */
    public function getIterator(): Traversable
    {
        return new ArrayIterator($this->items);
    }
}
