<?php

namespace Drupal\nodehive_core\Plugin\DashboardBlock;

use Drupal\content_planner\DashboardBlockBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;

use Symfony\Component\HttpFoundation\Request;

/**
 * Provides a 'NodeHiveSpacesCardsBlock' block to display spaces as cards.
 *
 * @DashboardBlock(
 *   id = "node_hive_spaces_cards_block",
 *   name = @Translation("NodeHive Spaces Cards"),
 *   category = "NodeHive",
 *   id_category = "nodehive"
 * )
 */
class NodeHiveSpacesCardsBlock extends DashboardBlockBase implements ContainerFactoryPluginInterface {

  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public function build() {
    $build = [];
    $config = $this->getConfiguration();

    // Extract selected space IDs where 'select' is set to 1.
    $selected_spaces_config = !empty($config['plugin_specific_config']['spaces']) ? $config['plugin_specific_config']['spaces'] : [];
    $selected_space_ids = array_filter($selected_spaces_config, function ($space) {
      return !empty($space['select']);
    });

    // Get only the keys (space IDs) of the selected spaces.
    $selected_space_ids = array_keys($selected_space_ids);

    // Start building the query to load spaces.
    $space_storage = $this->entityTypeManager->getStorage('nodehive_space');
    $spaces_query = $space_storage->getQuery()
      ->accessCheck(TRUE)
      ->condition('status', 1);

    // If specific spaces are selected, adjust the query to load only those.
    // Otherwise, the query remains unchanged to load all spaces.
    if (!empty($selected_space_ids)) {
      $spaces_query->condition('id', $selected_space_ids, 'IN');
    }

    $space_ids = $spaces_query->execute();
    $spaces = [];
    if ($space_ids) {
      $spaces = $space_storage->loadMultiple($space_ids);
    }

    // If no specific spaces are selected and no spaces are found,
    // load all spaces.
    if (empty($selected_space_ids) && empty($spaces)) {
      $spaces = $space_storage->loadMultiple();
    }

    // Sort spaces by weight if specific spaces are selected.
    if (!empty($selected_space_ids)) {
      uasort($spaces, function ($a, $b) use ($selected_spaces_config) {
        $weight_a = $selected_spaces_config[$a->id()]['weight'] ?? 0;
        $weight_b = $selected_spaces_config[$b->id()]['weight'] ?? 0;
        return $weight_a <=> $weight_b;
      });
    }

    // Determine the class for desktop columns based on configuration.
    $desktop_columns_class = 'desktop-columns-' . ($config['plugin_specific_config']['desktop_columns'] ?? '4');

    // Container for all space cards.
    $build['spaces_cards'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => ['nodehive-spaces-cards-container', $desktop_columns_class],
      ],
    ];

    foreach ($spaces as $space) {
      // Generate URL for the space.
      $url = $space->toUrl();
      $external_url = '';

      if (!$space->get('space_url')->isEmpty()) {
        $first_link = $space->get('space_url')->first()->getValue();
        $external_url = $first_link['uri'] ?? '';
      }

      // Create the card as a single clickable link.
      $card_container = [
        '#type' => 'html_tag',
        '#tag' => 'a',
        '#attributes' => [
          'class' => ['nodehive-space-card'],
          'href' => $url->toString(),
        ],
        'children' => [],
      ];

      // Add the thumbnail as a div with background-image.
      $card_container['children']['thumbnail'] = [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#attributes' => [
          'class' => ['nodehive-space-card-thumbnail'],
          'style' => 'background-image: url("https://preview.nodehive.com/api/screenshot?resX=1600&resY=900&outFormat=jpg&waitTime=200&isFullPage=false&dismissModals=false&url=' . $external_url . '")',
        ],
      ];

      // Add title below thumbnail.
      $card_container['children']['title_below'] = [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#attributes' => ['class' => ['nodehive-space-card-title-below']],
        '#value' => $space->label(),
      ];

