<?php
declare(strict_types=1);

namespace WP_AUX\Entities\Admin\AuxComponents;

use AuxCF\Entities\FieldEntity;
use WP_AUX\Services\Admin\AuxComponents\AuxComponentsAuditFieldPropertiesService;
use WP_AUX\Services\Admin\AuxComponents\AuxComponentsAuditFieldService;

class AuxComponentsAuditFieldEntity
{
  public int $instanceNumber;
  public FieldEntity $field;
  public AuxComponentAuditFileEntity $file;
  public array $path;
  public \ReflectionClass|null $parentClass;
  public ?AuxComponentAuditFileEntity $parentClassFile = null;

  /**
   * @var \ReflectionProperty[]
   */
  public $properties;
  /**
   * @var AuxComponentsAuditFieldPropertyEntity[]
   */
  public $auditProperties;
  public mixed $conditionalLogic;

  /**
   * @var AuxComponentsAuditFieldEntity[]
   */
  public $subAuditFields = [];

  public null|AuxComponentsAuditComponentEntity|AuxComponentsAuditFieldEntity $parentEntity = null;

  public function __construct(FieldEntity $field) {
    static $instanceNumber;
    $instanceNumber++;

    $this->instanceNumber = $instanceNumber;

    $this->field = $field;

    $reflect = new \ReflectionClass($this->field);

    $this->file = new AuxComponentAuditFileEntity($reflect->getFileName());

    $this->parentClass = $reflect->getParentClass();
    $this->parentClassFile = new AuxComponentAuditFileEntity($reflect->getParentClass()->getFileName());

    $this->properties = $reflect->getProperties();
    $this->conditionalLogic = $reflect->getProperty('initConditionalLogic')->getValue($field);

    if (method_exists($this->field, 'getFields')) {
      $subFields = $field->getFields();

      foreach ($subFields as $subField) {
        $subAuditField = new AuxComponentsAuditFieldEntity($subField);
        $subAuditField->setParentEntity($this);

        $this->subAuditFields[] = $subAuditField;
      }
    }

    foreach ($this->properties as $property) {
      if (in_array($property->name, AuxComponentsAuditFieldPropertiesService::$ignoreFieldProperties)) {
        continue;
      }

      $this->auditProperties[] = new AuxComponentsAuditFieldPropertyEntity($this, $property);
    }
  }

  public function setParentEntity(AuxComponentsAuditComponentEntity|AuxComponentsAuditFieldEntity $parentEntity) {
    $this->parentEntity = $parentEntity;
    return $this;
  }

  /**
   * @var AuxComponentsAuditFieldPropertyEntity[]
   */
  public function getAuditProperties(): array
  {
    return $this->auditProperties;
  }


  public function getFieldAuditPath() {
    if (empty($this->parentEntity)) {
      return [];
    }

    $path = [];
    $object = $this;
    while ($object = @$object->parentEntity) {
      $path[] = $object;
    }

    return array_reverse($path);
  }

  public function getCollectionPath(): string
  {
    $collection = $this->field->getFieldsCollection();

    if (!$collection) {
      return '';
    }

    $collectionReflect = new \ReflectionClass($collection);

    return $collectionReflect->getFileName();
  }
}
