<?php

declare(strict_types=1);

namespace Drupal\Tests\conductor\Functional;

use Drupal\Component\Serialization\Json;
use Drupal\conductor\Repository\DraftRepository;
use Drupal\Core\Session\AccountInterface;
use PHPUnit\Framework\Attributes\Group;
use Symfony\Component\HttpFoundation\Response;

/**
 * Test for the settings API endpoint.
 */
#[Group("conductor")]
final class ConductorSettingsApiControllerTest extends ConductorBrowserTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'conductor',
    'conductor_test',
    'key',
    'canvas',
  ];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  public function setUp(): void {
    parent::setUp();
    $this->generateKey();
  }

  public function testAccessControl(): void {
    // Anonymous users are denied.
    $this->drupalGet('/conductor/api/settings');
    $this->assertSession()->statusCodeEquals(Response::HTTP_FORBIDDEN);

    // Users without the permission are denied.
    $no_permission_user = $this->createUser(['access content']);
    \assert($no_permission_user instanceof AccountInterface);
    $this->drupalLogin($no_permission_user);
    $this->drupalGet('/conductor/api/settings');
    $this->assertSession()->statusCodeEquals(Response::HTTP_FORBIDDEN);
  }

  public function testSettingsWithoutCredentials(): void {
    // Remove the key config so credentials are missing.
    \Drupal::configFactory()->getEditable('conductor.settings')->clear('key_id')->save();

    $user = $this->createUser(['use conductor']);
    \assert($user instanceof AccountInterface);
    $this->drupalLogin($user);

    $this->drupalGet('/conductor/api/settings');
    $this->assertSession()->statusCodeEquals(Response::HTTP_UNAUTHORIZED);
  }

  public function testSettingsResponse(): void {
    $user = $this->createUser(['use conductor']);
    \assert($user instanceof AccountInterface);
    $this->drupalLogin($user);

    $this->drupalGet('/conductor/api/settings');
    $this->assertSession()->statusCodeEquals(Response::HTTP_OK);

    $data = Json::decode($this->getSession()->getPage()->getContent());
    $this->assertSame('12345', $data['accountId']);
    $this->assertSame(DraftRepository::DEFAULT_MAX_DRAFT, $data['maxDrafts']);
    $this->assertSame(0, $data['usedDrafts']);
  }

  public function testSettingsWithValidCredentials(): void {
    $user = $this->createUser(['use conductor']);
    \assert($user instanceof AccountInterface);
    $this->drupalLogin($user);

    $this->drupalGet('/conductor/api/settings');
    $this->assertSession()->statusCodeEquals(Response::HTTP_OK);

    $data = Json::decode($this->getSession()->getPage()->getContent());
    $this->assertSame('12345', $data['accountId']);
  }

  public function testSettingsWithInvalidCredentials(): void {
    $this->generateInvalidKey();

    $user = $this->createUser(['use conductor']);
    \assert($user instanceof AccountInterface);
    $this->drupalLogin($user);

    $this->drupalGet('/conductor/api/settings');
    $this->assertSession()->statusCodeEquals(Response::HTTP_UNAUTHORIZED);
  }

  public function testUsedDraftsCount(): void {
    // Create a canvas page and link a draft to it.
    $page = $this->generateBasicCanvasPage();
    $this->container->get(DraftRepository::class)
      ->createDraft($page->getEntityType()->id(), (int) $page->id(), 'draft-abc-123');

    $user = $this->createUser(['use conductor']);
    \assert($user instanceof AccountInterface);
    $this->drupalLogin($user);

    $this->drupalGet('/conductor/api/settings');
    $this->assertSession()->statusCodeEquals(Response::HTTP_OK);

    $data = Json::decode($this->getSession()->getPage()->getContent());
    $this->assertSame(1, $data['usedDrafts']);
  }

}
