<?php

declare(strict_types=1);

namespace Drupal\Tests\flowdrop\Unit\DTO\ConfigEdit;

use Drupal\Tests\UnitTestCase;
use Drupal\flowdrop\DTO\ConfigEdit\ConfigEdit;
use Drupal\flowdrop\DTO\ConfigEdit\ConfigEditApiEndpoints;
use Drupal\flowdrop\DTO\ConfigEdit\DynamicSchemaEndpoint;
use Drupal\flowdrop\DTO\ConfigEdit\ExternalEditLink;
use Drupal\Tests\flowdrop\Unit\Traits\DtoContractTestTrait;

/**
 * Tests the ConfigEdit DTOs.
 *
 * @group flowdrop
 */
class ConfigEditTest extends UnitTestCase {

  use DtoContractTestTrait;

  /**
   * Tests ConfigEdit round-trip serialization.
   *
   * @covers \Drupal\flowdrop\DTO\ConfigEdit\ConfigEdit
   */
  public function testConfigEditRoundTrip(): void {
    $configEdit = new ConfigEdit(
      dynamicSchema: new DynamicSchemaEndpoint(
        url: "/api/schema",
        method: "POST",
        parameterMapping: ["id" => "metadata.id"],
        headers: ["X-Custom" => "value"],
        cacheSchema: FALSE,
        timeout: 5000,
      ),
      externalEditLink: new ExternalEditLink(
        url: "/admin/edit/{id}",
        label: "Edit Config",
        icon: "mdi:pencil",
        description: "Open admin form",
        parameterMapping: ["id" => "config.id"],
        openInNewTab: FALSE,
      ),
      api: new ConfigEditApiEndpoints(
        create: "/api/config",
        read: "/api/config/{id}",
        update: "/api/config/{id}",
        delete: "/api/config/{id}",
      ),
      preferDynamicSchema: FALSE,
      showRefreshButton: FALSE,
      loadingMessage: "Please wait...",
      errorMessage: "Error loading",
    );

    $this->assertRoundTripSerialization($configEdit);
  }

  /**
   * Tests ConfigEdit helper methods.
   *
   * @covers \Drupal\flowdrop\DTO\ConfigEdit\ConfigEdit
   */
  public function testConfigEditHelpers(): void {
    $empty = new ConfigEdit();
    $this->assertFalse($empty->hasDynamicSchema());
    $this->assertFalse($empty->hasExternalEditLink());
    $this->assertFalse($empty->hasApi());

    $full = new ConfigEdit(
      dynamicSchema: new DynamicSchemaEndpoint(url: "/api"),
      externalEditLink: new ExternalEditLink(url: "/edit"),
      api: new ConfigEditApiEndpoints(create: "/create"),
    );
    $this->assertTrue($full->hasDynamicSchema());
    $this->assertTrue($full->hasExternalEditLink());
    $this->assertTrue($full->hasApi());
  }

  /**
   * Tests DynamicSchemaEndpoint round-trip.
   *
   * @covers \Drupal\flowdrop\DTO\ConfigEdit\DynamicSchemaEndpoint
   */
  public function testDynamicSchemaEndpointRoundTrip(): void {
    $endpoint = new DynamicSchemaEndpoint(
      url: "/api/schema/{nodeTypeId}",
      method: "GET",
      parameterMapping: ["nodeTypeId" => "metadata.id"],
      headers: ["Authorization" => "Bearer token"],
      cacheSchema: TRUE,
      timeout: 10000,
    );
    $this->assertRoundTripSerialization($endpoint);
  }

  /**
   * Tests ExternalEditLink round-trip.
   *
   * @covers \Drupal\flowdrop\DTO\ConfigEdit\ExternalEditLink
   */
  public function testExternalEditLinkRoundTrip(): void {
    $link = new ExternalEditLink(
      url: "/admin/config/{id}",
      label: "Edit",
      icon: "mdi:cog",
      description: "Open editor",
      parameterMapping: ["id" => "config.entity_id"],
      openInNewTab: TRUE,
    );
    $this->assertRoundTripSerialization($link);
  }

  /**
   * Tests ConfigEditApiEndpoints round-trip.
   *
   * @covers \Drupal\flowdrop\DTO\ConfigEdit\ConfigEditApiEndpoints
   */
  public function testApiEndpointsRoundTrip(): void {
    $api = new ConfigEditApiEndpoints(
      create: "/api/create",
      read: "/api/read/{id}",
      update: "/api/update/{id}",
      delete: "/api/delete/{id}",
      custom: ["list" => "/api/list"],
    );
    $this->assertRoundTripSerialization($api);
  }

}
