<?php

namespace Drupal\nodehive_area_fragment\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Url;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides a 'Connected spaces' Block.
 *
 * @Block(
 *   id = "nodehive_area_fragment_connected_spaces_block",
 *   admin_label = @Translation("Connected spaces"),
 *   category = @Translation("Nodehive"),
 * )
 */
class ConnectedSpacesBlock extends BlockBase implements ContainerFactoryPluginInterface {

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

  /**
   * The route match.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

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

  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * Constructs a new ConnectedSpaceBlock instance.
   *
   * @param array $configuration
   *   The plugin configuration.
   * @param string $plugin_id
   *   The plugin ID.
   * @param mixed $plugin_definition
   *   The plugin definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match.
   * @param \Drupal\Core\Session\AccountProxyInterface $account
   *   The current user.
   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
   *   The language manager.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    EntityTypeManagerInterface $entity_type_manager,
    RouteMatchInterface $route_match,
    AccountProxyInterface $account,
    LanguageManagerInterface $language_manager,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entity_type_manager;
    $this->routeMatch = $route_match;
    $this->account = $account;
    $this->languageManager = $language_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('current_route_match'),
      $container->get('current_user'),
      $container->get('language_manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $supported_entities = [
      'nodehive_area' => [
        'space_field'  => 'space_id',
      ],
    ];

    if (!$this->account->hasPermission('administer nodehive space')) {
      return NULL;
    }

    $entity = NULL;
    foreach ($supported_entities as $entity_id => $entity_properties) {
      $route_entity = $this->routeMatch->getParameter($entity_id);
      if (!$route_entity) {
        continue;
      }

      if ($route_entity instanceof EntityInterface) {
        $entity = $route_entity;
        continue;
      }

      // Try to load it.
      $entity = $this->entityTypeManager
        ->getStorage($entity_id)
        ->load($route_entity);
    }

    if (!$entity) {
      return [];
    }

    // Load spaces.
    $entity_configuration = $supported_entities[$entity->getEntityTypeId()];
    $spaces = $entity->get($entity_configuration['space_field'])->referencedEntities();

    $build = [
      '#type' => 'container',
      '#attributes' => [
        'class' => ["block", "layer-wrapper", "gin-layer-wrapper"],
      ],
    ];

    $build["content"] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => ["nodehive-sidebar"],
      ],
    ];

    $build["content"]["nodehive_sidebar"]["spaces"] = [
      '#markup' => '<div>Connected Spaces:</div>',
      '#type' => 'container',
      '#attributes' => [
        'class' => ["nodehive-spaces"],
      ],
    ];

    $space_urls = [];
    foreach ($spaces as $space) {
      foreach ($space->space_url->getValue() as $value) {
        $space_urls[] = $value['uri'];
      }

      $build["content"]["nodehive_sidebar"]["spaces"][$space->id()] = [
        '#type' => 'link',
        '#title' => $space->label(),
        '#url' => Url::fromRoute("entity.nodehive_space.canonical", ["nodehive_space" => $space->id()]),
        '#attributes' => [
          'class' => ["button", "button--small"],
        ],
      ];

      if ($entity instanceof NodeInterface) {
        $nid = $entity->id();
        $preview_url = $space_urls[0] ?? FALSE;
        $query_parameters = ['url' => $preview_url . '/node/' . $nid];

        $variables["content"]["nodehive_sidebar"]["spaces"]['editor'][$space->id()] = [
          '#type' => 'link',
          '#title' => 'Visual Editor',
          '#url' => Url::fromRoute("nodehive_visualeditor.visual_editor_single", ["nodehive_space" => $space->id()])->setOption('query', $query_parameters),
          '#attributes' => [
            'class' => ["button", "button--small"],
          ],
        ];
      }
    }

    if ($entity->isTranslatable()) {
      $build["content"]["nodehive_sidebar"]["nodehive_lang_switcher"] = [
        '#type' => 'container',
        '#markup' => '<div>Translations</div>',
        '#attributes' => [
          'class' => ["nodehive-lang-switcher"],
        ],

        '#weight' => 50,
      ];

      $languages = $this->languageManager->getLanguages();
      $current_language = $this->languageManager
        ->getCurrentLanguage()
        ->getId();

      foreach ($languages as $lang) {
        if ($entity->hasTranslation($lang->getId())) {
          $variables["content"]["nodehive_sidebar"]["nodehive_lang_switcher"][$lang->getId()] = [
            '#type' => 'link',
            '#title' => 'View ' . $lang->getName(),
            '#url' => $entity->toUrl('canonical', ['language' => $lang]),
            '#attributes' => [
              'class' => ["button", "button--small"],
            ],
          ];

          $variables["content"]["nodehive_sidebar"]["nodehive_lang_switcher"][$lang->getId() . 'edit'] = [
            '#type' => 'link',
            '#title' => 'Edit ' . $lang->getName(),
            '#url' => $entity->getTranslation($lang->getId())->toUrl('edit-form'),
            '#attributes' => [
              'class' => ["button", "button--small"],
            ],
          ];
        }
        else {
          $variables["content"]["nodehive_sidebar"]["nodehive_lang_switcher"][$lang->getId() . 'add'] = [
            '#type' => 'link',
            '#title' => 'Add ' . $lang->getName(),
            '#url' => Url::fromRoute('entity.' . $entity->getEntityTypeId() . '.content_translation_add', [
              'source' => $entity->language()->getId(),
              'target' => $lang->getId(),
              $entity->getEntityTypeId() => $entity->id(),
            ]),
            '#attributes' => [
              'class' => ["button", "button--small"],
            ],
          ];
        }

        if ($current_language === $lang->getId()) {
          $build["content"]["nodehive_sidebar"]["nodehive_lang_switcher"][$lang->getId()]['#attributes']['class'][] = "button--primary";
        }
      }
    }

    $build['#cache']['max-age'] = 0;
    $build['#attached']['library'][] = "nodehive_core/node";

    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    return 0;
  }

}
