<?php
namespace Newland\NeosCommon\ViewHelpers\Controller;

/*
 * This file is part of the "neos-common" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */


use Neos\FluidAdaptor\Core\Widget\AbstractWidgetController;

class PaginationController extends AbstractWidgetController
{

    /** @var int */
    protected $currentPage = 0;

    /** @var int */
    protected $totalPageCount = 0;

    public function initializeAction(): void
    {
        $this->currentPage = (int) $this->widgetConfiguration['currentPage'];
        $this->totalPageCount = (int) $this->widgetConfiguration['totalPageCount'];
    }

    private function generatePaginationItem(
        int $page,
        bool $isCurrent = false,
        bool $disabled = false
    ): array {
        $href = null;
        if (!$disabled && !$isCurrent) {
            $params = array_merge($_GET, [ 'page' => $page ]);
            $uriQuery = http_build_query($params);
            $href = '?' . $uriQuery;
        }

        return [
            'isCurrent' => $isCurrent,
            'page' => $page,
            'href' => $href,
            'disabled' => $disabled,
        ];
    }

    /**
     * Generate properties for rendering pagination.
     */
    private function generatePagination(): array
    {
        $showStartItems = $this->totalPageCount > 2 &&
            ($this->totalPageCount <= 7 || $this->currentPage <= 4);
        $startItemCount = $this->totalPageCount <= 7 ? $this->totalPageCount - 2 : 4;
        $showMidItems = $this->currentPage > 4 && $this->totalPageCount - $this->currentPage > 3;
        $showEndItems = $this->totalPageCount > 7 && $this->totalPageCount - $this->currentPage <= 3;
        $midItemIndex = $this->currentPage - 1;
        $startItems = [];
        $midItems = [];
        $endItems = [];

        if ($showStartItems) {
            for ($i = 1; $i <= $startItemCount; $i++) {
                $page = $i + 1;
                $startItems[] = $this->generatePaginationItem($page, $page === $this->currentPage);
            }
        }

        if ($showMidItems) {
            for ($i = 0; $i < 3; $i++) {
                $page = $i + $midItemIndex;
                $midItems[] = $this->generatePaginationItem($page, $page === $this->currentPage);
            }
        }

        if ($showEndItems) {
            for ($i = 4; $i > 0; $i--) {
                $page = $this->totalPageCount - $i;
                $endItems[] = $this->generatePaginationItem($page, $page === $this->currentPage);
            }
        }

        $firstItem = $this->generatePaginationItem(1, $this->currentPage === 1);
        $lastItem = $this->generatePaginationItem($this->totalPageCount, $this->totalPageCount === $this->currentPage);
        $prevItem = $this->generatePaginationItem($this->currentPage + -1, false, $this->currentPage === 1);
        $nextItem = $this->generatePaginationItem(
            $this->currentPage + 1,
            false,
            $this->currentPage === $this->totalPageCount
        );

        return [
            'showStartItems' => $showStartItems,
            'showMidItems' => $showMidItems,
            'showEndItems' => $showEndItems,
            'firstItem' => $firstItem,
            'lastItem' => $lastItem,
            'startItems' => $startItems,
            'midItems' => $midItems,
            'endItems' => $endItems,
            'prevItem' => $prevItem,
            'nextItem' => $nextItem,
            'current' => $this->currentPage,
            'total' => $this->totalPageCount,
        ];
    }

    public function indexAction(): void
    {
        $this->view->assign('pagination', $this->generatePagination());
    }
}
