<?php
/**
 * Pagination Helper
 * Generate pagination links for data tables
 */

// ============================================
// PAGINATION CLASS
// ============================================

class Pagination {
    private $totalItems;
    private $itemsPerPage;
    private $currentPage;
    private $url;
    private $maxPages = 10;
    
    /**
     * Constructor
     * @param int $totalItems Total number of items
     * @param int $itemsPerPage Items per page
     * @param int $currentPage Current page number
     * @param string $url Base URL for pagination links
     */
    public function __construct($totalItems, $itemsPerPage = 20, $currentPage = 1, $url = '') {
        $this->totalItems = (int)$totalItems;
        $this->itemsPerPage = (int)$itemsPerPage;
        $this->currentPage = max(1, (int)$currentPage);
        $this->url = $url ?: $_SERVER['REQUEST_URI'];
        $this->removePageParam();
    }
    
    /**
     * Remove page parameter from URL
     */
    private function removePageParam() {
        $this->url = preg_replace('/[?&]page=\d+/', '', $this->url);
        $this->url = preg_replace('/&page=\d+/', '', $this->url);
    }
    
    /**
     * Get total pages
     * @return int
     */
    public function getTotalPages() {
        return ceil($this->totalItems / $this->itemsPerPage);
    }
    
    /**
     * Get offset for SQL query
     * @return int
     */
    public function getOffset() {
        return ($this->currentPage - 1) * $this->itemsPerPage;
    }
    
    /**
     * Get limit for SQL query
     * @return int
     */
    public function getLimit() {
        return $this->itemsPerPage;
    }
    
    /**
     * Get SQL LIMIT clause
     * @return string
     */
    public function getLimitClause() {
        return "LIMIT {$this->getOffset()}, {$this->itemsPerPage}";
    }
    
    /**
     * Check if has previous page
     * @return bool
     */
    public function hasPrev() {
        return $this->currentPage > 1;
    }
    
    /**
     * Check if has next page
     * @return bool
     */
    public function hasNext() {
        return $this->currentPage < $this->getTotalPages();
    }
    
    /**
     * Get previous page number
     * @return int
     */
    public function getPrevPage() {
        return $this->currentPage - 1;
    }
    
    /**
     * Get next page number
     * @return int
     */
    public function getNextPage() {
        return $this->currentPage + 1;
    }
    
    /**
     * Get page numbers for pagination
     * @return array
     */
    public function getPageNumbers() {
        $totalPages = $this->getTotalPages();
        $currentPage = $this->currentPage;
        $maxPages = $this->maxPages;
        
        $start = max(1, $currentPage - floor($maxPages / 2));
        $end = min($totalPages, $start + $maxPages - 1);
        
        if ($end - $start + 1 < $maxPages) {
            $start = max(1, $end - $maxPages + 1);
        }
        
        return range($start, $end);
    }
    
