<?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 creating NodeHive Spaces.
 */
#[Mcp(
  id: 'create-space-tool',
  name: new TranslatableMarkup('Create Space Tool'),
  description: new TranslatableMarkup('Provides MCP tool for creating new NodeHive Spaces.'),
)]
class CreateSpaceTool 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' => [
        'default_space_type' => 'full_website',
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(
    array $form,
    FormStateInterface $form_state,
  ): array {
    $config = $this->getConfiguration();

    $form['default_space_type'] = [
      '#type' => 'select',
      '#title' => $this->t('Default Space Type'),
      '#description' => $this->t('Default space type for new spaces.'),
      '#options' => [
        'full_website' => $this->t('Website'),
        'directory' => $this->t('Website Directory'),
        'database' => $this->t('Database'),
        'other' => $this->t('Other'),
      ],
      '#default_value' => $config['config']['default_space_type'] ?? 'full_website',
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function getTools(): array {
    $config = $this->getConfiguration();

    return [
      new Tool(
        name: 'create-nodehive-space',
        description: 'Create a new NodeHive Space with specified properties.',
        inputSchema: [
          'type' => 'object',
          'properties' => [
            'label' => [
              'type' => 'string',
              'description' => 'The name/label of the space.',
            ],
            'space_url' => [
              'type' => 'string',
              'format' => 'uri',
              'description' => 'The URL for the space.',
            ],
            'space_type' => [
              'type' => 'string',
              'description' => 'Space type (Website, Directory/Subdirectory, Database, Other)',
              'enum' => ['full_website', 'directory', 'database', 'other'],
              'default' => $config['config']['default_space_type'] ?? 'full_website',
            ],
            'status' => [
              'type' => 'boolean',
              'description' => 'Whether the space is enabled.',
              'default' => TRUE,
            ],
            'tags' => [
              'type' => 'array',
              'items' => [
                'type' => 'string',
              ],
              'description' => 'Tags for the space.',
            ],
          ],
          'required' => ['label', 'space_url'],
        ],
      ),
    ];
  }

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

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

  /**
   * Execute the create space tool.
   */
  protected function executeCreateSpace(array $arguments): array {
    try {
      $config = $this->getConfiguration();

      // Validate required fields.
      if (empty($arguments['label'])) {
        throw new \InvalidArgumentException('Label is required.');
      }
      if (empty($arguments['space_url'])) {
        throw new \InvalidArgumentException('Space URL is required.');
      }

      // Create the space entity.
      $space_storage = $this->entityTypeManager->getStorage('nodehive_space');
      $space = $space_storage->create([
        'label' => $arguments['label'],
        'space_url' => ['uri' => $arguments['space_url']],
        'space_type' => $arguments['space_type'] ?? $config['config']['default_space_type'] ?? 'full_website',
        'status' => $arguments['status'] ?? TRUE,
      ]);

      // Handle tags if provided.
      if (!empty($arguments['tags'])) {
        $tag_ids = $this->createOrGetTags($arguments['tags']);
        $space->set('tags', $tag_ids);
      }

      $space->save();

      return [
        [
          'type' => 'text',
          'text' => sprintf(
            'Successfully created NodeHive Space "%s" with ID %d. Space URL: %s',
            $space->label(),
            $space->id(),
            $arguments['space_url']
          ),
        ],
      ];
    }
    catch (\Exception $e) {
      return [
        [
          'type' => 'text',
          'text' => 'Error creating space: ' . $e->getMessage(),
        ],
      ];
    }
  }

  /**
   * Create or get existing tags.
   */
  protected function createOrGetTags(array $tag_names): array {
    $tag_ids = [];
    $term_storage = $this->entityTypeManager->getStorage('taxonomy_term');

    foreach ($tag_names as $tag_name) {
      // Try to find existing tag.
      $existing_terms = $term_storage->loadByProperties([
        'name' => $tag_name,
        'vid' => 'nodehive_space_tags',
      ]);

      if (!empty($existing_terms)) {
        $tag_ids[] = reset($existing_terms)->id();
      }
      else {
        // Create new tag.
        $term = $term_storage->create([
          'name' => $tag_name,
          'vid' => 'nodehive_space_tags',
        ]);
        $term->save();
        $tag_ids[] = $term->id();
      }
    }

    return $tag_ids;
  }

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

}
