<?php

namespace Drupal\gutenberg\Controller;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\Renderer;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;

/**
 * Returns responses for our blocks routes.
 */
class EntityController extends ControllerBase {

  /**
   * Drupal\Core\Config\ConfigFactoryInterface instance.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Drupal\Core\Render\Renderer instance.
   *
   * @var \Drupal\Core\Render\Renderer
   */
  protected $renderer;

  /**
   * Drupal\Core\Plugin\Context\ContextRepositoryInterface
   * 
   * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface
   */
  protected $contextRepository;

  /**
   * Drupal\Core\Entity\EntityTypeManagerInterface
   * 
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Drupal\Core\Entity\EntityDisplayRepositoryInterface
   * 
   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
   */
  protected $entityDisplayRepository;

  /**
   * BlocksController constructor.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   Config factory service.
   * @param \Drupal\Core\Render\Renderer $renderer
   *   Render service.
   * @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository
   *   Context repository service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity type manager service.
   * @return void
   */
  public function __construct(
    ConfigFactoryInterface $config_factory,
    Renderer $renderer,
    ContextRepositoryInterface $context_repository,
    EntityTypeManagerInterface $entity_type_manager,
    EntityDisplayRepositoryInterface $entity_display_repository
  ) {
    $this->configFactory = $config_factory;
    $this->renderer = $renderer;
    $this->contextRepository = $context_repository;
    $this->entityTypeManager = $entity_type_manager;
    $this->entityDisplayRepository = $entity_display_repository;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): self {
    return new static(
      $container->get('config.factory'),
      $container->get('renderer'),
      $container->get('context.repository'),
      $container->get('entity_type.manager'),
      $container->get('entity_display.repository')
    );
  }

  /**
   * Return a rendered entity by type and bundle.
   * 
   * @param \Symfony\Component\HttpFoundation\Request $request
   *  The request object.
   * @param integer $entity_id
   *  The entity id.
   * @param string $entity_type
   *  The entity type.
   * @param string $view_mode
   *  The view mode.
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   */
  public function renderEntity(Request $request, $entity_id, $entity_type, $view_mode = 'default') {
    $entity = $this->entityTypeManager->getStorage($entity_type)->load($entity_id);
    $entity_view = $this->entityTypeManager->getViewBuilder($entity_type)->view($entity, $view_mode);
    $entity_rendered = $this->renderer->renderRoot($entity_view);
    return new JsonResponse([
      'entity' => $entity_rendered,
    ]);
  }

  /**
   * Return view modes for an entity type.
   * 
   * @param \Symfony\Component\HttpFoundation\Request $request
   * The request object.
   * @param string $entity_type
   * The entity type.
   * @param string $bundle
   * The bundle.
   * 
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   */
  public function viewModes(Request $request, $entity_type, $bundle) {
    return new JsonResponse([
      'view_modes' => $this->entityDisplayRepository->getViewModeOptionsByBundle($entity_type, $bundle),
    ]);
  }
}
