<?php

declare(strict_types=1);

namespace ModernFields\FieldGroups\Entities;

use ModernFields\FieldGroups\Entities\Traits\NormalizesMeta;
use ModernFields\FieldGroups\Repositories\FieldRepository;

use WP_Post;

/**
 * Represents a Modern Fields group with normalized meta data accessors.
 * 
 * @since 1.0.0
 */
class FieldGroup
{
  use NormalizesMeta;

  /**
   * @var int
   */
  protected int $ID;

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

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

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

  /**
   * @var array<Field>
   * 
   */
  protected array $fields;

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

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

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

  /**
   * @var array<string>
   */
  protected array $targets;

  /**
   * @var array<string>
   */
  protected array $roles;

  /**
   * @var array<string, mixed>
   */
  protected array $settings;

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

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

  /**
   * @var int
   */
  protected int $fields_count;

  /**
   * @param WP_Post $post
   */
  public function __construct(WP_Post $post)
  {
    # Main data
    $this->ID = (int) $post->ID;
    $this->title = $this->normalizeString(get_the_title($post->ID));
    $this->description = $this->normalizeString($post->post_excerpt);
    $this->raw_content = $this->normalizeString($post->post_content);
    $this->content = $this->normalizeString(apply_filters('the_content', $post->post_content));
    $this->fields = FieldRepository::getFieldsByGroupId($post->ID);

    # Location
    $this->location = $this->normalizeString(get_post_meta($post->ID, 'mf_location', true));
    $this->scope = $this->normalizeString(get_post_meta($post->ID, 'mf_scope', true));
    $this->targets = $this->normalizeArray(get_post_meta($post->ID, 'mf_targets', false));
    $this->roles = $this->normalizeArray(get_post_meta($post->ID, 'mf_roles', false));

    # Additional information
    $this->settings = $this->normalizeArray(get_post_meta($post->ID, 'mf_settings', true));
    $this->position = $this->normalizeString(get_post_meta($post->ID, 'mf_position', true));
    $this->cpt = $this->normalizeString(get_post_meta($post->ID, 'mf_cpt', true));
    $this->fields_count = (int) get_post_meta($post->ID, 'fields_count', true);
  }

  /**
   * @return int
   */
  public function getId(): int
  {
    return $this->ID;
  }

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

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

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

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

  /**
   * @return array<Field>
   */
  public function getFields(): array
  {
    return $this->fields;
  }

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

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

  /**
   * @return array<string>
   */
  public function getTargets(): array
  {
    return $this->targets;
  }

  /**
   * @return array<string>
   */
  public function getRoles(): array
  {
    return $this->roles;
  }

  /**
   * @return array<string, mixed>
   */
  public function getSettings(): array
  {
    return $this->settings;
  }

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

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

  /**
   * @return int
   */
  public function getFieldsCount(): int
  {
    return $this->fields_count;
  }

  /**
   * @return array<string, mixed>
   */
  public function toArray(): array
  {
    return [
      'id' => $this->ID,
      'title' => $this->title,
      'description' => $this->description,
      'content' => [
        'raw' => $this->raw_content,
        'rendered' => $this->content,
      ],
      'fields' => array_map(fn(Field $field) => $field->toArray(), $this->fields),
      'location' => $this->location,
      'scope' => $this->scope,
      'targets' => $this->targets,
      'roles' => $this->roles,
      'settings' => $this->settings,
      'position' => $this->position,
      'cpt' => $this->cpt,
      'fieldsCount' => $this->fields_count,
    ];
  }
}
