<?php

namespace Drupal\dc_core\Plugin\QueueWorker;

use Drupal\Core\Annotation\QueueWorker;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\QueueWorkerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Custom Queue Worker.
*
* @QueueWorker(
*   id = "character_import",
*   title = @Translation("Character Import Queue"),
*   cron = {"time" = 60}
* )
*/
final class CharacterQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface {

 /**
  * The entity type manager.
  *
  * @var \Drupal\Core\Entity\EntityTypeManagerInterface
  */
  protected $entityTypeManager;

  /**
  * The database connection.
  *
  * @var \Drupal\Core\Database\Connection
  */
  protected $database;

  /**
   * Main constructor.
   *
   * @param array $configuration
   *   Configuration array.
   * @param mixed $plugin_id
   *   The plugin id.
   * @param mixed $plugin_definition
   *   The plugin definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Database\Connection $database
   *   The connection to the database.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    EntityTypeManagerInterface $entity_type_manager,
    Connection $database
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->entityTypeManager = $entity_type_manager;
    $this->database = $database;
  }

  /**
   * Used to grab functionality from the container.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The container.
   * @param array $configuration
   *   Configuration array.
   * @param mixed $plugin_id
   *   The plugin id.
   * @param mixed $plugin_definition
   *   The plugin definition.
   * @return static
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition
  ) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('database'),
    );
  }

  /**
   * Processes an item in the queue.
   *
   * @param mixed $data
   *   The queue item data.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   * @throws \Exception
   */
  public function processItem($data) {
    $client = \Drupal::httpClient();
    $url = "https://dchadwick.ddev.site/api/character-list";
    $character_api_data = $client->request('GET', $url, ['verify' => false])->getBody()->getContents();
    $json_data = json_decode($character_api_data, TRUE);
    $target_data = $json_data[$data->id];

    if ($data->operation == "CREATE") {
      $node_values = [
        'type' => 'character',
        'title' => $target_data['name'],
        'field_species' => $target_data['species'],
        'field_character_height' => $target_data['height'],
        'field_hair' => $target_data['hair'],
        'field_eyes' => $target_data['eyes'],
        'field_birth' => $target_data['birth'],
        'field_death' => $target_data['death'],
        'field_character_title' => $target_data['title'],
        'field_occupation' => $target_data['occupation'],
        'field_affiliation' => $target_data['affiliation'],
        'field_bio' => ['value' => $target_data['bio']],
        'field_character_image' => $target_data['image_url'],
        'field_character_id' => $data->id,
        'field_youtube_url' => $target_data['youtube_url'],
      ];
      $node = \Drupal::entityTypeManager()->getStorage('node')->create($node_values)->save();
      \Drupal::logger('dc_core')->notice("Created character " . $target_data['name']);
    }
    elseif ($data->operation == "UPDATE") {
      // load the entity by character id.
      $existing_entity = $this->entityTypeManager->getStorage('node')->loadByProperties([
        'type' => 'character',
        'field_character_id' => $data->id,
      ]);
      $existing_entity = reset($existing_entity);
      $node_values = [
        'title' => $target_data['name'],
        'field_species' => $target_data['species'],
        'field_character_height' => $target_data['height'],
        'field_hair' => $target_data['hair'],
        'field_eyes' => $target_data['eyes'],
        'field_birth' => $target_data['birth'],
        'field_death' => $target_data['death'],
        'field_character_title' => $target_data['title'],
        'field_occupation' => $target_data['occupation'],
        'field_affiliation' => $target_data['affiliation'],
        'field_bio' => ['value' => $target_data['bio']],
        'field_character_image' => $target_data['image_url'],
        'field_character_id' => $data->id,
        'field_youtube_url' => $target_data['youtube_url'],
      ];
      foreach ($node_values as $field_name => $value) {
        $existing_entity->set($field_name, $value);
      }
      $existing_entity->save();
      \Drupal::logger('dc_core')->notice("Updated character " . $target_data['name']);
    }

  }

}
