<?php

declare(strict_types=1);

namespace Drupal\migrate_leshed\Plugin\migrate\process;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\Attribute\MigrateProcess;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Finds or creates 'partenaire' nodes from a comma-separated list of names.
 *
 * Input: a string such as "Port Autonome de Rouen, Labelle 69". Names are
 * split on commas and trimmed. Empty values and placeholders ("/") are
 * skipped. An existing node with the same title is reused, otherwise it is
 * created. Returns an array of node IDs.
 */
#[MigrateProcess(id: 'partenaire_generate', handle_multiples: TRUE)]
final class PartenaireGenerate extends ProcessPluginBase implements ContainerFactoryPluginInterface {

  /**
   * Placeholder values that must not create a partenaire node.
   */
  private const IGNORED_VALUES = ['/', '?', '-'];

  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    private readonly EntityTypeManagerInterface $entityTypeManager,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self {
    return new self(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property): array {
    if (!is_string($value) || trim($value) === '') {
      return [];
    }

    $names = array_filter(array_map('trim', explode(',', $value)));

    $nids = [];
    foreach ($names as $name) {
      if (in_array($name, self::IGNORED_VALUES, TRUE)) {
        continue;
      }
      $nids[] = $this->getOrCreatePartenaire($name);
    }

    return $nids;
  }

  /**
   * Returns the nid of the matching partenaire node, creating it if needed.
   */
  private function getOrCreatePartenaire(string $title): int {
    $storage = $this->entityTypeManager->getStorage('node');

    $ids = $storage->getQuery()
      ->condition('type', 'partenaire')
      ->condition('title', $title)
      ->accessCheck(FALSE)
      ->range(0, 1)
      ->execute();
    if ($ids) {
      return (int) reset($ids);
    }

    $node = $storage->create([
      'type' => 'partenaire',
      'title' => $title,
      'status' => 1,
      'uid' => $this->configuration['author_uid'] ?? 3,
    ]);
    $node->save();

    return (int) $node->id();
  }

}
