<?php

namespace Drupal\pagedesigner\Plugin\rest\resource;

use Drupal\Core\Language\LanguageInterface;
use Drupal\pagedesigner\Entity\Element;
use Drupal\pagedesigner\Service\Renderer;
use Drupal\rest\ModifiedResourceResponse;
use Drupal\rest\Plugin\ResourceBase;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * Provides a resource to get rendered elements.
 *
 * @RestResource(
 *   id = "pagedesigner_render",
 *   label = @Translation("Pagedesigner render"),
 *   uri_paths = {
 *     "canonical" = "/pagedesigner/render/{id}",
 *   }
 * )
 */
class RenderResource extends ResourceBase {

  /**
   * Constructs a new ElementResource object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param array $serializer_formats
   *   The available serialization formats.
   * @param \Psr\Log\LoggerInterface $logger
   *   A logger instance.
   * @param \Drupal\pagedesigner\Service\Renderer $renderer
   *   The pagedesigner renderer.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    array $serializer_formats,
    LoggerInterface $logger,
    protected Renderer $renderer,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
          $configuration,
          $plugin_id,
          $plugin_definition,
          $container->getParameter('serializer.formats'),
          $container->get('logger.factory')->get('pagedesigner'),
          $container->get('pagedesigner.service.renderer')
      );
  }

  /**
   * Responds to GET requests.
   *
   * @param int $id
   *   The element to render.
   *
   * @return \Drupal\rest\ModifiedResourceResponse
   *   The HTTP response object.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\HttpException
   *   Throws exception expected.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
   *   If the request is malformed.
   */
  public function get($id) {
    if (!is_numeric($id)) {
      throw new BadRequestHttpException('The entity key must be numeric.');
    }
    $entity = Element::load($id);
    if ($entity == NULL) {
      throw new NotFoundHttpException('The entity does not exist.');
    }
    if (!$entity->access('view')) {
      throw new AccessDeniedHttpException('You are not allowed to view this element.');
    }
    $language = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
    if ($entity->hasTranslation($language)) {
      $entity = $entity->getTranslation($language);
    }

    $renderer = $this->renderer->renderForEdit($entity, $entity->entity->entity);
    $output = $renderer->getOutput();
    $markup = \Drupal::service('renderer')->renderInIsolation($output);
    $response = new ModifiedResourceResponse([
      ['command' => 'pd_markup', 'data' => $markup],
      ['command' => 'pd_styles', 'data' => $renderer->getStyles()],
    ], 201);
    return $response;
  }

}
