<?php

declare(strict_types=1);

namespace Drupal\Tests\conductor\Functional;

use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\Tests\ApiRequestTrait;
use PHPUnit\Framework\Attributes\Group;
use Symfony\Component\HttpFoundation\Response;

/**
 * Browser tests for conductor module.
 */
#[Group("conductor")]
final class ConductorHttpApiBrowserTest extends ConductorBrowserTestBase {

  use ApiRequestTrait;

  /**
   * {@inheritdoc}
   *
   * Enable only the module under test for now.
   */
  protected static $modules = [
    'conductor',
    'conductor_test',
    'key',
  ];

  /**
   * {@inheritdoc}
   *
   * Use a minimal core theme to avoid unrelated dependencies.
   */
  protected $defaultTheme = 'stark';

  /**
   * Request the simplest GET request to the Conductor API using the HTTP client.
   */
  public function testSimpleGetRequests(): void {
    $this->generateKey();
    // Anonymous user.
    $this->drupalGet('/conductor/proxy/v3/accounts');
    $this->assertSession()->statusCodeEquals(403);
    $this->assertSession()->responseContains('You are not authorized to access this page');

    // Logged in user with permissions.
    $account = $this->drupalCreateUser(['use conductor', 'access content']);
    assert($account instanceof AccountInterface);
    $this->drupalLogin($account);
    $this->assertFalse(\Drupal::currentUser()->isAnonymous(), 'User should not be anonymous after login');
    $this->assertTrue($this->drupalUserIsLoggedIn($account));
    $this->drupalGet('/conductor/proxy/v3/accounts');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->responseContains('https://api.conductor.com/v3/accounts/12345/web-properties');

    // Hacky request to validate the query string is passed to the request.
    $this->drupalGet('/conductor/proxy/v3/accounts', [
      'query' => ['requestUuid' => '1234-asdf-5678-qwer'],
    ]);
    $this->assertSession()->responseContains('Successfully forwarded the query string to the request');

    // The following aren't really testing that the proxy returns the appropriate
    // response given an endpoint, since the endpoint and responses are hardcoded
    // in conductor_test. Instead they're testing whether the response is passed
    // through as-is.

    // non-existent endpoint.
    $this->drupalGet('/conductor/proxy/v3/does-not-exist');
    $this->assertSession()->statusCodeEquals(404);
    $this->assertSession()->responseContains('Not found');

    // Internal server error.
    $this->drupalGet('/conductor/proxy/v3/accounts-500');
    $this->assertSession()->statusCodeEquals(500);
    $this->assertSession()->responseContains('{}');

    // Invalid json header.
    $this->drupalGet('/conductor/proxy/v3/wrong-json-header');
    $this->assertSession()->statusCodeEquals(200);
    // But in the content, there is the json.
    $this->assertSession()->responseContains('accountId');
  }

  public function testRequestsWithoutCredentials(): void {
    // Anonymous user.
    $this->drupalGet('/conductor/proxy/v3/accounts');
    $this->assertSession()->statusCodeEquals(403);
    $this->assertSession()->responseContains('You are not authorized to access this page');

    // Logged in user with permissions.
    $account = $this->drupalCreateUser(['use conductor', 'access content']);
    assert($account instanceof AccountInterface);
    $this->drupalLogin($account);
    $this->assertFalse(\Drupal::currentUser()->isAnonymous(), 'User should not be anonymous after login');
    $this->assertTrue($this->drupalUserIsLoggedIn($account));
    $this->drupalGet('/conductor/proxy/v3/accounts');
    $this->assertSession()->statusCodeEquals(Response::HTTP_UNAUTHORIZED);
    $this->assertSession()->responseContains('Key ID not found.');
  }

  public function testGetConductorDrafts(): void {
    $this->generateKey();
    // Logged in user with permissions.
    $account = $this->drupalCreateUser(['use conductor', 'access content']);
    assert($account instanceof AccountInterface);
    $this->drupalLogin($account);
    $this->assertTrue($this->drupalUserIsLoggedIn($account));
    $response = $this->drupalGet('/conductor/proxy/v3/accounts/12345/drafts/writing-assistant');
    $drafts = json_decode($response, TRUE);
    $this->assertCount(3, $drafts);
    $this->assertSame(12345, $drafts[0]['accountId']);
    $this->assertSame('APPROVED', $drafts[0]['status']);
  }

  public function testDeleteConductorDraft(): void {
    $this->generateKey();
    $account = $this->drupalCreateUser(['use conductor', 'access content']);
    assert($account instanceof AccountInterface);
    $this->drupalLogin($account);
    $this->assertTrue($this->drupalUserIsLoggedIn($account));
    $url = Url::fromUri('base:/conductor/proxy/v3/accounts/12345/drafts/033196cc-8705-40b2-a570-a3705f529f11/writing-assistant');
    $response = $this->makeApiRequest('DELETE', $url, []);
    $this->assertSame('true', trim((string) $response->getBody()));
  }

}
