<?php

declare(strict_types=1);

namespace Drupal\Tests\simple_interactive_maps\Unit\Attribute;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\simple_interactive_maps\Attribute\MapDefinition;
use Drupal\Tests\UnitTestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;

/**
 * Tests that the MapDefinition attribute produces the expected definition.
 */
#[Group('simple_interactive_maps')]
#[CoversClass(MapDefinition::class)]
final class MapDefinitionAttributeTest extends UnitTestCase {

  /**
   * Tests that the attribute produces the definition keys code reads by key.
   *
   * The attribute must produce the same definition keys the old annotation
   * class produced, since MapDefinitionPluginManager/InteractiveMapForm read
   * these by array key (e.g. $definition['map_category']).
   */
  public function testDefinitionShape(): void {
    $reflection = new \ReflectionClass(MapDefinitionAttributeFixture::class);
    $attributes = $reflection->getAttributes();
    $this->assertCount(1, $attributes);

    /** @var \Drupal\simple_interactive_maps\Attribute\MapDefinition $instance */
    $instance = $attributes[0]->newInstance();
    $instance->setClass(MapDefinitionAttributeFixture::class);
    $definition = $instance->get();

    $this->assertSame('test_map_definition', $definition['id']);
    $this->assertSame('Test Map', $definition['label']->getUntranslatedString());
    $this->assertSame('A test map.', $definition['description']->getUntranslatedString());
    $this->assertTrue($definition['uses_default_tooltip']);
    $this->assertSame('@label', $definition['default_tooltip']);
    $this->assertSame('Test Category', $definition['map_category']);
  }

  /**
   * Tests that optional fields default correctly when omitted.
   *
   * Regression guard for the generated map plugins (e.g. UnitedStates) that
   * omit uses_default_tooltip/default_tooltip/map_category and rely on
   * defaults.
   */
  public function testOptionalFieldsDefaultCorrectly(): void {
    $reflection = new \ReflectionClass(MapDefinitionAttributeMinimalFixture::class);
    $instance = $reflection->getAttributes()[0]->newInstance();
    $instance->setClass(MapDefinitionAttributeMinimalFixture::class);
    $definition = $instance->get();

    $this->assertFalse($definition['uses_default_tooltip']);
    $this->assertSame('', $definition['default_tooltip']);
    $this->assertSame('', $definition['map_category']);
  }

}

/**
 * Fixture class carrying a full MapDefinition attribute, for reflection.
 */
#[MapDefinition(
  id: 'test_map_definition',
  label: new TranslatableMarkup('Test Map'),
  description: new TranslatableMarkup('A test map.'),
  uses_default_tooltip: TRUE,
  default_tooltip: '@label',
  map_category: 'Test Category',
)]
class MapDefinitionAttributeFixture {}

/**
 * Fixture class with only the required MapDefinition attribute fields.
 */
#[MapDefinition(
  id: 'test_map_definition_minimal',
  label: new TranslatableMarkup('Minimal Test Map'),
  description: new TranslatableMarkup('A minimal test map.'),
)]
class MapDefinitionAttributeMinimalFixture {}
