<?php

declare(strict_types=1);

namespace Drupal\Tests\simple_interactive_maps\Kernel;

use Drupal\KernelTests\KernelTestBase;
use Drupal\simple_interactive_maps\Entity\InteractiveMap;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
 * CRUD coverage for the interactive_map config entity type.
 *
 * Also a regression guard for the @ConfigEntityType annotation ->
 * #[ConfigEntityType] attribute migration and the config schema fixes that
 * were needed alongside it (regions/groups were declared as the wrong
 * schema type and would fail strict schema validation on save).
 */
#[Group('simple_interactive_maps')]
#[CoversClass(InteractiveMap::class)]
#[RunTestsInSeparateProcesses]
final class InteractiveMapEntityTest extends KernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'system',
    'field_group',
    'simple_interactive_maps',
  ];

  /**
   * Tests that the interactive_map entity type is discoverable.
   */
  public function testEntityTypeIsDiscoverable(): void {
    $entityTypeManager = $this->container->get('entity_type.manager');
    $this->assertTrue($entityTypeManager->hasDefinition('interactive_map'));

    $definition = $entityTypeManager->getDefinition('interactive_map');
    $this->assertSame('simple_interactive_maps.interactive_map', $definition->getConfigPrefix());
    $this->assertSame('administer interactive_map', $definition->getAdminPermission());
  }

  /**
   * Tests that a map survives a save and load round trip.
   */
  public function testSaveAndLoadRoundTrip(): void {
    $map = InteractiveMap::create([
      'id' => 'test_map',
      'label' => 'Test Map',
      'base_map' => 'us_states_territories',
      'regions' => [
        'AL' => [
          'id' => 'AL',
          'label' => 'Alabama',
          'hidden' => 0,
          'group' => '',
          'fill_color' => '#4ba0a6',
          'hover_color' => '#076369',
          'stroke_color' => '#e6e6e6',
          'text_color' => '#000000',
          'tooltip' => ['value' => '', 'format' => 'plain_text'],
          'action' => ['plugin_id' => 'none', 'plugin_configuration' => []],
        ],
      ],
      'groups' => [
        'group_a' => [
          'label' => 'Group A',
          'override_colors' => TRUE,
          'fill_color' => '#aaaaaa',
          'hover_color' => '#bbbbbb',
          'stroke_color' => '#cccccc',
          'text_color' => '#dddddd',
          'override_tooltip' => FALSE,
          'override_action' => FALSE,
        ],
      ],
    ]);
    $map->save();

    /** @var \Drupal\simple_interactive_maps\Entity\InteractiveMap $loaded */
    $loaded = $this->container->get('entity_type.manager')
      ->getStorage('interactive_map')
      ->loadUnchanged('test_map');

    $this->assertSame('Test Map', $loaded->label());
    $this->assertSame('us_states_territories', $loaded->get('base_map'));
    $this->assertArrayHasKey('AL', $loaded->getRegions());
    $this->assertArrayHasKey('group_a', $loaded->getGroups());
    $this->assertSame('[interactive_map map=test_map]', $loaded->getEmbedCode());
  }

  /**
   * Tests that deleting a group persists after save.
   */
  public function testDeleteGroupPersists(): void {
    $map = InteractiveMap::create([
      'id' => 'test_map',
      'label' => 'Test Map',
      'base_map' => 'us_states_territories',
      'groups' => [
        'group_a' => ['label' => 'Group A'],
        'group_b' => ['label' => 'Group B'],
      ],
    ]);
    $map->save();

    $map->deleteGroup('group_a');
    $map->save();

    /** @var \Drupal\simple_interactive_maps\Entity\InteractiveMap $loaded */
    $loaded = $this->container->get('entity_type.manager')
      ->getStorage('interactive_map')
      ->loadUnchanged('test_map');

    $this->assertArrayNotHasKey('group_a', $loaded->getGroups());
    $this->assertArrayHasKey('group_b', $loaded->getGroups());
  }

}
