<?php

declare(strict_types=1);

namespace Drupal\ai\Plugin\AiPlatform;

use Drupal\ai\Plugin\ConfigurablePluginBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Symfony\AI\Platform\ModelCatalog\ModelCatalogInterface;
use Symfony\AI\Platform\PlatformInterface;
use Symfony\AI\Platform\Result\DeferredResult;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * Base class for ai_platform plugins.
 */
abstract class AiPlatformPluginBase extends ConfigurablePluginBase implements PluginFormInterface, AiPlatformInterface, ContainerFactoryPluginInterface {

  /**
   * The HTTP client.
   *
   * @var \Symfony\Contracts\HttpClient\HttpClientInterface|null
   */
  protected ?HttpClientInterface $httpClient = NULL;

  /**
   * The event dispatcher.
   *
   * @var \Psr\EventDispatcher\EventDispatcherInterface|null
   */
  protected ?EventDispatcherInterface $eventDispatcher = NULL;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
    $instance = new static($configuration, $plugin_id, $plugin_definition);
    $instance->httpClient = $container->get(HttpClientInterface::class);
    $instance->eventDispatcher = $container->get(EventDispatcherInterface::class);
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function label(): string {
    return (string) $this->pluginDefinition['label'];
  }

  /**
   * Gets the initialized platform instance.
   *
   * @return \Symfony\AI\Platform\PlatformInterface
   *   The platform instance.
   */
  final protected function platform(): PlatformInterface {
    $platform = $this->initializePlatform();
    // @todo Provide support for wrapping platforms (caching, logging,
    //   failover, etc.),
    // similar to Symfony's AiBundle implementation:
    // https://github.com/symfony/ai/blob/v0.3.3/src/ai-bundle/src/AiBundle.php#L179-L186
    return $platform;
  }

  /**
   * Initializes the underlying Symfony AI platform.
   *
   * @return \Symfony\AI\Platform\PlatformInterface
   *   The initialized platform.
   */
  abstract protected function initializePlatform(): PlatformInterface;

  /**
   * {@inheritdoc}
   */
  final public function invoke(string $model, object|array|string $input, array $options = []): DeferredResult {
    return $this->platform()->invoke($model, $input, $options);
  }

  /**
   * {@inheritdoc}
   */
  public function getModelCatalog(): ModelCatalogInterface {
    return $this->platform()->getModelCatalog();
  }

  /**
   * {@inheritdoc}
   */
  public function getAvailableConfiguration(string $operation_type, string $model_id): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration(): array {
    return [];
  }

}
