<?php

namespace Drupal\Tests\acquia_dam\Kernel;

use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\Request;

/**
 * Test config form access.
 *
 * @group acquia_dam_kernel
 */
class AcquiaDamConfigurationFormTest extends AcquiaDamKernelTestBase {

  /**
   * Tests config form access.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function testFormAccess(): void {
    // Set current user as admin.
    $this->drupalSetUpCurrentUser([], [], TRUE);

    $request = $this->getMockedRequest("/admin/config/acquia-dam", 'GET');
    $response = $this->processRequest($request);
    self::assertEquals(200, $response->getStatusCode());

    // Set current user as authorised with necessary permission.
    $this->drupalSetUpCurrentUser([], ['administer site configuration']);
    $request = $this->getMockedRequest("/admin/config/acquia-dam", 'GET');
    $response = $this->processRequest($request);
    self::assertEquals(200, $response->getStatusCode());

    // Set current user as authorised without necessary permission.
    $this->drupalSetUpCurrentUser();
    $request = $this->getMockedRequest("/admin/config/acquia-dam", 'GET');
    $response = $this->processRequest($request);
    self::assertEquals(403, $response->getStatusCode());
  }

  /**
   * Tests that the domain field in the form is disabled and not editable.
   */
  public function testFormDomainField(): void {
    $this->drupalSetUpCurrentUser([], [], TRUE);

    $request = $this->getMockedRequest("/admin/config/acquia-dam", 'GET');
    $response = $this->processRequest($request);
    self::assertEquals(200, $response->getStatusCode());
    self::assertStringContainsString('Site is authenticated with Acquia DAM.', (string) $response->getContent());
    // Assert that the domain field is not editable and disabled.
    self::assertStringContainsString('<input data-drupal-selector="edit-domain" aria-describedby="edit-domain--description" disabled="disabled"', (string) $response->getContent());
  }

  /**
   * Tests disconnecting the site and changing the domain.
   *
   * @throws \Exception
   */
  public function testFormDisconnectNewDomain(): void {
    $this->drupalSetUpCurrentUser([], [], TRUE);

    // Step 1: Disconnect the site from Acquia DAM.
    $url = Url::fromRoute('acquia_dam.disconnect_site');
    $request = $this->getMockedRequest($url->toString(), 'GET');
    $response = $this->processRequest($request);
    self::assertEquals(200, $response->getStatusCode());
    self::assertStringContainsString('Are you sure you want to disconnect this site from Acquia DAM?', (string) $response->getContent());
    $button = $this->cssSelect('input[type="submit"]');
    $attributes = [
      'id' => 'edit-submit',
      'value' => 'Disconnect',
    ];
    $response = $this->doFormSubmit(
      $url->toString(),
      [],
      'Disconnect'
    );
    self::assertEquals(303, $response->getStatusCode());

    // Visit configuration page to verify the success message and disconnection
    $request = $this->getMockedRequest("/admin/config/acquia-dam", 'GET');
    $response = $this->processRequest($request);
    self::assertEquals(200, $response->getStatusCode());
    self::assertStringContainsString('Site successfully disconnected from Acquia DAM.', (string) $response->getContent());

    // Step 2: Change the domain to "https://example.dam.acquia.com".
    $data = [
      'auth_type' => 'authorization_code',
      'domain' => 'https://example.dam.acquia.com',
      'op' => 'Authenticate Site',
    ];

    // Submit the form with the new domain.
    $response = $this->doFormSubmit(
      '/admin/config/acquia-dam',
      $data
    );
    // This should result in a 302 redirect to the authentication URL.
    self::assertEquals(302, $response->getStatusCode());

    // Step 3: Verify the domain is updated in the configuration.
    $config = $this->container->get('config.factory')->get('acquia_dam.settings');
    self::assertEquals('example.dam.acquia.com', $config->get('domain'));

    // Step 4: Visit the configuration page and verify the new domain is displayed.
    $request = $this->getMockedRequest("/admin/config/acquia-dam", 'GET');
    $response = $this->processRequest($request);
    self::assertEquals(200, $response->getStatusCode());

    // Check for the domain field containing the new domain value.
    self::assertStringContainsString('example.dam.acquia.com', (string) $response->getContent());
  }

}
