<?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\Tool;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * MCP plugin for listing NodeHive Spaces.
 */
#[Mcp(
  id: 'list-spaces-tool',
  name: new TranslatableMarkup('List Spaces Tool'),
  description: new TranslatableMarkup('Provides MCP tool for listing NodeHive Spaces.'),
)]
class ListSpacesTool 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 tool.
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function getTools(): array {
    return [
      new Tool(
        name: 'list-nodehive-spaces',
        description: 'List all NodeHive Spaces with their details.',
        inputSchema: [
          'type' => 'object',
          'properties' => [
            'limit' => [
              'type' => 'integer',
              'description' => 'Maximum number of spaces to return (default: all).',
              'minimum' => 1,
            ],
            'offset' => [
              'type' => 'integer',
              'description' => 'Number of spaces to skip (default: 0).',
              'minimum' => 0,
              'default' => 0,
            ],
            'space_type' => [
              'type' => 'string',
              'description' => 'Filter by space type.',
              'enum' => ['full_website', 'directory', 'database', 'other'],
            ],
            'status' => [
              'type' => 'boolean',
              'description' => 'Filter by status (enabled/disabled).',
            ],
          ],
          'required' => [],
        ],
      ),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function executeTool(string $toolId, mixed $arguments): array {
    if ($toolId === md5('list-nodehive-spaces')) {
      return $this->executeListSpaces($arguments);
    }

    throw new \InvalidArgumentException('Unknown tool: ' . $toolId);
  }

  /**
   * Execute the list spaces tool.
   */
  protected function executeListSpaces(array $arguments): array {
    try {
      $space_storage = $this->entityTypeManager->getStorage('nodehive_space');

      // Build query with filters.
      $query = $space_storage->getQuery()
        ->accessCheck(FALSE)
        ->sort('created', 'DESC');

      // Apply filters.
      if (isset($arguments['space_type'])) {
        $query->condition('space_type', $arguments['space_type']);
      }

      if (isset($arguments['status'])) {
        $query->condition('status', $arguments['status'] ? 1 : 0);
      }

      // Apply pagination.
      $offset = $arguments['offset'] ?? 0;
      if ($offset > 0) {
        $query->range($offset, $arguments['limit'] ?? NULL);
      }
      elseif (isset($arguments['limit'])) {
        $query->range(0, $arguments['limit']);
      }

      $space_ids = $query->execute();
      $spaces = $space_storage->loadMultiple($space_ids);

      $spaces_data = [];
      foreach ($spaces as $space) {
        $space_info = [
          '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' => date('Y-m-d H:i:s', $space->get('created')->value),
          'changed' => date('Y-m-d H:i:s', $space->get('changed')->value),
          'tags' => [],
        ];

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

        $spaces_data[] = $space_info;
      }

      $total_count = $space_storage->getQuery()
        ->accessCheck(FALSE)
        ->count()
        ->execute();

      $filtered_count = count($spaces_data);

      return [
        [
          'type' => 'text',
          'text' => sprintf(
            "Found %d NodeHive Spaces (showing %d):\n\n%s",
            $total_count,
            $filtered_count,
            $this->formatSpacesList($spaces_data)
          ),
        ],
      ];
    }
    catch (\Exception $e) {
      return [
        [
          'type' => 'text',
          'text' => 'Error listing spaces: ' . $e->getMessage(),
        ],
      ];
    }
  }

  /**
   * Format spaces list for display.
   */
  protected function formatSpacesList(array $spaces_data): string {
    if (empty($spaces_data)) {
      return 'No spaces found.';
    }

    $output = [];
    foreach ($spaces_data as $space) {
      $status = $space['status'] ? 'Enabled' : 'Disabled';
      $tags = !empty($space['tags']) ? ' [Tags: ' . implode(', ', $space['tags']) . ']' : '';

      $output[] = sprintf(
        "• %s (ID: %d)\n  URL: %s\n  Type: %s | Status: %s%s\n  Created: %s",
        $space['label'],
        $space['id'],
        $space['space_url'],
        $space['space_type'],
        $status,
        $tags,
        $space['created']
      );
    }

    return implode("\n\n", $output);
  }

  /**
   * {@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');
  }

}
