<?php
namespace SabaiApps\Framework\Model\Paginator;

use SabaiApps\Framework\Model\AbstractEntityRepository;
use SabaiApps\Framework\Criteria\AbstractCriteria;

/**
 * EntityCriteriaPaginator class for paginating entities based on a specific entity relationship and criteria.
 * Fetches and counts entities related to a given entity and matching the criteria.
 */
class EntityCriteriaPaginator extends AbstractPaginator {

	protected $_entityName, $_entityId, $_criteria;

	/**
	 * Constructor.
	 *
	 * @param AbstractEntityRepository $repository Entity repository.
	 * @param string                   $entityName Name of the related entity.
	 * @param int                      $entityId ID of the related entity.
	 * @param AbstractCriteria         $criteria Criteria for filtering entities.
	 * @param int                      $perpage Number of entities per page.
	 * @param string                   $sort Sorting field.
	 * @param string                   $order Sorting order (ASC/DESC).
	 * @param int                      $limit Maximum number of entities to fetch.
	 */
	public function __construct( AbstractEntityRepository $repository, $entityName, $entityId, AbstractCriteria $criteria, $perpage, $sort, $order, $limit = 0 ) {
		parent::__construct( $repository, $perpage, $sort, $order, $limit );
		$this->_entityName = $entityName;
		$this->_entityId   = $entityId;
		$this->_criteria   = $criteria;
	}

	/**
	 * Gets the total count of elements for pagination.
	 *
	 * @return int Total count of elements.
	 */
	protected function _getElementCount() {
		$method = 'countBy' . $this->_entityName . 'AndCriteria';
		return $this->_repository->$method( $this->_entityId, $this->_criteria );
	}

	/**
	 * Fetches elements for the current page.
	 *
	 * @param int $limit Number of elements to fetch.
	 * @param int $offset Offset for fetching elements.
	 * @return mixed Fetched elements.
	 */
	protected function _getElements( $limit, $offset ) {
		$method = 'fetchBy' . $this->_entityName . 'AndCriteria';
		return $this->_repository->$method( $this->_entityId, $this->_criteria, $limit, $offset, $this->_sort, $this->_order );
	}
}