      // Add stats (contents + editors count).
      $contents_count = (int) $this->entityTypeManager->getStorage('node')
        ->getQuery()
        ->accessCheck(FALSE)
        ->condition('nodehive_space', $space->id())
        ->count()
        ->execute();
      $editors_count = $space->editors->count();
      $card_container['children']['stats'] = [
        '#type' => 'html_tag',
        '#tag' => 'div',
        '#attributes' => ['class' => ['nodehive-space-card-stats']],
        '#value' => $this->t('@count contents · @editors editors', [
          '@count' => $contents_count,
          '@editors' => $editors_count,
        ]),
      ];

      // Add the card container to the build array.
      $build['spaces_cards'][] = $card_container;
    }

    $build['#attached']['library'][] = 'nodehive_core/nodehive-spaces-cards';

    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function getConfigSpecificFormFields(FormStateInterface &$form_state, Request &$request, array $block_configuration) {
    $form = [];
    $spaces = $this->entityTypeManager->getStorage('nodehive_space')->loadMultiple();

    $options = [];
    foreach ($spaces as $space_id => $space) {
      $options[$space_id] = [
        'label' => $space->label(),
      // Default weight.
        'weight' => 50,
      // Default select value.
        'select' => 0,
      ];
    }

    // Load selected spaces from block configuration.
    $selected_spaces = $block_configuration['plugin_specific_config']['spaces'] ?? [];

    // Update weights in options based on selected_spaces configuration.
    foreach ($selected_spaces as $space_id => $config) {
      if (isset($options[$space_id])) {
        $options[$space_id]['weight'] = $config['weight'] ?? 50;
        $options[$space_id]['select'] = $config['select'] ?? 0;
      }
    }

    // Sort options by weight.
    uasort($options, function ($a, $b) {
      return $a['weight'] <=> $b['weight'];
    });

    $form['note'] = [
      '#type' => 'markup',
      '#markup' => $this->t('Select specific spaces to display. Leaving all unselected will display all available spaces.'),
      '#prefix' => '<div class="description">',
      '#suffix' => '</div>',
    ];

    // Define the table.
    $form['spaces'] = [
      '#type' => 'table',
      '#description' => $this->t('Select the spaces to display as cards.'),
      '#header' => [
        'select' => $this->t('Select'),
        'label' => $this->t('Space Name'),
        // Add more headers if needed.
        'weight' => $this->t('Weight'),
      ],
      '#empty' => $this->t('No spaces available.'),
      '#tabledrag' => [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'space-order-weight',
        ],
      ],
    ];

    // Populate the table rows.
    foreach ($options as $space_id => $option) {
      $form['spaces'][$space_id]['#attributes']['class'][] = 'draggable';
      $form['spaces'][$space_id]['select'] = [
        '#type' => 'checkbox',
        '#default_value' => $option['select'],
      ];
      $form['spaces'][$space_id]['label'] = [
        '#markup' => $option['label'],
      ];
      // Define the weight field for ordering.
      $form['spaces'][$space_id]['weight'] = [
        '#type' => 'weight',
        '#title' => $this->t('Weight for @title', ['@title' => $option['label']]),
        '#title_display' => 'invisible',
        '#default_value' => $option['weight'],
        '#attributes' => ['class' => ['space-order-weight']],
      ];
    }

    $column_options = [
      '1' => $this->t('1 column'),
      '2' => $this->t('2 columns'),
      '3' => $this->t('3 columns'),
      '4' => $this->t('4 columns'),
      '5' => $this->t('5 columns'),
      '6' => $this->t('6 columns'),
    ];

    $form['desktop_columns'] = [
      '#type' => 'select',
      '#title' => $this->t('Desktop Columns'),
      '#description' => $this->t('Select the number of columns to display in desktop view.'),
      '#options' => $column_options,
    // Default to 4 columns if not set.
      '#default_value' => $block_configuration['plugin_specific_config']['desktop_columns'] ?? '4',
    ];

    return $form;
  }

}
