<?php

namespace Drupal\nodehive_core;

use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\nodehive_core\Helper\NodehiveLanguageHelper;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Preprocessor for structured content nodes.
 */
class StructuredContentNodePreprocessor {

  use StringTranslationTrait;

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

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

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

  /**
   * The language helper.
   *
   * @var \Drupal\nodehive_core\Helper\NodehiveLanguageHelper
   */
  protected $languageHelper;

  public function __construct(
    AccountProxyInterface $current_user,
    EntityTypeManagerInterface $entity_type_manager,
    LanguageManagerInterface $language_manager,
    NodehiveLanguageHelper $language_helper,
  ) {
    $this->currentUser = $current_user;
    $this->entityTypeManager = $entity_type_manager;
    $this->languageManager = $language_manager;
    $this->languageHelper = $language_helper;
  }

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

  /**
   * Preprocesses node template variables.
   */
  public function preprocess(array &$variables) {
    /** @var \Drupal\node\NodeInterface $node */
    $node = $variables['node'];
    if (!$node->hasField("nodehive_space")) {
      return;
    }

    // Check if any of the target roles exist in the user's roles.
    $access_space = $this->currentUser->hasPermission('administer nodehive space');

    if ($access_space && ($variables['view_mode'] == 'default' || $variables['view_mode'] == 'full')) {
      // Add NodeHive compact sidebar bar.
      $type_label = $node->type->entity ? $node->type->entity->label() : $node->bundle();

      $variables["content"]["nodehive_sidebar"] = [
        '#type' => 'container',
        '#attributes' => [
          'class' => [
            'nodehive-sidebar-compact',
          ],
        ],
        '#cache' => [
          'contexts' => ['cookies:nodehive_sidebar_space'],
        ],
      ];

      // Content info section: type badge + translations.
      $variables["content"]["nodehive_sidebar"]["content_info"] = [
        '#type' => 'container',
        '#attributes' => [
          'class' => ['nodehive-compact-info'],
        ],
        '#weight' => -100,
        'type_badge' => [
          '#type' => 'html_tag',
          '#tag' => 'span',
          '#attributes' => [
            'class' => ['nodehive-type-badge'],
          ],
          '#value' => Html::escape($type_label),
        ],
        'translations' => [
          '#type' => 'container',
          '#attributes' => [
            'class' => ['nodehive-compact-translations'],
          ],
          'links' => $this->languageHelper->buildLanguageViewLinks($node),
        ],
      ];

      // Spaces section: build space data for the switcher.
      $space_refs = $node->get("nodehive_space")->getValue();
      $cookie_space_id = \Drupal::request()->cookies->get('nodehive_sidebar_space');
      $node_url = $node->toUrl()->toString();
      $space_data = [];

      foreach ($space_refs as $space_ref) {
        $space = $this->entityTypeManager->getStorage("nodehive_space")->load($space_ref['target_id']);
        if (!$space) {
          continue;
        }
        $space_urls = [];
        foreach ($space->space_url->getValue() as $value) {
          $space_urls[] = $value['uri'];
        }
        $preview_url = $space_urls[0] ?? '';
        $visual_editor_url = Url::fromRoute("nodehive_visualeditor.visual_editor_single", ["nodehive_space" => $space->id()])
          ->setOption('query', ['url' => $preview_url . $node_url])
          ->toString();

        $space_data[] = [
          'id' => $space->id(),
          'label' => $space->label(),
          'visual_editor_url' => $visual_editor_url,
          'external_url' => $preview_url ? $preview_url . $node_url : '',
          'is_active' => (string) $space->id() === (string) $cookie_space_id,
        ];
      }

      // Determine active space (cookie match or first).
      $active_space = NULL;
      foreach ($space_data as $s) {
        if ($s['is_active']) {
          $active_space = $s;
          break;
        }
      }
      if (!$active_space && !empty($space_data)) {
        $active_space = $space_data[0];
        $space_data[0]['is_active'] = TRUE;
      }

      if ($active_space) {
        $variables["content"]["nodehive_sidebar"]["space_switcher"] = [
          '#type' => 'inline_template',
          '#template' => $this->getSpaceSwitcherTemplate(),
          '#context' => [
            'spaces' => $space_data,
            'active_space' => $active_space,
            'is_multi' => count($space_data) > 1,
            'node_url' => $node_url,
          ],
        ];
      }

      // Configure dropdown: inline at the end.
      $current_url = Url::fromRoute('<current>');
      $destination = $current_url->toString();
      $node_type = $node->bundle();
      $node_type_entity = $this->entityTypeManager->getStorage('node_type')->load($node_type);

      if ($node_type_entity) {
        $user = $this->currentUser;
        if (
          $user->hasPermission('administer content types')
          || $user->hasPermission('administer node display')
          || $user->hasPermission('administer node fields')
          || $user->hasPermission('administer node form display')
        ) {
          $operations = [];

          if ($user->hasPermission('administer node fields')) {
            $operations['manage_fields'] = [
              'title' => $this->t('Manage fields'),
              'url' => Url::fromRoute('entity.node.field_ui_fields', [
                'node_type' => $node_type_entity->id(),
              ], ['query' => ['destination' => $destination]]),
            ];
          }

          if ($user->hasPermission('administer node display')) {
            $operations['manage_display'] = [
              'title' => $this->t('Manage display'),
              'url' => Url::fromRoute('entity.entity_view_display.node.default', [
                'node_type' => $node_type_entity->id(),
                'view_mode_name' => 'default',
              ], ['query' => ['destination' => $destination]]),
            ];
          }

          if ($user->hasPermission('administer node form display')) {
            $operations['manage_form'] = [
              'title' => $this->t('Manage form display'),
              'url' => Url::fromRoute('entity.entity_form_display.node.default', [
                'node_type' => $node_type_entity->id(),
                'form_mode_name' => 'default',
              ], ['query' => ['destination' => $destination]]),
            ];
          }

          if ($user->hasPermission('administer content types')) {
            $operations['edit'] = [
              'title' => $this->t('Manage settings'),
              'url' => Url::fromRoute('entity.node_type.edit_form', [
                'node_type' => $node_type_entity->id(),
              ], ['query' => ['destination' => $destination]]),
            ];
          }

          $links = [];
          foreach ($operations as $operation_id => $operation) {
            $operation['url']->setOption('query', ['destination' => $destination]);
            $links[$operation_id] = [
              'title' => $operation['title'],
              'url' => $operation['url'],
            ];
          }

          if (!empty($links)) {
            $variables['content']['nodehive_sidebar']['configure'] = [
              '#type' => 'container',
              '#attributes' => [
                'class' => ['nodehive-compact-configure'],
              ],
              '#weight' => 55,
              'dropbutton' => [
                '#type' => 'dropbutton',
                '#links' => $links,
                '#attributes' => [
                  'class' => [
                    'dropbutton',
                    'dropbutton--extrasmall',
                    'dropbutton--multiple',
                    'dropbutton--gin',
                  ],
                ],
              ],
            ];
          }
        }
      }
    }

    $variables['#attached']['library'][] = "nodehive_core/node";
  }

