<?php
declare(strict_types=1);

namespace AuxCF\Entities;

use AuxCF\Entities\Field\GroupFieldEntity;

/**
 * A collection of fields to group together multiple fields commonly used together in a group
 *
 * Instead of listing multiple fields in every group they are used together, one
 * field collection can be defined to be used in multiple groups. Fields collections
 * can contain fields and fields collections. Fields collections can also specify
 * fields to exclude from the collection.
 *
 * @since 1.0.0
 */
class FieldsCollectionEntity
{
  /**
   * @var string[] List of namespaced classes of fields and fields collections in the collection
   */
  protected array $initFields = [];
  /**
   * @var string[] List of namespaced classes of fields and fields collections to exclude (for collections with inherited "initFields")
   */
  protected array $initExcludeFields = [];

  public function __construct() {
    $this->initFields();
  }

  /**
   * Set the initFields to be the defined or inherited initFields value, minus excluded fields
   * @since 1.0.0
   */
  public function initFields(): void
  {
    if (!empty($this->initExcludeFields)) {
      $this->initFields = array_diff($this->initFields, $this->initExcludeFields);
    }
  }

  /**
   * Cycle through the fields in the collection and add them to the group
   *
   * This method will recursively cycle through the fields in the collection and add them
   * to the group. If the field is a collection, it will be added to the group and the
   * collection will be added to the group as well.
   *
   * @since 1.0.0
   */
  public function addFieldsToGroup(FieldGroupEntity|GroupFieldEntity $group, ?FieldsCollectionEntity $fieldsCollection = null): void
  {
    foreach ($this->initFields as $fieldKey => $fieldValue) {
      /* @var FieldEntity|FieldsCollectionEntity $fieldEntity */
      $fieldEntity = $fieldValue::create();

      if ($fieldEntity instanceof FieldsCollectionEntity) {
        $fieldEntity->addFieldsToGroup($group, $fieldEntity);
      } else {
        if ($fieldsCollection) {
          $fieldEntity->setFieldsCollection($fieldsCollection);
        }

        $group->addField($fieldEntity);
      }
    }
  }

  /**
   * Static method available on all collections to create a new instance of the collection
   * @since 1.0.0
   */
  public static function create(): static
  {
    return new static();
  }
}
