<?php
declare(strict_types=1);

namespace WP_AUX\Entities\AuxFramework\Partials;

use WP_AUX\Services\AuxFramework\ElementClassesService;
use WP_AUX\Services\HtmlService;

/**
 * The heading group of AUX components
 * @since 1.0.0
 */
class HeadingGroupEntity
{
  protected int $level = 2;
  protected ?string $content = null;
  protected ?string $superheader = null;
  protected ?string $subheader = null;
  protected ?string $prepend = null;
  protected array $styles = [];
  protected string|array|null $link = null;
  protected bool $isFeature = false;

  function __construct(?string $content = null, string|array|null $link = null, ?int $level = null) {
    $this->content = $content;

    if ($link) {
      $this->link = $link;
    }

    if ($level) {
      $this->level = $level;
    }
  }

  /**
   * Set the depth of the heading
   * @since 1.0.0
   */
  public function setLevel(int $level): self
  {
    $this->level = $level;
    return $this;
  }

  /**
   * Set the content of the primary heading element
   * @since 1.0.0
   */
  public function setContent(?string $content): self
  {
    $this->content = $content;
    return $this;
  }

  /**
   * Set the superheader content above the heading element
   * @since 1.0.0
   */
  public function setSuperheader(?string $superheader): self
  {
    $this->superheader = $superheader;
    return $this;
  }

  /**
   * Set the subheader content below the heading element
   * @since 1.0.0
   */
  public function setSubheader(?string $subheader): self
  {
    $this->subheader = $subheader;
    return $this;
  }

  /**
   * Prepend HTML before the superheader/primary header/subheader
   * @since 1.0.0
   */
  public function setPrepend(?string $prepend): self
  {
    $this->prepend = $prepend;
    return $this;
  }

  /**
   * Set the link for the primary heading element
   * @since 1.0.0
   */
  public function setLink(string|array|null $link): self
  {
    $this->link = $link;
    return $this;
  }

  /**
   * Flag the heading group as being part of a featured component
   * @since 1.0.0
   */
  public function setIsFeature(bool $isFeature): self
  {
    $this->isFeature = $isFeature;
    return $this;
  }

  /**
   * Add a style to the heading group
   * @since 1.0.0
   */
  public function addStyle(string $style): self
  {
    $this->styles[] = $style;
    return $this;
  }

  /**
   * Get if the heading group will render
   *
   * Heading groups only render if there is heading content, regardless of what
   * other heading information is provided.
   *
   * @since 1.0.0
   */
  public function willRender(): bool
  {
    return !empty($this->content);
  }

  public function __toString(): string
  {
    if (!$this->content) {
      return '';
    }

    $headingTag = 'h'.$this->level;

    $headingContent = $this->content;
    if ($this->link) {
      $headingContent = HtmlService::link($headingContent, $this->link, false);
    }

    $primaryHeading = sprintf('<%s>%s</%s>', $headingTag, $headingContent, $headingTag);

    $superheader = '';
    if ($this->superheader) {
      $superheader .= sprintf('<span class="superhead">%s</span>', $this->superheader);
    }

    $subheader = '';
    if ($this->subheader) {
      $subheader .= sprintf('<span class="subhead">%s</span>', $this->subheader);
    }

    $headingClass = ElementClassesService::buildClasses('heading-group');
    if ($this->isFeature) {
      $headingClass->addModifier('feature');
    }

    if (!empty($this->styles)) {
      foreach ($this->styles as $style) {
        $headingClass->addModifier($style);
      }
    }

    return sprintf(
      '<div class="%s">%s%s%s%s</div>',
      $headingClass,
      $this->prepend,
      $superheader,
      $primaryHeading,
      $subheader
    );
  }

  /**
   * Create a new heading group, starting with primary heading content, a link, and the heading level
   * @since 1.0.0
   */
  public static function create(?string $content, string|array|null $link = null, ?int $level = null): static
  {
    $headingGroup = new static($content, $link, $level);

    return $headingGroup;
  }
}
