<?php

declare(strict_types=1);

namespace Drupal\native_observability\Service;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Extension\ModuleHandlerInterface;

/**
 * Cleans up retained aggregated metrics records.
 */
final class MetricsCleanupHandler implements ObservabilityCleanupHandlerInterface {

  /**
   * Constructs the metrics cleanup handler.
   */
  public function __construct(
    private readonly Connection $database,
    private readonly TimeInterface $time,
    private readonly ModuleHandlerInterface $moduleHandler,
  ) {
  }

  /**
   * {@inheritdoc}
   */
  public function id(): string {
    return 'metrics';
  }

  /**
   * {@inheritdoc}
   */
  public function isAvailable(): bool {
    return $this->moduleHandler->moduleExists('native_observability_metrics')
      && $this->database->schema()->tableExists('native_observability_route_metric');
  }

  /**
   * {@inheritdoc}
   */
  public function cleanup(array $settings): int {
    if (!$this->isAvailable()) {
      return 0;
    }

    $days = max(1, (int) ($settings['metrics_retention_days'] ?? 7));
    $threshold = $this->time->getCurrentTime() - ($days * 86400);
    $limit = max(1, (int) ($settings['cleanup_batch_limit'] ?? 5000));

    $ids = $this->database->select('native_observability_route_metric', 'm')
      ->fields('m', ['id'])
      ->condition('created_at', $threshold, '<')
      ->range(0, $limit)
      ->execute()
      ->fetchCol();

    if (!$ids) {
      return 0;
    }

    return (int) $this->database->delete('native_observability_route_metric')
      ->condition('id', $ids, 'IN')
      ->execute();
  }

  /**
   * {@inheritdoc}
   */
  public function cleanupAll(): int {
    if (!$this->isAvailable()) {
      return 0;
    }

    $count = (int) $this->database->select('native_observability_route_metric', 'm')
      ->countQuery()
      ->execute()
      ->fetchField();

    if ($count === 0) {
      return 0;
    }

    $this->database->truncate('native_observability_route_metric')->execute();

    return $count;
  }

}
