<?php

declare(strict_types=1);

namespace Drupal\nodehive_content_browser\Service;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\node\NodeInterface;

/**
 * Service for searching content.
 */
class ContentSearchService {

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

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * The date formatter.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * Constructs a ContentSearchService object.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   The current user.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date formatter.
   */
  public function __construct(
    EntityTypeManagerInterface $entity_type_manager,
    AccountProxyInterface $current_user,
    DateFormatterInterface $date_formatter,
  ) {
    $this->entityTypeManager = $entity_type_manager;
    $this->currentUser = $current_user;
    $this->dateFormatter = $date_formatter;
  }

  /**
   * Performs a content search.
   *
   * @param string $query
   *   The search query.
   * @param int $limit
   *   The number of results to return.
   * @param int $offset
   *   The offset for pagination.
   *
   * @return array
   *   An array containing search results and metadata.
   */
  public function search(string $query, int $limit = 20, int $offset = 0): array {
    $results = [];
    $total = 0;

    if (!empty($query)) {
      $node_storage = $this->entityTypeManager->getStorage('node');

      // Build the query.
      $query_builder = $node_storage->getQuery()
        ->accessCheck(TRUE)
        ->condition('title', $query, 'CONTAINS')
        ->sort('changed', 'DESC');

      // Get total count.
      $count_query = clone $query_builder;
      $total = $count_query->count()->execute();

      // Get results with pagination.
      $nids = $query_builder
        ->range($offset, $limit)
        ->execute();

      if (!empty($nids)) {
        $nodes = $node_storage->loadMultiple($nids);

        foreach ($nodes as $node) {
          $results[] = $this->formatNodeResult($node);
        }
      }
    }

    return [
      'results' => $results,
      'total' => $total,
      'query' => $query,
      'limit' => $limit,
      'offset' => $offset,
    ];
  }

  /**
   * Formats a node for the search results.
   *
   * @param \Drupal\node\NodeInterface $node
   *   The node to format.
   *
   * @return array
   *   The formatted node data.
   */
  protected function formatNodeResult(NodeInterface $node): array {
    $type_storage = $this->entityTypeManager->getStorage('node_type');
    $node_type = $type_storage->load($node->bundle());

    $result = [
      'nid' => $node->id(),
      'title' => $node->getTitle(),
      'type' => $node->bundle(),
      'type_label' => $node_type ? $node_type->label() : $node->bundle(),
      'status' => $node->isPublished() ? 'published' : 'unpublished',
      'changed' => $this->dateFormatter->formatTimeDiffSince($node->getChangedTime()),
      'view_url' => $node->toUrl()->toString(),
      'edit_url' => $node->toUrl('edit-form')->toString(),
    ];

    // Add space references if available.
    if ($node->hasField('field_space') && !$node->get('field_space')->isEmpty()) {
      $spaces = [];
      foreach ($node->get('field_space')->referencedEntities() as $space) {
        $spaces[] = [
          'id' => $space->id(),
          'title' => $space->label(),
        ];
      }
      $result['spaces'] = $spaces;
    }

    return $result;
  }

}
