<?php

namespace ModernFields\FieldGroups\Entities;

/**
 * Represents a field entity.
 * 
 * @since 1.0.0
 */
class Field
{
  /**
   * @var string
   */
  protected string $label;

  /**
   * @var string
   */
  protected string $name;

  /**
   * @var string
   */
  protected string $description;

  /**
   * @var string
   */
  protected string $block_name;

  /**
   * @var array
   */
  protected array $attributes;

  /**
   * @var string
   */
  protected string $type;

  /**
   * @param array $field
   */
  public function __construct(array $field)
  {
    $this->label = $field['attrs']['label'] ?? '';
    $this->name = $field['attrs']['name'] ?? '';
    $this->description = $field['attrs']['description'] ?? '';
    $this->block_name = $field['blockName'];
    $this->attributes = $field['attrs'] ?? [];

    $this->type = $field['type'] ?? 'string';
  }

  /**
   * Creates a Field instance from a mf_field database post.
   *
   * The post content holds a JSON-encoded object with the block name and the
   * fully-resolved attributes (including merged registry defaults) that were
   * written at index time by SaveGroup::indexFields().
   *
   * @since 0.6
   * @param \WP_Post $post A mf_field post
   * @return self
   */
  public static function fromDatabase(\WP_Post $post): self
  {
    $data = maybe_unserialize($post->post_content) ?? [];

    return new self([
      'blockName' => $data['blockName'] ?? '',
      'type'      => $data['type'] ?? 'string',
      'attrs'     => $data['attributes'] ?? [],
    ]);
  }

  /**
   * @return string
   */
  public function getLabel(): string
  {
    return $this->label;
  }

  /**
   * @return string
   */
  public function getName(): string
  {
    return $this->name;
  }

  /**
   * @return string
   */
  public function getDescription(): string
  {
    return $this->description;
  }

  /**
   * @return string
   */
  public function getBlockName(): string
  {
    return $this->block_name;
  }

  /**
   * @return array
   */
  public function getAttributes(): array
  {
    return $this->attributes;
  }

  /**
   * @param string $name
   * @return mixed
   */
  public function getAttribute(string $name): mixed
  {
    return $this->attributes[$name] ?? null;
  }

  /**
   * @return string
   */
  public function getType(): string
  {
    return $this->type;
  }

  /**
   * Serialize the field for the frontend. Attributes include name and description
   * so the frontend has everything it needs without extra mapping.
   *
   * @return array{label: string, name: string, blockName: string, attributes: array, type: string}
   */
  public function toArray(): array
  {
    return [
      'blockName' => $this->block_name,
      'label' => $this->label,
      'name' => $this->name,
      'description' => $this->description,
      'attributes' => $this->attributes,
      'type' => $this->type,
    ];
  }
}
