<?php

namespace Drupal\rufi_structure;

use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Drupal\taxonomy\TermInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Class PatchBreadcrumbBuilder.
 */
class RuFiStructureNodeBreadcrumbBuilder implements BreadcrumbBuilderInterface {
  use StringTranslationTrait;

  /**
   * The current request.
   *
   * @var \Symfony\Component\HttpFoundation\Request|null
   */
  protected ?Request $request;

  /**
   * Constructs the TermBreadcrumbBuilder.
   *
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The entity type manager.
   */
  public function __construct(RequestStack $request_stack) {
    $this->request = $request_stack->getCurrentRequest();
  }

  protected array $routesApply = [
    'entity.node.canonical',
    'entity.node.edit_form',
    'entity.node.version_history',
    'entity.node.delete_form',
    'view.votingapi_votes.node_page',
    'change_requests.patches_overview',
  ];

  protected array $appendCanonical = [
    'entity.node.edit_form',
    'entity.node.version_history',
    'entity.node.delete_form',
    'view.votingapi_votes.node_page',
    'change_requests.patches_overview',
  ];

  protected function getNode($node) {
    if ($node instanceof NodeInterface) {
      return $node;
    } elseif (is_numeric($node)) {
      return Node::load($node);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function applies(RouteMatchInterface $route_match) {
    if (in_array($route_match->getRouteName(), $this->routesApply)) {
      /** @var NodeInterface $node */
      $node = $this->getNode($route_match->getParameter('node'));
      return ($node instanceof NodeInterface && $node->hasField('field_sector')) ;
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function build(RouteMatchInterface $route_match): Breadcrumb
  {

    $breadcrumb = new Breadcrumb();
    $breadcrumb->addCacheContexts(['route', 'url.query_args']);
    $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));

    /** @var NodeInterface $node */
    $node = $this->getNode($route_match->getParameter('node'));
    if ($node instanceof NodeInterface && $node->hasField('field_sector')) {
      $links = [];
      $ref_terms = $node->get('field_sector')->referencedEntities();
      /** @var TermInterface|bool $term */
      while ($term = reset($ref_terms)) {
        if (($parent_link = $term->toLink()) && $parent_link instanceof Link) {
          $links[] = $parent_link;
        }
        $ref_terms = ($term->parent) ? $term->parent->referencedEntities() : [];
      }
      $node_type = $node->bundle();
      $base_text = '';
      if ($node_type == 'rule') {
        $base_text = $this->t('Rules');
      } elseif ($node_type == 'problem') {
        $base_text = $this->t('Problems');
      }
      if ($base_text) {
        $links[] = Link::createFromRoute($base_text, 'view.rufi_section_tree.section_page');
      }

      foreach (array_reverse($links) as $link) {
        $link->getUrl()->setOption('query', ['node_type' => $node->bundle()]);
        $breadcrumb->addLink($link);
      }

      if (in_array($route_match->getRouteName(), $this->appendCanonical)) {
        $breadcrumb->addLink($node->toLink());
      }
    }

    return $breadcrumb;
  }

}
