<?php

declare(strict_types=1);

namespace Drupal\lms_xapi;

use Drupal\Core\Database\Connection;
use Drupal\Core\Database\StatementInterface;
use Drupal\lms_xapi\Event\ReferenceEvent;
use Symfony\Component\DependencyInjection\Attribute\AutowireCallable;

/**
 * LRS reference storage class.
 */
final class LRSReferenceStorage {

  public const TABLE = 'lms_xapi_lrs_references';

  /**
   * The constructor.
   */
  public function __construct(
    private readonly Connection $db,
    #[AutowireCallable(service: 'event_dispatcher', method: 'dispatch')]
    private \Closure $dispatchEvent,
  ) {}

  /**
   * Get registration UUID.
   */
  public function getStoredLrsUuid(string $lms_id): string {
    $statement = $this->db->select(self::TABLE)
      ->fields(self::TABLE, ['uuid'])
      ->condition('lms_id', $lms_id)
      ->execute();
    \assert($statement instanceof StatementInterface);
    $result = $statement->fetchField();
    return \is_string($result) ? $result : '';
  }

  /**
   * Create / update item.
   */
  public function saveLrsUuid(string $uuid, string $lms_id): void {
    $this->db->insert(self::TABLE)
      ->fields([
        'lms_id' => $lms_id,
        'uuid' => $uuid,
      ])
      ->execute();
  }

  /**
   * Delete item or all items with a given group ID.
   *
   * @param string $search
   *   The beginning string of LMS identifier.
   */
  public function deleteLrsReferences(string $search): void {
    if ($search === '') {
      throw new \InvalidArgumentException('Attempting to delete registrations without a search string.');
    }

    $statement = $this->db->select(self::TABLE, 'references')
      ->fields('references', ['uuid'])
      ->condition('lms_id', $search, 'LIKE')
      ->execute();

    \assert($statement instanceof StatementInterface);
    $registration_ids = $statement->fetchCol();
    if (\count($registration_ids) === 0) {
      return;
    }

    $event = new ReferenceEvent('delete', $registration_ids);
    ($this->dispatchEvent)($event, ReferenceEvent::NAME);
    if ($event->isPropagationStopped()) {
      return;
    }

    $statement = $this->db->delete(self::TABLE);
    $statement->condition('uuid', $registration_ids, 'IN');
    $statement->execute();
  }

}
