<?php

namespace Velis\Test\Mvc;

use PHPUnit\Framework\TestCase;
use Velis\Dto\Common\Result\PaginatedListResult;
use Velis\Filter;
use Velis\Mvc\Paginator;

class PaginatorTest extends TestCase
{
    public function testPaginate()
    {
        $page = 3;
        $perPage = 10;
        $pagination = new Paginator($page, $perPage);

        $data = $pagination->getList(new class () {
            public const ITEMS_PER_PAGE = 30;
            public static int $listItemsFound;

            public static function getList($page = 1, $params = null, $order = null, $limit = 50, $fields = null)
            {
                $result = [];
                foreach (range(1, 100) as $id) {
                    $result[] = new self();
                }
                $result = array_slice($result, ($page - 1) * $limit, $limit);
                self::$listItemsFound = count($result);

                return $result;
            }
        });
        $paginatedList = $pagination->paginate($data);

        $this->assertInstanceOf(PaginatedListResult::class, $paginatedList);
        $this->assertCount($perPage, $paginatedList->data);
        $this->assertEquals($page, $paginatedList->metadata->page);
    }

    public function testPaginateWithDefaultPageAndCount()
    {
        $pagination = new Paginator();

        $data = $pagination->getList(new class () {
            public const ITEMS_PER_PAGE = 41;
            public static int $listItemsFound;

            public static function getList($page = 1, $params = null, $order = null, $limit = 50, $fields = null)
            {
                $result = [];
                foreach (range(1, 100) as $id) {
                    $result[] = new self();
                }
                $result = array_slice($result, ($page - 1) * $limit, $limit);
                self::$listItemsFound = count($result);

                return $result;
            }
        });
        $paginatedList = $pagination->paginate($data);

        $this->assertInstanceOf(PaginatedListResult::class, $paginatedList);
        $this->assertCount(30, $paginatedList->data); // Paginator::ITEMS_PER_PAGE = 30
        $this->assertEquals(1, $paginatedList->metadata->page);
    }

    public function testFromParams()
    {
        $params = new Filter();
        $paginator = Paginator::fromParams($params);
        $this->assertEquals(new Paginator(), $paginator);
    }

    public function testPaginateWithSetDefaultPerPage()
    {
        $defaultPerPage = 10;

        $pagination = new Paginator();
        $pagination->setDefaultPerPage($defaultPerPage);

        $data = $pagination->getList(new class () {
            public const ITEMS_PER_PAGE = 30;
            public static int $listItemsFound;

            public static function getList($page = 1, $params = null, $order = null, $limit = 50, $fields = null)
            {
                $result = [];
                foreach (range(1, 100) as $id) {
                    $result[] = new self();
                }
                $result = array_slice($result, ($page - 1) * $limit, $limit);
                self::$listItemsFound = count($result);

                return $result;
            }
        });
        $paginatedList = $pagination->paginate($data);

        $this->assertInstanceOf(PaginatedListResult::class, $paginatedList);
        $this->assertCount($defaultPerPage, $paginatedList->data);
        $this->assertEquals(1, $paginatedList->metadata->page);
    }
}
