<?php

declare(strict_types=1);

namespace Drupal\Tests\ai_content_suggestions\FunctionalJavascript;

use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\ai\FunctionalJavascriptTests\BaseClassFunctionalJavascriptTests;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
 * Tests the Summarise plugin form interaction on the node add page.
 *
 * @group ai_content_suggestions
 */
#[RunTestsInSeparateProcesses]
class SummarisePluginTest extends BaseClassFunctionalJavascriptTests {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'node',
    'text',
    'filter',
    'field',
    'user',
    'file',
    'ai',
    'ai_test',
    'ai_content_suggestions',
  ];

  /**
   * {@inheritdoc}
   */
  protected string $screenshotModuleName = 'ai_content_suggestions';

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    // Configure the EchoProvider as the default chat provider.
    $this->setDefaultProvider('chat', 'echoai', 'gpt-test');

    // Create the 'page' content type.
    $node_type = NodeType::create([
      'type' => 'page',
      'name' => 'Basic page',
    ]);
    $node_type->save();
    $field_storage = FieldStorageConfig::loadByName('node', 'body');
    if (!$field_storage) {
      // Add the body field storage and instance manually to avoid using
      // the deprecated node_add_body_field() function.
      $field_storage = FieldStorageConfig::create([
        'field_name' => 'body',
        'entity_type' => 'node',
        'type' => 'text_with_summary',
      ]);
      $field_storage->save();
    }

    FieldConfig::create([
      'field_storage' => $field_storage,
      'bundle' => 'page',
      'label' => 'Body',
      'settings' => [
        'display_summary' => TRUE,
        'allowed_formats' => [],
      ],
    ])->save();

    // Add the body field to the default node form display.
    \Drupal::service('entity_display.repository')
      ->getFormDisplay('node', 'page')
      ->setComponent('body', ['type' => 'text_textarea_with_summary'])
      ->save();

    // Enable the Summarise plugin with the EchoProvider model and restrict it
    // to the 'page' bundle.
    \Drupal::configFactory()
      ->getEditable('ai_content_suggestions.settings')
      ->set('plugins', ['summarise' => 'echoai__gpt-test'])
      ->set('entity_types', [
        'node' => [
          'mode' => 'enable',
          'bundles' => ['page'],
        ],
      ])
      ->save();

    // Create and log in a user with the required permissions.
    $account = $this->drupalCreateUser([
      'access content',
      'create page content',
      'access ai content suggestion tools',
    ]);
    $this->drupalLogin($account);
  }

  /**
   * Tests the Summarise plugin renders and responds correctly on the add form.
   */
  public function testSummarisePluginOnNodeAddForm(): void {
    $this->drupalGet('/node/add/page');
    $assertSession = $this->assertSession();
    $page = $this->getSession()->getPage();

    // Verify the Summarise text plugin label is present on the page.
    $assertSession->pageTextContains('Summarise text');

    // The Summarise details is placed in the 'advanced' vertical tabs group.
    // Wait for the tab menu link generated by Drupal's vertical-tabs JS and
    // click it to make the panel visible.
    $assertSession->waitForElement('css', '#edit-summarise');
    $page->find('css', '#edit-summarise')->click();

    // Wait for the Summarize button inside the panel to become visible.
    $assertSession->waitForElementVisible('css', '#edit-summarise-summarise-submit');

    // Click the Summarize button with the body field still empty.
    $page->pressButton('Summarize');
    $assertSession->assertWaitOnAjaxRequest();

    // The response should indicate there is no text to summarise.
    $assertSession->waitForText('no text');
    $responseElement = $page->find('css', '#response-summarise');
    $this->assertNotNull($responseElement, 'The #response-summarise element is present after the first click.');
    $this->assertStringContainsString('no text', $responseElement->getText());

    // Fill the body field with lorem ipsum content.
    $page->fillField('body[0][value]', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.');

    // Click the Summarize button again now that the body field has content.
    $page->pressButton('Summarize');
    $assertSession->assertWaitOnAjaxRequest();

    // The EchoProvider returns a response starting with 'Hello world!'. In no
    // streaming mode the full text is "Hello world! Input: … Config: []".
    $assertSession->waitForText('Hello world!');
    $responseElement = $page->find('css', '#response-summarise');
    $this->assertNotNull($responseElement, 'The #response-summarise element is present after the second click.');
    $this->assertStringContainsString('Hello world!', $responseElement->getText());
  }

}
