<?php

namespace Drupal\nodehive_mcp\Plugin\Mcp;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\mcp\Attribute\Mcp;
use Drupal\mcp\Plugin\McpPluginBase;
use Drupal\mcp\ServerFeatures\Resource;
use Drupal\mcp\ServerFeatures\ResourceTemplate;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * NodeHive Space MCP plugin that provides resources for spaces.
 */
#[Mcp(
  id: 'nodehive-space-resources',
  name: new TranslatableMarkup('NodeHive Space Resources'),
  description: new TranslatableMarkup('Provides MCP resources for accessing NodeHive Spaces data.'),
)]
class NodeHiveSpaceResources extends McpPluginBase implements ContainerFactoryPluginInterface {

  use StringTranslationTrait;

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

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * {@inheritDoc}
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition,
  ) {
    $instance = parent::create(
      $container, $configuration, $plugin_id, $plugin_definition
    );
    $instance->entityTypeManager = $container->get('entity_type.manager');
    $instance->moduleHandler = $container->get('module_handler');

    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration(): array {
    return [
      'enabled' => TRUE,
      'config' => [],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(
    array $form,
    FormStateInterface $form_state,
  ): array {
    // No specific configuration needed for this plugin.
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function getResources(): array {
    $resources = [];

    // List all spaces.
    $resources[] = new Resource(
      uri: 'spaces',
      name: 'NodeHive Spaces',
      description: 'List of all NodeHive Spaces.',
      mimeType: 'application/json',
      text: json_encode($this->getSpacesData()),
    );

    return $resources;
  }

  /**
   * {@inheritdoc}
   */
  public function getResourceTemplates(): array {
    return [
      new ResourceTemplate(
        uriTemplate: 'space/{id}',
        name: 'NodeHive Space Details',
        description: 'Detailed information about a specific NodeHive Space.',
        mimeType: 'application/json',
      ),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function readResource(string $resourceId): array {
    // Base resources.
    if ($resourceId === 'spaces') {
      return array_filter(
        $this->getResources(),
        fn(Resource $resource) => $resource->uri === $resourceId
      );
    }

    // Individual space details.
    if (preg_match('/^space\/(\d+)$/', $resourceId, $matches)) {
      $space_id = $matches[1];
      $space_storage = $this->entityTypeManager->getStorage('nodehive_space');
      $space = $space_storage->load($space_id);

      if (!$space) {
        throw new \InvalidArgumentException("Space with ID $space_id not found.");
      }

      $space_data = [
        'id' => $space->id(),
        'label' => $space->label(),
        'space_url' => $space->get('space_url')->uri,
        'space_type' => $space->get('space_type')->value,
        'status' => (bool) $space->get('status')->value,
        'created' => $space->get('created')->value,
        'changed' => $space->get('changed')->value,
        'tags' => [],
      ];

      // Get tags.
      if (!$space->get('tags')->isEmpty()) {
        foreach ($space->get('tags')->referencedEntities() as $tag) {
          $space_data['tags'][] = $tag->label();
        }
      }

      return [
        new Resource(
          uri: "space/$space_id",
          name: $space->label(),
          description: "Details for NodeHive Space: " . $space->label(),
          mimeType: 'application/json',
          text: json_encode($space_data),
        ),
      ];
    }

    throw new \InvalidArgumentException("Unknown resource: $resourceId");
  }

  /**
   * Get spaces data for resources.
   */
  protected function getSpacesData(): array {
    $space_storage = $this->entityTypeManager->getStorage('nodehive_space');
    $spaces = $space_storage->loadMultiple();

    $spaces_data = [];
    foreach ($spaces as $space) {
      $spaces_data[] = [
        'id' => $space->id(),
        'label' => $space->label(),
        'space_url' => $space->get('space_url')->uri,
        'space_type' => $space->get('space_type')->value,
        'status' => (bool) $space->get('status')->value,
        'created' => $space->get('created')->value,
        'changed' => $space->get('changed')->value,
      ];
    }

    return $spaces_data;
  }

  /**
   * {@inheritdoc}
   */
  public function hasAccess(): AccessResult {
    return AccessResult::allowedIfHasPermission(
      $this->currentUser, 'use nodehive mcp tools'
    );
  }

  /**
   * {@inheritdoc}
   */
  public function checkRequirements(): bool {
    return $this->moduleHandler->moduleExists('nodehive_core') &&
           $this->moduleHandler->moduleExists('mcp');
  }

}
