<?php

declare(strict_types=1);

namespace Drupal\nodehive_core\Plugin\WireComponent;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\wire\View;
use Drupal\wire\WireComponentBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides "ContentBrowser" Wire component.
 *
 * @WireComponent(
 *   id = "contentbrowser",
 *   label = @Translation("ContentBrowser"),
 * )
 */
class Contentbrowser extends WireComponentBase {

  use StringTranslationTrait;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected EntityTypeManagerInterface $entityTypeManager;

  /**
   * The search query string.
   *
   * @var string
   */
  public string $search = '';

  /**
   * The content type filter.
   *
   * @var string
   */
  public string $contentType = '';

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function render(): ?View {
    return View::fromTpl('contentbrowser', [
      'items' => $this->getArticles(),
      'content_types' => $this->getContentTypes(),
    ]);
  }

  /**
   * Returns a list of articles matching the current filters.
   */
  private function getArticles(): array {
    $nodeStorage = $this->entityTypeManager->getStorage('node');
    $query = $nodeStorage->getQuery()->accessCheck(TRUE)
      ->condition('status', 1)
      ->condition('title', '%' . addcslashes($this->search, '\%_') . '%', 'LIKE')
      ->range(0, 500);

    if (!empty($this->contentType)) {
      $query->condition('type', $this->contentType);
    }

    $articles = $nodeStorage->loadMultiple($query->execute());

    return array_map(function ($article) {
      $nodeTypeStorage = $this->entityTypeManager->getStorage('node_type');
      $nodeType = $nodeTypeStorage->load($article->bundle());

      return [
        'link' => $article->toLink(),
        'status' => $article->isPublished() ? $this->t('Published') : $this->t('Unpublished'),
        'edit_url' => Url::fromRoute('entity.node.edit_form', ['node' => $article->id()])->toString(),
        'type' => $nodeType ? $nodeType->label() : $this->t('Unknown'),
      ];
    }, $articles);
  }

  /**
   * Returns available content types as an options array.
   */
  private function getContentTypes(): array {
    $contentTypes = $this->entityTypeManager->getStorage('node_type')->loadMultiple();
    $options = [];
    foreach ($contentTypes as $type) {
      $options[$type->id()] = $type->label();
    }
    return $options;
  }

}
