<?php

declare(strict_types=1);

namespace Drupal\Tests\simple_interactive_maps\Unit\Attribute;

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

/**
 * Tests that the MapAction attribute produces the expected plugin definition.
 */
#[Group('simple_interactive_maps')]
#[CoversClass(MapAction::class)]
final class MapActionAttributeTest 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 MapActionPluginBase reads these by array key
   * (e.g. $this->pluginDefinition['label']).
   */
  public function testDefinitionShape(): void {
    $reflection = new \ReflectionClass(MapActionAttributeFixture::class);
    $attributes = $reflection->getAttributes();
    $this->assertCount(1, $attributes);

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

    $this->assertSame('test_map_action', $definition['id']);
    $this->assertInstanceOf(TranslatableMarkup::class, $definition['label']);
    $this->assertSame('Test Action', $definition['label']->getUntranslatedString());
    $this->assertInstanceOf(TranslatableMarkup::class, $definition['description']);
    $this->assertSame('A test action.', $definition['description']->getUntranslatedString());
    $this->assertTrue($definition['is_system']);
    $this->assertSame(-100, $definition['weight']);
    $this->assertSame(MapActionAttributeFixture::class, $definition['class']);
  }

  /**
   * Tests that optional attribute fields fall back to their defaults.
   */
  public function testDefaultsForOptionalFields(): void {
    $attribute = new MapAction(
      id: 'minimal_action',
      label: new TranslatableMarkup('Minimal'),
      description: new TranslatableMarkup('Minimal description.'),
    );

    $this->assertFalse($attribute->is_system);
    $this->assertSame(0, $attribute->weight);
  }

}

/**
 * Fixture class carrying a MapAction attribute for reflection-based testing.
 */
#[MapAction(
  id: 'test_map_action',
  label: new TranslatableMarkup('Test Action'),
  description: new TranslatableMarkup('A test action.'),
  is_system: TRUE,
  weight: -100,
)]
class MapActionAttributeFixture {}
