<?php

namespace Drupal\ai_ckeditor\Plugin\AiCKEditor;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\ai_ckeditor\AiCKEditorPluginBase;
use Drupal\ai_ckeditor\Attribute\AiCKEditor;
use Drupal\ai_ckeditor\Command\AiRequestCommand;

/**
 * Plugin to do AI completion.
 */
#[AiCKEditor(
  id: 'ai_ckeditor_completion',
  label: new TranslatableMarkup('Generate with AI'),
  description: new TranslatableMarkup('Get ideas and text completion assistance from AI.'),
  module_dependencies: [],
)]
final class Completion extends AiCKEditorPluginBase {

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

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $options = $this->aiProviderManager->getSimpleProviderModelOptions('chat', FALSE);
    $form['provider'] = [
      '#type' => 'select',
      '#title' => $this->t('AI provider'),
      '#options' => $options,
      "#empty_option" => $this->t('-- Default from AI module (chat) --'),
      '#default_value' => $this->configuration['provider'] ?? $this->aiProviderManager->getSimpleDefaultProviderOptions('chat'),
      '#description' => $this->t('Select which provider to use for this plugin. See the <a href=":link">Provider overview</a> for details about each provider.', [':link' => '/admin/config/ai/providers']),
    ];

    $prompts_config = $this->getConfigFactory()->get('ai_ckeditor.settings');
    $prompt_complete = $prompts_config->get('prompts.complete');
    $form['prompt'] = [
      '#type' => 'ai_prompt',
      '#title' => $this->t('Completion pre prompt'),
      '#prompt_types' => ['ai_ckeditor_complete'],
      '#parents' => [
        'editor',
        'settings',
        'plugins',
        'ai_ckeditor_ai',
        'plugins',
        'ai_ckeditor_completion',
        'prompt',
      ],
      '#default_value' => $prompt_complete ?? '',
      '#description' => $this->t('This prompt will be prepended before the user prompt. This field may be left empty too.'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
    $this->configuration['provider'] = $form_state->getValue('provider');
    $newPrompt = $form_state->getValue('prompt');
    // @todo if no prompt is selected, this returns an array instead of an
    // empty string. Figure out why.
    if (is_array($newPrompt)) {
      $newPrompt = '';
    }
    $prompts_config = $this->getConfigFactory()->getEditable('ai_ckeditor.settings');
    $prompts_config->set('prompts.complete', $newPrompt)->save();
  }

  /**
   * {@inheritdoc}
   */
  protected function needsSelectedText(): bool {
    return FALSE;
  }

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

    $form['text_to_submit'] = [
      '#type' => 'textarea',
      '#title' => $this->t('What would you like to ask or get ideas for?'),
      '#default_value' => '',
      '#required' => TRUE,
      // Ensure this comes before the generate button.
      '#weight' => 5,
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function ajaxGenerate(array &$form, FormStateInterface $form_state): AjaxResponse {
    $response = new AjaxResponse();
    $values = $form_state->getValues();
    $prompts_config = $this->getConfigFactory()->get('ai_ckeditor.settings');
    $promptId = $prompts_config->get('prompts.complete');
    if (!empty($promptId)) {
      $promptText = $this->getConfigFactory()->get('ai.ai_prompt.' . $promptId)?->get('prompt') ?? '';
      $promptText .= PHP_EOL . $values['plugin_config']['text_to_submit'];
    }
    else {
      $promptText = $values['plugin_config']['text_to_submit'];
    }
    assert(is_array($this->pluginDefinition));
    $response->addCommand(new AiRequestCommand($promptText, $values["editor_id"], $this->pluginDefinition['id'], 'ai-ckeditor-response'));

    return $response;
  }

}