    /**
     * Generate pagination HTML
     * @param string $class CSS class for pagination container
     * @return string
     */
    public function render($class = 'pagination') {
        $totalPages = $this->getTotalPages();
        
        if ($totalPages <= 1) {
            return '';
        }
        
        $separator = strpos($this->url, '?') === false ? '?' : '&';
        $html = '<nav aria-label="Page navigation"><ul class="' . $class . '">';
        
        // Previous button
        if ($this->hasPrev()) {
            $html .= '<li class="page-item">
                        <a class="page-link" href="' . $this->url . $separator . 'page=' . $this->getPrevPage() . '" aria-label="Previous">
                            <span aria-hidden="true">&laquo;</span>
                            <span class="sr-only">Previous</span>
                        </a>
                      </li>';
        } else {
            $html .= '<li class="page-item disabled">
                        <span class="page-link">&laquo;</span>
                      </li>';
        }
        
        // First page
        if ($this->getPageNumbers()[0] > 1) {
            $html .= '<li class="page-item">
                        <a class="page-link" href="' . $this->url . $separator . 'page=1">1</a>
                      </li>';
            if ($this->getPageNumbers()[0] > 2) {
                $html .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
            }
        }
        
        // Page numbers
        foreach ($this->getPageNumbers() as $page) {
            if ($page == $this->currentPage) {
                $html .= '<li class="page-item active">
                            <span class="page-link">' . $page . '</span>
                          </li>';
            } else {
                $html .= '<li class="page-item">
                            <a class="page-link" href="' . $this->url . $separator . 'page=' . $page . '">' . $page . '</a>
                          </li>';
            }
        }
        
        // Last page
        $lastPage = $totalPages;
        $pageNumbers = $this->getPageNumbers();
        if ($pageNumbers[count($pageNumbers) - 1] < $lastPage) {
            if ($pageNumbers[count($pageNumbers) - 1] < $lastPage - 1) {
                $html .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
            }
            $html .= '<li class="page-item">
                        <a class="page-link" href="' . $this->url . $separator . 'page=' . $lastPage . '">' . $lastPage . '</a>
                      </li>';
        }
        
        // Next button
        if ($this->hasNext()) {
            $html .= '<li class="page-item">
                        <a class="page-link" href="' . $this->url . $separator . 'page=' . $this->getNextPage() . '" aria-label="Next">
                            <span aria-hidden="true">&raquo;</span>
                            <span class="sr-only">Next</span>
                        </a>
                      </li>';
        } else {
            $html .= '<li class="page-item disabled">
                        <span class="page-link">&raquo;</span>
                      </li>';
        }
        
        $html .= '</ul></nav>';
        
        // Add info text
        $start = $this->getOffset() + 1;
        $end = min($this->getOffset() + $this->itemsPerPage, $this->totalItems);
        $html .= '<div class="pagination-info text-muted text-center mt-2 small">
                    Showing ' . $start . ' to ' . $end . ' of ' . $this->totalItems . ' entries
                  </div>';
        
        return $html;
    }
    
    /**
     * Render simple pagination (prev/next only)
     * @return string
     */
    public function renderSimple() {
        $totalPages = $this->getTotalPages();
        
        if ($totalPages <= 1) {
            return '';
        }
        
        $separator = strpos($this->url, '?') === false ? '?' : '&';
        $html = '<div class="simple-pagination d-flex justify-content-between">';
        
        if ($this->hasPrev()) {
            $html .= '<a href="' . $this->url . $separator . 'page=' . $this->getPrevPage() . '" class="btn btn-outline-primary">
                        &laquo; Previous
                      </a>';
        } else {
            $html .= '<span class="btn btn-outline-secondary disabled">&laquo; Previous</span>';
        }
        
        $html .= '<span class="text-muted">Page ' . $this->currentPage . ' of ' . $totalPages . '</span>';
        
        if ($this->hasNext()) {
            $html .= '<a href="' . $this->url . $separator . 'page=' . $this->getNextPage() . '" class="btn btn-outline-primary">
                        Next &raquo;
                      </a>';
        } else {
            $html .= '<span class="btn btn-outline-secondary disabled">Next &raquo;</span>';
        }
        
        $html .= '</div>';
        
        return $html;
    }
    
    /**
     * Render dropdown pagination
     * @return string
     */
    public function renderDropdown() {
        $totalPages = $this->getTotalPages();
        
        if ($totalPages <= 1) {
            return '';
        }
        
        $separator = strpos($this->url, '?') === false ? '?' : '&';
        $html = '<div class="pagination-dropdown d-flex align-items-center gap-2">
                    <span class="text-muted">Page:</span>
                    <select class="form-control form-control-sm w-auto" onchange="window.location.href=this.value">';
        
        for ($i = 1; $i <= $totalPages; $i++) {
            $selected = ($i == $this->currentPage) ? 'selected' : '';
            $url = $this->url . $separator . 'page=' . $i;
            $html .= '<option value="' . $url . '" ' . $selected . '>' . $i . '</option>';
        }
        
        $html .= '</select>
                    <span class="text-muted">of ' . $totalPages . '</span>
                </div>';
        
        return $html;
    }
    
