<?php
declare(strict_types=1);

namespace WP_AUX\Entities\AuxFramework\Partials;

use WHOOP\Entities\Elements\A;
use WHOOP\Entities\Elements\Li;
use WHOOP\Entities\Elements\Ul;
use WP_AUX\Services\AuxFramework\ElementClassesService;
use WP_AUX\Services\HtmlService;

class TagCollectionEntity
{
  protected bool $hasContainer = false;
  protected ?string $heading = null;
  protected ?string $tagType = null;
  protected array $items = [];
  protected bool $forceList = false;

  public function __construct() {}

  public function setHasContainer(bool $hasContainer): self
  {
    $this->hasContainer = $hasContainer;
    return $this;
  }

  public function setHeading(?string $heading): self
  {
    $this->heading = $heading;
    return $this;
  }

  public function setTagType(?string $tagType): self
  {
    $this->tagType = $tagType;
    return $this;
  }

  public function addItem(array|string $item, ?string $url = null): static
  {
    if (is_string($item)) {
      $item = [
        'title' => $item,
        'url' => $url,
      ];
    }

    $this->items[] = $item;

    return $this;
  }

  public function hasItems(): bool
  {
    return !empty($this->items);
  }

  public function setForceList(bool $forceList): self
  {
    $this->forceList = $forceList;
    return $this;
  }

  public function getList(): Ul|A
  {
    $listClass = ElementClassesService::buildClasses('tag-collection');

    $ul = Ul::create()
      ->addClass((string) $listClass);

    $linkClass = ElementClassesService::buildClasses('tag');

    if ($this->tagType) {
      $linkClass->addModifier($this->tagType);
    }

    foreach ($this->items as $item) {
      $link = A::create($item['title'], [
        'href' => $item['url'],
        'target' => $item['target'] ?? '_self',
      ])->addClass((string) $linkClass);

      if (isset($item['class'])) {
        $link->addClass($item['class']);
      }

      if (!empty($item['data'])) {
        foreach ($item['data'] as $key => $value) {
          $link->setDataValue($key, $value);
        }
      }

      if (count($this->items) === 1 && !$this->forceList) {
        return $link;
      }

      $li = Li::create($link);

      $ul->appendElement($li);
    }

    return $ul;
  }

  public function __toString(): string
  {
    $list = $this->getList();

    if (!$this->hasContainer) {
      return (string) $list;
    }

    $headingContent = HtmlService::formattedValue(
      $this->heading,
      '<span class="tag-collection__header">%s</span>'
    );

    return sprintf(
      '<div class="tag-collection__container">%s%s</div>',
      $headingContent,
      $list
    );
  }

  public static function create(): static
  {
    $collection = new static();

    return $collection;
  }

  public static function createContainer(?string $heading = null): static
  {
    $collection = (new static())
      ->setHasContainer(true)
      ->setHeading($heading);

    return $collection;
  }
}
