<?php
namespace WP_AUX\Entities;

class PaginationEntity {
  public array $rawLinks = [];

  public function __construct() {
    $this->rawLinks = paginate_links(['type' => 'array']) ?? [];
  }

  protected function getLinkTag($linkHtml): \DOMElement {
    $dom = new \DOMDocument;
    $dom->loadHTML($linkHtml);
    $xpath = new \DOMXPath($dom);

    return $xpath->query('//a | //span')->item(0);
  }

  protected function updateLinkAttr(\DOMElement $tag, array $attr): array
  {
    if (substr_count($attr['class'], 'next ') || substr_count($attr['class'], 'prev ')) {
      if (substr_count($attr['class'], 'next ')) {
        $attr['class'] = str_replace('next ', 'wayfinding wayfinding--forward', $attr['class']);
        $attr['aria-label'] = 'Next Page';
      }

      if (substr_count($attr['class'], 'prev ')) {
        $attr['class'] = str_replace('prev ', 'wayfinding wayfinding--back', $attr['class']);
        $attr['aria-label'] = 'Previous Page';
      }
    } else {
      $attr['class'] = str_replace('page-numbers', 'pagination__page', $attr['class']);

      if (!empty($attr['href'])) {
        $attr['aria-label'] = 'Page ' . $tag->textContent;
      }
    }

    if (isset($attr['aria-current'])) {
      $attr['class'] = str_replace('current', 'pagination__page--current', $attr['class']);
    }

    return $attr;
  }

  protected function transformRawLinks(): array
  {
    $links = [];

    if (empty($this->rawLinks)) {
      return $links;
    }

    foreach ($this->rawLinks as $link) {
      $tag = $this->getLinkTag($link);

      $attr = [];
      foreach ($tag->attributes as $attrName => $attribNodeVal) {
        $attr[$attrName] = $tag->getAttribute($attrName);
      }

      $attr = $this->updateLinkAttr($tag, $attr);

      foreach ($attr as $attrName => $attrValue) {
        $tag->setAttribute($attrName, $attrValue);
      }

      $links[] = $tag->ownerDocument->saveHTML($tag);
    }

    return $links;
  }

  public function hasLinks(): bool
  {
    return count($this->rawLinks) > 0;
  }

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

    $links = $this->transformRawLinks();

    ob_start();
    ?>
      <nav aria-label="Pagination" class="pagination">
        <ul class="pagination__list">
          <?php
          foreach ($links as $link) {
          ?>
              <li class="pagination__item"><?php echo $link; ?></li>
          <?php
          }
          ?>
        </ul>
      </nav>
    <?php
    return ob_get_clean();
  }

  public function __toString(): string
  {
    return $this->getHtml();
  }
}