    /**
     * Get pagination data as array (for AJAX)
     * @return array
     */
    public function getData() {
        return [
            'current_page' => $this->currentPage,
            'total_pages' => $this->getTotalPages(),
            'total_items' => $this->totalItems,
            'items_per_page' => $this->itemsPerPage,
            'offset' => $this->getOffset(),
            'has_prev' => $this->hasPrev(),
            'has_next' => $this->hasNext(),
            'prev_page' => $this->getPrevPage(),
            'next_page' => $this->getNextPage(),
            'page_numbers' => $this->getPageNumbers()
        ];
    }
}

// ============================================
// HELPER FUNCTIONS
// ============================================

/**
 * Create pagination instance
 * @param int $totalItems Total number of items
 * @param int $itemsPerPage Items per page
 * @param int $currentPage Current page number
 * @param string $url Base URL
 * @return Pagination
 */
function createPagination($totalItems, $itemsPerPage = 20, $currentPage = 1, $url = '') {
    return new Pagination($totalItems, $itemsPerPage, $currentPage, $url);
}

/**
 * Get current page number from URL
 * @return int
 */
function getCurrentPage() {
    $page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
    return max(1, $page);
}

/**
 * Generate pagination links (simple function)
 * @param int $currentPage Current page number
 * @param int $totalPages Total number of pages
 * @param string $url Base URL
 * @return string
 */
function paginationLinks($currentPage, $totalPages, $url = '') {
    $pagination = new Pagination($totalPages * 20, 20, $currentPage, $url);
    return $pagination->render();
}

/**
 * Display pagination info text
 * @param int $total Total items
 * @param int $perPage Items per page
 * @param int $currentPage Current page
 * @return string
 */
function paginationInfo($total, $perPage, $currentPage) {
    $start = ($currentPage - 1) * $perPage + 1;
    $end = min($currentPage * $perPage, $total);
    return "Showing $start to $end of $total entries";
}

// ============================================
// AJAX PAGINATION
// ============================================

/**
 * Generate AJAX pagination links
 * @param int $currentPage
 * @param int $totalPages
 * @param string $callback JavaScript callback function
 * @return string
 */
function ajaxPaginationLinks($currentPage, $totalPages, $callback = 'loadPage') {
    if ($totalPages <= 1) {
        return '';
    }
    
    $html = '<nav><ul class="pagination">';
    
    // Previous
    if ($currentPage > 1) {
        $html .= '<li class="page-item">
                    <a class="page-link" href="javascript:void(0)" onclick="' . $callback . '(' . ($currentPage - 1) . ')">&laquo;</a>
                  </li>';
    } else {
        $html .= '<li class="page-item disabled"><span class="page-link">&laquo;</span></li>';
    }
    
    // Page numbers
    $start = max(1, $currentPage - 5);
    $end = min($totalPages, $currentPage + 5);
    
    if ($start > 1) {
        $html .= '<li class="page-item"><a class="page-link" href="javascript:void(0)" onclick="' . $callback . '(1)">1</a></li>';
        if ($start > 2) $html .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
    }
    
    for ($i = $start; $i <= $end; $i++) {
        if ($i == $currentPage) {
            $html .= '<li class="page-item active"><span class="page-link">' . $i . '</span></li>';
        } else {
            $html .= '<li class="page-item"><a class="page-link" href="javascript:void(0)" onclick="' . $callback . '(' . $i . ')">' . $i . '</a></li>';
        }
    }
    
    if ($end < $totalPages) {
        if ($end < $totalPages - 1) $html .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
        $html .= '<li class="page-item"><a class="page-link" href="javascript:void(0)" onclick="' . $callback . '(' . $totalPages . ')">' . $totalPages . '</a></li>';
    }
    
    // Next
    if ($currentPage < $totalPages) {
        $html .= '<li class="page-item">
                    <a class="page-link" href="javascript:void(0)" onclick="' . $callback . '(' . ($currentPage + 1) . ')">&raquo;</a>
                  </li>';
    } else {
        $html .= '<li class="page-item disabled"><span class="page-link">&raquo;</span></li>';
    }
    
    $html .= '</ul></nav>';
    
    return $html;
}