<?php
class Pagination
{
    private int $total;
    private int $perPage;
    private int $currentPage;
    private string $baseUrl;
    private int $totalPages;

    public function __construct(int $total, int $perPage, int $currentPage, string $baseUrl)
    {
        $this->total = $total;
        $this->perPage = max(1, $perPage);
        $this->currentPage = max(1, $currentPage);
        $this->baseUrl = $baseUrl;
        $this->totalPages = (int) ceil($total / $this->perPage);
    }

    public function render(): string
    {
        if ($this->totalPages <= 1) return '';

        $html = '<nav aria-label="Page navigation"><ul class="pagination justify-content-center">';

        // First
        $html .= $this->pageItem(1, '<i class="fas fa-angle-double-left"></i>', $this->currentPage === 1);

        // Previous
        $prev = max(1, $this->currentPage - 1);
        $html .= $this->pageItem($prev, '<i class="fas fa-angle-left"></i>', $this->currentPage === 1);

        // Page numbers
        $range = $this->getPageRange();
        if ($range[0] > 1) {
            $html .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
        }
        foreach ($range as $page) {
            $active = $page === $this->currentPage ? ' active' : '';
            $html .= '<li class="page-item' . $active . '"><a class="page-link" href="' . $this->url($page) . '">' . $page . '</a></li>';
        }
        if (end($range) < $this->totalPages) {
            $html .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
        }

        // Next
        $next = min($this->totalPages, $this->currentPage + 1);
        $html .= $this->pageItem($next, '<i class="fas fa-angle-right"></i>', $this->currentPage === $this->totalPages);

        // Last
        $html .= $this->pageItem($this->totalPages, '<i class="fas fa-angle-double-right"></i>', $this->currentPage === $this->totalPages);

        $html .= '</ul></nav>';
        $html .= '<div class="text-center text-muted small mb-3">Showing ' . (($this->currentPage - 1) * $this->perPage + 1) . ' to ' . min($this->currentPage * $this->perPage, $this->total) . ' of ' . number_format($this->total) . ' entries</div>';

        return $html;
    }

    private function pageItem(int $page, string $label, bool $disabled): string
    {
        if ($disabled) {
            return '<li class="page-item disabled"><span class="page-link">' . $label . '</span></li>';
        }
        return '<li class="page-item"><a class="page-link" href="' . $this->url($page) . '">' . $label . '</a></li>';
    }

    private function getPageRange(): array
    {
        $delta = 2;
        $start = max(1, $this->currentPage - $delta);
        $end = min($this->totalPages, $this->currentPage + $delta);
        return range($start, $end);
    }

    private function url(int $page): string
    {
        $params = $_GET;
        unset($params['_url']);
        $params['page'] = $page;
        $sep = str_contains($this->baseUrl, '?') ? '&' : '?';
        return $this->baseUrl . $sep . http_build_query($params);
    }

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