<?php

namespace Drupal\Tests\gutenberg\FunctionalJavascript;

use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
 * Tests the reusable blocks feature.
 */
#[RunTestsInSeparateProcesses]
class ReusableBlocksTest extends GutenbergWebdriverTestBase {

  /**
   * Tests creating and using reusable blocks in Gutenberg.
   */
  public function testCreatingAndUsingReusableBlocks() {
    self::assertCount(0, $this->getReusableBlocks());

    // Insert a paragraph block via the inserter.
    $insert_block_button = '.editor-document-tools__inserter-toggle';
    $this->assertSession()->waitForElement('css', $insert_block_button, 5000);
    $page = $this->getSession()->getPage();
    $page->find('css', $insert_block_button)->click();
    $paragraph_selector = '.editor-block-list-item-paragraph\/paragraph';
    $this->assertSession()->waitForElement('css', $paragraph_selector, 5000);
    $this->getSession()->evaluateScript("document.querySelector('[class*=\"editor-block-list-item-paragraph\"]').click()");

    // Close the block inserter.
    $page->find('css', $insert_block_button)->click();

    // Wait for the paragraph block to appear, then type content into it.
    // The contenteditable may be in an iframe (editor-canvas) or directly
    // in the page depending on block API version.
    $this->getSession()->evaluateScript(<<<JS
(function() {
  var el = document.querySelector('[contenteditable="true"]');
  if (!el) {
    var iframe = document.querySelector('iframe[name="editor-canvas"]');
    if (iframe) el = iframe.contentDocument.querySelector('[contenteditable="true"]');
  }
  if (el) {
    el.focus();
    el.textContent = 'test content';
    el.dispatchEvent(new Event('input', { bubbles: true }));
  }
})();
JS);

    // Click on the paragraph block to select it.
    $this->getSession()->evaluateScript(<<<JS
(function() {
  var el = document.querySelector('[contenteditable="true"]');
  if (!el) {
    var iframe = document.querySelector('iframe[name="editor-canvas"]');
    if (iframe) el = iframe.contentDocument.querySelector('[contenteditable="true"]');
  }
  if (el) el.click();
})();
JS);

    // Click the block settings menu (three dots).
    $settings_menu = '.block-editor-block-settings-menu';
    $this->assertSession()->waitForElement('css', $settings_menu, 5000);
    $page->find('css', $settings_menu)->click();

    // Find and click "Create pattern" in the context menu.
    $this->assertSession()->waitForElement('css', '.components-menu-group', 3000);
    $all_items = $page->findAll('css', '.components-menu-group button span');
    foreach ($all_items as $item) {
      $text = $item->getText();
      if (strpos($text, 'Create pattern') === FALSE) {
        continue;
      }
      $item->click();
      break;
    }

    // Fill in the pattern name and save.
    $modal_selector = '.patterns-menu-items__convert-modal';
    $this->assertSession()->waitForElement('css', $modal_selector, 5000);
    $page->find('css', $modal_selector . ' .components-text-control__input')->setValue('test reusable block');
    $page->find('css', $modal_selector . ' .components-button.is-primary')->click();

    // Wait for the save to complete.
    $this->assertSession()->assertWaitOnAjaxRequest();
    self::assertCount(1, $this->getReusableBlocks());
  }

}
