<?php

declare(strict_types=1);

namespace Drupal\nodehive_redirect\Hook;

use Drupal\Component\Utility\Crypt;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\redirect\Entity\Redirect;

/**
 * Hook implementations for nodehive_redirect.
 */
final class RedirectHooks {

  /**
   * Adds the nodehive_space base field to the redirect entity type.
   */
  public function entityBaseFieldInfo(EntityTypeInterface $entityType): array {
    $fields = [];
    if ($entityType->id() === 'redirect') {
      $fields['nodehive_space'] = BaseFieldDefinition::create('entity_reference')
        ->setLabel(new TranslatableMarkup('NodeHive Space'))
        ->setDescription(new TranslatableMarkup('The NodeHive space this redirect belongs to. NULL means a global redirect.'))
        ->setSetting('target_type', 'nodehive_space')
        ->setCardinality(1)
        ->setRequired(FALSE)
        ->setDisplayOptions('form', [
          'type' => 'entity_reference_autocomplete',
          'weight' => 10,
          'settings' => [
            'match_operator' => 'CONTAINS',
            'size' => 60,
            'placeholder' => '',
          ],
        ])
        ->setDisplayConfigurable('view', FALSE)
        ->setDisplayConfigurable('form', TRUE);
    }

    return $fields;
  }

  /**
   * Regenerates the redirect hash to include the nodehive_space value.
   */
  public function redirectPresave(Redirect $redirect): void {
    // This fires after Redirect::preSave() has already set the hash.
    // We regenerate the hash to include nodehive_space, allowing the same
    // source path to exist in multiple spaces without a unique key conflict.
    $source = $redirect->get('redirect_source')->get(0);
    $path = $source->path ?? '';
    $query = (array) ($source->query ?? []);
    $lang = $redirect->get('language')->value;
    /** @var int|string $spaceId */
    $spaceId = $redirect->get('nodehive_space')->target_id ?? '';

    $hash = [
      'source' => trim(mb_strtolower($path), '/'),
      'language' => $lang,
      'space' => $spaceId,
    ];
    if (!empty($query)) {
      $hash['source_query'] = $query;
    }
    redirect_sort_recursive($hash, 'ksort');

    $redirect->set('hash', Crypt::hashBase64(serialize($hash)));
  }

}
