<?php

namespace Mtc\Core;

/**
 * Class PaginationTemplate
 * This class implements generic pagination template.
 * Created to ensure that all site sections can use the same layout for pagination
 *
 * @author Martins Fridenbergs <martins.fridenbergs@mtcmedia.co.uk>
 * @version 2016-11-14
 */
class PaginationTemplate
{
    /**
     * @var int number of pages withing pagination
     */
    public $total_pages = 1;

    /**
     * @var int current page
     */
    public $active_page = 1;

    /**
     * @var string CSS class attached to anchor elements
     */
    public $link_class = '';

    /**
     * @var int setting whether to show "Page X of Y" text
     */
    public $show_page_x_of_y = false;

    /**
     * @var bool Setting whether to show link to the first page
     */
    private $show_first = false;

    /**
     * @var bool Setting whether to show link to the last page
     */
    private $show_last = false;

    /**
     * @var bool Setting whether to show link to the next page
     */
    private $show_next = true;

    /**
     * @var bool Setting whether to show link to the previous page
     */
    private $show_previous = true;

    /**
     * @var bool Setting whether to show page numbers
     */
    public $show_page_numbers = true;

    /**
     * @var bool Setting whether to show "View all"
     */
    public $show_view_all = true;

    /**
     * @var string URL that exists for current page (without page index)
     */
    private $page_url = '';

    /**
     * @var int first pagination page to display
     */
    public $start = 1;

    /**
     * @var int last pagination page to display
     */
    public $end = 1;

    /**
     * @var int number of pagination links to display on either side of current page
     */
    public $pages_to_display = PAGINATION_PAGES_TO_DISPLAY;

    public $item_count;
    public $per_page;

    public $url_suffix = '';

    /**
     * Pagination constructor.
     * Expects setting array:
     * - item_count - total amount of records
     * - per_page - number of records displayed in single page
     * - url - current page url without the page index
     * - pages_to_display - size of total page links to display
     *
     * @param array $settings list of settings to overwrite defaults
     */
    public function __construct($settings = [])
    {
        foreach ($settings as $key => $setting) {
            $this->{$key} = $setting;
        }
        if (! empty($settings['item_count']) && ! empty($settings['per_page'])) {
            $this->total_pages = ceil($settings['item_count'] / $settings['per_page']);
        }

        /*
         * Find the first and last page links to display.
         * First check if page display count doesn't exceed total page count
         */
        if ($this->pages_to_display > $this->total_pages) {
            $this->start = 1;
            $this->end = $this->total_pages;
        } else {
            /*
             * If starting page is lower that page 1, force page 1 as starting point
             * If last page is more than total number of pages, force pagination to end at last page
             */
            if (($this->active_page - $this->pages_to_display) < 1) {
                $this->start = 1;
            } else {
                $this->start = $this->active_page - $this->pages_to_display;
            }

            if (($this->total_pages - $this->active_page) < $this->pages_to_display) {
                $this->end = $this->total_pages;
            } else {
                $this->end = $this->active_page + $this->pages_to_display;
            }
        }
    }

    /**
     * Function to check whether first page link should be shown
     * @return bool whether to show link to first page
     */
    public function showFirst()
    {
        return $this->active_page > 1 && $this->show_first;
    }

    /**
     * Function to check whether last page link should be shown
     * @return bool whether to show link to last page
     */
    public function showLast()
    {
        return $this->active_page < $this->total_pages && $this->show_last;
    }

    /**
     * Function to check whether next page link should be shown
     * @return bool whether to show link to first page
     */
    public function showNext()
    {
        return $this->active_page < $this->total_pages && $this->show_next;
    }

    /**
     * Function to check whether previous page link should be shown
     * @return bool whether to show link to last page
     */
    public function showPrevious()
    {
        return $this->active_page > 1 && $this->show_previous;
    }

    /**
     * Function to check whether previous page link should be shown
     * @return bool whether to show link to last page
     */
    public function showViewAll()
    {
        return $this->total_pages > 1 && $this->show_view_all;
    }

    /**
     * generate url that will display all items
     * @return bool whether to show link to last page
     */
    public function viewAllUrl()
    {
        // Check if url already has GET params attached
        if (! str_contains($this->page_url, '?')) {
            return $this->page_url.'?view_all=true';
        } else {
            return $this->page_url.'&view_all=true';
        }
    }

    /**
     * Generate pagination url
     * @param int $page_id page number to open
     * @return string page url
     */
    public function pageUrl($page_id)
    {
        if ($page_id == 1) {
            return $this->page_url;
        }
        // Check if url already has GET params attached
        if (! str_contains($this->page_url, '?')) {
            return $this->page_url.'?page='.$page_id.$this->url_suffix;
        } else {
            return $this->page_url.'&page='.$page_id.$this->url_suffix;
        }
    }

    /**
     * Render the pagination template based on current object
     * @return string pagination template for current object
     */
    public function render(): string
    {
        return app('twig')->render('navigation/pagination.twig', [
            'pagination' => $this,
        ]);
    }
}
