<?php

declare(strict_types=1);

namespace Drupal\conductor;

use Drupal\Component\Datetime\Time;
use Drupal\conductor\Repository\DraftRepository;
use Drupal\conductor\Repository\DraftRepositoryInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Psr\Log\LoggerInterface;

/**
 * Service to clean up old, unlinked Conductor drafts.
 */
final readonly class DraftCleanup {

  public function __construct(
    private ConductorHttpApiClient $client,
    private DraftRepositoryInterface $draftRepository,
    private LoggerInterface $logger,
    private Time $time,
    private ConfigFactoryInterface $configFactory,
  ) {
  }

  /**
   * Executes the cleanup process.
   */
  public function run(): array {
    $config = $this->configFactory->get('conductor.settings');

    if (!$config->get('enable_draft_cleanup')) {
      return [];
    }

    $min_age_seconds = (int) $config->get('delete_unlinked_drafts_after');
    $now = $this->time->getCurrentTime();
    $draftsDeleted = [];

    try {
      $drafts = $this->client->getExistingDrafts();
      $candidates = [];

      foreach ($drafts as $draft) {
        $title = (string) ($draft['draftTitle'] ?? '');
        if (!str_starts_with($title, DraftRepository::DEFAULT_DRAFT_TITLE)) {
          continue;
        }

        if (($now - (int) $draft['created']) < $min_age_seconds) {
          // Too new, so keep.
          continue;
        }

        // Skip drafts that are already mapped in Drupal.
        if ($this->draftRepository->isDraftLinkedToAnEntity((string) $draft['id'])) {
          continue;
        }

        $candidates[] = (string) $draft['id'];
      }

      $deleted = 0;
      foreach ($candidates as $draft_id) {
        if ($this->client->deleteDraft($draft_id)) {
          $deleted++;
          $draftsDeleted[] = (string) $draft_id;
        }
      }

      if (!empty($candidates)) {
        $this->logger->notice('Draft cleanup cron evaluated @count candidates; deleted @deleted drafts with prefix "%prefix".', [
          '@count' => (string) count($candidates),
          '@deleted' => (string) $deleted,
          '%prefix' => DraftRepository::DEFAULT_DRAFT_TITLE,
        ]);
      }
    }
    catch (\Throwable $e) {
      $this->logger->error('Cleanup cron failed: @message', ['@message' => $e->getMessage()]);
    }

    return $draftsDeleted;
  }

}
