<?php
declare(strict_types=1);

namespace AuxCF\Entities\Traits;

use AuxCF\Entities\FieldGroup\FieldGroupBlockLocationEntity;
use AuxCF\Entities\FieldGroup\FieldGroupLocationEntity;
use AuxCF\Entities\FieldGroup\FieldGroupLocationsSetEntity;
use AuxCF\Entities\FieldGroup\FieldGroupPageTemplateLocationEntity;
use AuxCF\Entities\FieldGroup\FieldGroupPostTemplateLocationEntity;
use AuxCF\Entities\FieldGroup\FieldGroupPostTypeLocationEntity;
use AuxCF\Entities\Settings\Enum\OperatorEnum;

/**
 * Traits handling locations for field groups
 *
 * @Dion - what do we mean by locations? I think this is to set the admin page where the field group
 *         will be displayed but want to check before adding that to this trait's documentation.
 * @since 1.0.0
 */
trait LocationsSetTraits
{
  /**
   * Locations to initialize when the field group is initialized
   *
   * <code>
   *  [
   *    [ FieldGroupLocationEntity::class, 'string-value' ],
   *  ]
   * </code>
   * @var array<int,array{0:class-string,1:string}>
   */
  protected array $initLocations = [];

  /**
   * @var FieldGroupLocationsSetEntity Set of locations for the field group
   */
  protected FieldGroupLocationsSetEntity $locationsSet;

  /**
   * Initialize locations for the field group, starting with creating the locations set
   *
   * If a block.json file is provided with valid configuration, a block location for
   * the field group will be added to the locations set.
   *
   * If locations are provided in the $initLocations property, they will be added to the
   * locations set.
   *
   * @since 1.0.0
   */
  protected function initLocations(): void
  {
    $this->locationsSet = new FieldGroupLocationsSetEntity();

    if ($this->blockConfig && static::isActive()) {
      $location = FieldGroupBlockLocationEntity::create($this->blockConfig->name);
      $this->addLocation($location);
    }

    if (!empty($this->initLocations)) {
      foreach ($this->initLocations as $locationKey => $locationValue) {
        /* @var FieldGroupLocationEntity $location */
        $location = $locationValue[0]::create($locationValue[1]);

        $this->addLocation($location);
      }
    }
  }

  /**
   * Add the field group to posts of the specified post type
   * @since 1.0.0
   */
  public static function addToPostType(string $postType): void
  {
    $pageFieldGroup = \WP_AUX::instance()->getPageFieldGroupEntity(static::$key);

    if (!$pageFieldGroup) {
      return;
    }

    $pageFieldGroup->addPostTypeLocation($postType);
  }

  /**
   * Add a post type location to the field group for the specified post type
   * @since 1.0.0
   */
  public function addPostTypeLocation(string $value): void
  {
    $locationEntity = FieldGroupPostTypeLocationEntity::create($value);
    $this->locationsSet->addLocation($locationEntity);
  }

  /**
   * Add the field group to posts using the specified post template
   * @since 1.0.0
   */
  public static function addToPostTemplate(string $templateName): void
  {
    $pageFieldGroup = \WP_AUX::instance()->getPageFieldGroupEntity(static::$key);

    if (!$pageFieldGroup) {
      return;
    }

    $pageFieldGroup->addPostTemplateLocation($templateName);
  }

  /**
   * Add a post template location to the field group for the specified post template
   * @since 1.0.0
   */
  public function addPostTemplateLocation(string $value): void
  {
    $locationEntity = FieldGroupPostTemplateLocationEntity::create($value);
    $this->locationsSet->addLocation($locationEntity);
  }

  /**
   * Add the field group to posts using the specified page template
   * @since 1.0.0
   */
  public static function addToPageTemplate(string $templateName): void
  {
    $pageFieldGroup = \WP_AUX::instance()->getPageFieldGroupEntity(static::$key);

    if (!$pageFieldGroup) {
      return;
    }

    $pageFieldGroup->addPageTemplateLocation($templateName);
  }

  /**
   * Add a page template location to the field group for the specified page template
   * @since 1.0.0
   */
  public function addPageTemplateLocation(string $value): void
  {
    $locationEntity = FieldGroupPageTemplateLocationEntity::create($value);
    $this->locationsSet->addLocation($locationEntity);
  }

  /**
   * Add a location to the field group
   * @since 1.0.0
   */
  public function addLocation(string|FieldGroupLocationEntity $param, string|OperatorEnum $operator = null, string $value = null): void
  {
    $this->locationsSet->addLocation($param, $operator, $value);
  }
}