  /**
   * Returns the inline Twig template for the space switcher.
   */
  protected function getSpaceSwitcherTemplate(): string {
    return <<<'TWIG'
<div class="nodehive-compact-space">
  <span class="nodehive-compact-space-label nodehive-compact-space-label--active">{{ active_space.label }}</span>
  {% if is_multi %}
    <div class="nodehive-space-switcher">
      <button type="button" class="nodehive-space-switcher__toggle" aria-expanded="false" aria-label="{{ 'Switch space'|t }}">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>
      </button>
      <ul class="nodehive-space-switcher__list">
        <li class="nodehive-space-switcher__heading">{{ 'Also used in'|t }}</li>
        {% for space in spaces %}
          {% if not space.is_active %}
            <li>
              <a href="{{ node_url }}" class="nodehive-space-switcher__item" data-space-id="{{ space.id }}">
                {{ space.label }}
              </a>
            </li>
          {% endif %}
        {% endfor %}
      </ul>
    </div>
  {% endif %}
</div>
<div class="nodehive-compact-space">
  <div class="nodehive-compact-actions">
    {% if active_space.visual_editor_url %}
      <a href="{{ active_space.visual_editor_url }}" class="nodehive-compact-action" title="{{ 'Visual Editor'|t }}">
        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
      </a>
    {% endif %}
    {% if active_space.external_url %}
      <a href="{{ active_space.external_url }}" class="nodehive-compact-action" title="{{ 'Visit website'|t }}" target="_blank">
        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>
      </a>
    {% endif %}
  </div>
</div>
<script>
(function() {
  var switcher = document.querySelector('.nodehive-space-switcher');
  if (!switcher) return;
  var toggle = switcher.querySelector('.nodehive-space-switcher__toggle');
  var list = switcher.querySelector('.nodehive-space-switcher__list');
  toggle.addEventListener('click', function(e) {
    e.stopPropagation();
    var open = list.classList.toggle('is-open');
    toggle.setAttribute('aria-expanded', String(open));
  });
  document.addEventListener('click', function() {
    list.classList.remove('is-open');
    toggle.setAttribute('aria-expanded', 'false');
  });
  list.addEventListener('click', function(e) {
    var item = e.target.closest('.nodehive-space-switcher__item');
    if (item) {
      e.preventDefault();
      document.cookie = 'nodehive_sidebar_space=' + item.dataset.spaceId + ';path=/;max-age=31536000;SameSite=Lax';
      window.location.reload();
    }
  });
})();
</script>
TWIG;
  }

}
