<?php

declare(strict_types=1);

namespace Drupal\ai\Form;

use Drupal\ai\AiPlatformPluginManager;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form handler for AI Platform entity add and edit forms.
 */
class AiPlatformEntityForm extends EntityForm {

  /**
   * The AI platform plugin manager.
   */
  protected AiPlatformPluginManager $pluginManager;

  /**
   * Constructs an AiPlatformEntityForm object.
   *
   * @param \Drupal\ai\AiPlatformPluginManager $plugin_manager
   *   The AI platform plugin manager.
   */
  public function __construct(AiPlatformPluginManager $plugin_manager) {
    $this->pluginManager = $plugin_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): static {
    return new static(
      $container->get('plugin.manager.ai_platform')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state): array {
    $form = parent::form($form, $form_state);

    /** @var \Drupal\ai\Entity\AiPlatformConfigInterface $entity */
    $entity = $this->entity;

    $form['label'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name'),
      '#default_value' => $entity->label(),
      '#required' => TRUE,
    ];

    $form['id'] = [
      '#type' => 'machine_name',
      '#default_value' => $entity->id(),
      '#machine_name' => [
        'exists' => '\Drupal\ai\Entity\AiPlatformConfig::load',
      ],
      '#disabled' => !$entity->isNew(),
    ];

    $definitions = $this->pluginManager->getDefinitions();
    $options = array_map(fn($def) => $def['label'], $definitions);
    asort($options);

    $form['plugin'] = [
      '#type' => 'select',
      '#title' => $this->t('Platform'),
      '#options' => $options,
      '#default_value' => $entity->get('plugin'),
      '#required' => TRUE,
      '#empty_option' => $this->t('- Select a platform -'),
      '#ajax' => [
        'callback' => '::updatePluginSettings',
        'wrapper' => 'plugin-settings-wrapper',
      ],
    ];

    $form['configuration'] = [
      '#type' => 'container',
      '#id' => 'plugin-settings-wrapper',
      '#tree' => TRUE,
    ];

    $plugin_id = $form_state->getValue('plugin') ?: $entity->get('plugin');
    if ($plugin_id && $this->pluginManager->hasDefinition($plugin_id)) {
      $instance = $entity->getPlatformInstance();
      // Ensure we use the plugin instance matching the current selection.
      if (!$instance || $instance->getPluginId() !== $plugin_id) {
        $instance = $this->pluginManager->createInstance($plugin_id, $entity->get('configuration') ?: []);
      }
      $form['configuration'] = $instance->buildConfigurationForm($form['configuration'], $form_state);
    }

    return $form;
  }

  /**
   * AJAX callback to update the plugin settings container.
   */
  public function updatePluginSettings(array $form, FormStateInterface $form_state): array {
    return $form['configuration'];
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state): void {
    parent::validateForm($form, $form_state);

    $plugin_id = $form_state->getValue('plugin');
    if ($plugin_id && $this->pluginManager->hasDefinition($plugin_id)) {
      $instance = $this->pluginManager->createInstance($plugin_id, $this->entity->get('configuration') ?: []);
      $instance->validateConfigurationForm($form['configuration'], $form_state);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    parent::submitForm($form, $form_state);

    $plugin_id = $form_state->getValue('plugin');
    if ($plugin_id && $this->pluginManager->hasDefinition($plugin_id)) {
      $instance = $this->pluginManager->createInstance($plugin_id, $this->entity->get('configuration') ?: []);
      $instance->submitConfigurationForm($form['configuration'], $form_state);
      // Update the entity configuration with the plugin's submitted values.
      $this->entity->set('configuration', $instance->getConfiguration());
    }

    $this->messenger()->addStatus($this->t('Saved the %label AI Platform.', [
      '%label' => $this->entity->label(),
    ]));
    $form_state->setRedirect('entity.ai_platform.collection');
  }

}
