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

use SabaiApps\Framework\Criteria\InCriteria;

/**
 * ChildEntitiesEntityCollectionDecorator class for decorating entity collections with child entities.
 * Adds functionality to fetch and assign child entities for each entity in the collection.
 */
class ChildEntitiesEntityCollectionDecorator extends AbstractEntityCollectionDecorator {

	protected $_parentKey, $_entityName, $_childEntities;

	/**
	 * Constructor.
	 *
	 * @param string                   $entityName Name of the child entity.
	 * @param string                   $parentKey Key used to link parent entities.
	 * @param AbstractEntityCollection $collection Entity collection to decorate.
	 */
	public function __construct( $entityName, $parentKey, AbstractEntityCollection $collection ) {
		parent::__construct( $collection );
		$this->_parentKey  = $parentKey;
		$this->_entityName = $entityName;
	}

	/**
	 * Rewinds the collection and fetches child entities.
	 */
	#[\ReturnTypeWillChange]
	public function rewind() {
		$this->_collection->rewind();
		if ( ! isset( $this->_childEntities ) ) {
			$this->_childEntities = array();
			if ( $this->_collection->count() > 0 ) {
				$criteria = new InCriteria( $this->_parentKey, $this->_collection->getAllIds() );
				$children = $this->_model->getRepository( $this->_entityName )->fetchByCriteria( $criteria );
				foreach ( $children as $child ) {
					$this->_childEntities[ $child->parent ][] = $child;
				}
				$this->_collection->rewind();
			}
		}
	}

	/**
	 * Gets the current entity and assigns its child entities.
	 *
	 * @return mixed Current entity with child entities.
	 */
	#[\ReturnTypeWillChange]
	public function current() {
		$current  = $this->_collection->current();
		$id       = $current->id;
		$entities = ! empty( $this->_childEntities[ $id ] ) ? $this->_childEntities[ $id ] : array();
		$current->assignObject( 'Children', $this->getModel()->createCollection( $this->_entityName, $entities ) );

		return $current;
	}
}
