<?php

declare(strict_types=1);

namespace Drupal\node_revision_delete_protection;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Session\AccountProxyInterface;

/**
 * Service for managing revision protection.
 */
class RevisionProtectionManager {

  /**
   * Constructs a RevisionManagerService object.
   *
   * @param \Drupal\Core\Database\Connection $connection
   *   The database connection.
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   *   The current user service.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   */
  public function __construct(
    protected Connection $connection,
    protected AccountProxyInterface $currentUser,
    protected TimeInterface $time,
  ) {}

  /**
   * Check if a revision is protected.
   *
   * @param string $entity_type
   *   The entity type.
   * @param int $revision_id
   *   The revision ID.
   *
   * @return bool
   *   TRUE if protected, FALSE otherwise.
   */
  public function isProtected(string $entity_type, int $revision_id): bool {
    $query = $this->connection->select('revision_protection', 'rp')
      ->fields('rp', ['revision_id'])
      ->condition('entity_type', $entity_type)
      ->condition('revision_id', $revision_id);
    $result = $query->execute()->fetchField();
    return !empty($result);
  }

  /**
   * Protect a revision from cleanup.
   *
   * @param string $entity_type
   *   The entity type.
   * @param int $entity_id
   *   The entity ID.
   * @param int $revision_id
   *   The revision ID.
   * @param string|null $reason
   *   Optional reason for protecting.
   */
  public function protect(string $entity_type, int $entity_id, int $revision_id, ?string $reason = NULL): void {
    $this->connection->merge('revision_protection')
      ->keys([
        'entity_type' => $entity_type,
        'entity_id' => $entity_id,
        'revision_id' => $revision_id,
      ])
      ->fields([
        'uid' => $this->currentUser->id(),
        'timestamp' => $this->time->getRequestTime(),
        'reason' => $reason,
      ])
      ->execute();
  }

  /**
   * Release revision protection.
   *
   * @param string $entity_type
   *   The entity type.
   * @param int $revision_id
   *   The revision ID.
   */
  public function release(string $entity_type, int $revision_id): void {
    $this->connection->delete('revision_protection')
      ->condition('entity_type', $entity_type)
      ->condition('revision_id', $revision_id)
      ->execute();
  }

}
