<?php

namespace Drupal\nodehive_core\Controller;

use Drupal\Core\Cache\CacheableJsonResponse;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Url;
use Drupal\path_alias\AliasManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * Translate paths into all languages.
 */
class TranslatedPathsController extends ControllerBase {

  /**
   * The entity type manager.
   *
   * @var \Drupal\path_alias\AliasManagerInterface
   */
  protected $aliasManager;
  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * Constructs a new TranslatedPathsController object.
   *
   * @param \Drupal\path_alias\AliasManagerInterface $alias_manager
   *   The alias manager.
   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
   *   The language manager.
   */
  public function __construct(AliasManagerInterface $alias_manager, LanguageManagerInterface $language_manager) {
    $this->aliasManager = $alias_manager;
    $this->languageManager = $language_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('path_alias.manager'),
      $container->get('language_manager')
    );
  }

  /**
   * Get path aliases in all languages.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   */
  public function handle(Request $request): JsonResponse|CacheableJsonResponse {
    $path = $request->query->get('path');
    if (!$path) {
      return new JsonResponse(['error' => 'Missing path parameter.'], 400);
    }
    $translated_paths = [];
    $languages = $this->languageManager->getLanguages();
    $system_path = $this->aliasManager->getPathByAlias($path);

    foreach ($languages as $language) {
      $system_path = $this->aliasManager->getPathByAlias($path, $language->getId());
      if ($system_path !== $path) {
        break;
      }
    }

    // For each language, get the alias.
    foreach ($languages as $language) {
      $alias = $this->aliasManager->getAliasByPath($system_path, $language->getId());
      $translated_paths[$language->getId()] = $alias;
    }

    // Get the node from the path for caching.
    $path_object = Url::fromUri('internal:' . $system_path);
    try {
      $route_parameters = $path_object->getRouteParameters();
    }
    catch (\UnexpectedValueException $e) {
      return new JsonResponse(['error' => 'Invalid internal path.'], 400);
    }
    $node = NULL;
    if (isset($route_parameters['node'])) {
      $node = $this->entityTypeManager()->getStorage('node')->load($route_parameters['node']);
    }

    // Create a CacheableJsonResponse and set cache metadata.
    $response = new CacheableJsonResponse($translated_paths);
    $cache_metadata = new CacheableMetadata();
    $cache_metadata->addCacheContexts(['url.query_args:path']);
    $response->addCacheableDependency($cache_metadata);

    if ($node) {
      $response->addCacheableDependency($node);
    }

    return $response;
  }

}
