<?php

declare(strict_types=1);

namespace Drupal\Tests\simple_interactive_maps\Functional;

use Drupal\simple_interactive_maps\Entity\InteractiveMap;
use Drupal\Tests\BrowserTestBase;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
 * Regression guard for the FileSystemInterface::EXISTS_REPLACE migration.
 *
 * Covers the Drupal\Core\File\FileExists::Replace migration in
 * DataImportFormBase. Uploading a CSV with the same filename twice must
 * replace the stored file rather than erroring or silently creating
 * "name_0.csv" and using stale data.
 */
#[Group('simple_interactive_maps')]
#[RunTestsInSeparateProcesses]
final class RegionDataImportFormTest extends BrowserTestBase {

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

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

  /**
   * Writes the given rows to a CSV file in the system temp directory.
   */
  private function writeCsv(string $filename, array $rows): string {
    $path = sys_get_temp_dir() . '/' . $filename;
    $fh = fopen($path, 'w');
    foreach ($rows as $row) {
      fputcsv($fh, $row);
    }
    fclose($fh);
    return $path;
  }

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $account = $this->drupalCreateUser(['administer interactive_map']);
    $this->drupalLogin($account);
  }

  /**
   * Tests that a second CSV upload under the same name replaces the file.
   *
   * Also tests that the CSV upload replaces the map's regions.
   */
  public function testCsvUploadReplacesRegionsAndSecondUploadReplacesTheFile(): void {
    $map = InteractiveMap::create([
      'id' => 'test_map',
      'label' => 'Test Map',
      'base_map' => 'us_states_territories',
    ]);
    $map->save();

    $header = [
      'id', 'label', 'hidden', 'group', 'fill_color', 'hover_color',
      'stroke_color', 'text_color', 'tooltip_value', 'tooltip_format',
      'action_plugin_id', 'action_configuration',
    ];

    $csvPath = $this->writeCsv('regions.csv', [
      $header,
      [
        'AL', 'Alabama', '0', '', '#111111', '#222222', '#333333', '#444444',
        'First upload', 'plain_text', 'none', '{}',
      ],
    ]);

    $this->drupalGet('/admin/structure/interactive-map/test_map/tools/region-import');
    $this->assertSession()->statusCodeEquals(200);

    $page = $this->getSession()->getPage();
    $page->attachFileToField('files[import_regions_file]', $csvPath);
    $page->pressButton('Send');
    $this->assertSession()->pageTextContains('Region data has been imported.');

    /** @var \Drupal\simple_interactive_maps\Entity\InteractiveMap $loaded */
    $loaded = \Drupal::entityTypeManager()->getStorage('interactive_map')->loadUnchanged('test_map');
    \assert($loaded instanceof InteractiveMap);
    $this->assertSame('#111111', $loaded->getRegions()['AL']['fill_color']);

    // Upload a second CSV under the exact same filename with different data:
    // this must replace the stored file, not fail or leave stale content.
    $csvPath = $this->writeCsv('regions.csv', [
      $header,
      [
        'AL', 'Alabama', '0', '', '#999999', '#888888', '#777777', '#666666',
        'Second upload', 'plain_text', 'none', '{}',
      ],
    ]);

    $this->drupalGet('/admin/structure/interactive-map/test_map/tools/region-import');
    $page = $this->getSession()->getPage();
    $page->attachFileToField('files[import_regions_file]', $csvPath);
    $page->pressButton('Send');
    $this->assertSession()->pageTextContains('Region data has been imported.');

    $loaded = \Drupal::entityTypeManager()->getStorage('interactive_map')->loadUnchanged('test_map');
    \assert($loaded instanceof InteractiveMap);
    $this->assertSame('#999999', $loaded->getRegions()['AL']['fill_color']);
  }

}
