<?php

declare(strict_types=1);

namespace ReallySimplePlugins\RSS\Core\Features\Vulnerability\Controllers;

use ReallySimplePlugins\RSS\Core\Features\Vulnerability\Services\VulnerabilityAfterSyncService;
use ReallySimplePlugins\RSS\Core\Features\Vulnerability\VulnerabilityController;
use ReallySimplePlugins\RSS\Core\Interfaces\ControllerInterface;
use ReallySimplePlugins\RSS\Core\Traits\HasScheduler;

/**
 * Orchestrates vulnerability re-sync triggers and notification decisions.
 *
 * Constraints: Delegates syncing, snapshot building, and email delivery to services and repositories.
 */
final class VulnerabilityNotificationController implements ControllerInterface
{
    use HasScheduler;


    /**
     * Debounce window (in seconds) for scheduling sync runs.
     */
    private const SYNC_DEBOUNCE_SECONDS = 300; // 5 minutes

    public const AFTER_SYNC_COMPLETED_ACTION = 'rsssl_vulnerability_after_sync_completed';
    private const SCHEDULED_AFTER_SYNC_ACTION = 'rsssl_vulnerability_run_after_sync';
    private VulnerabilityAfterSyncService $service;

    public function __construct(VulnerabilityAfterSyncService $service)
    {
        $this->service = $service;
    }

    public function register(): void
    {
        add_action(VulnerabilityController::SYNC_COMPLETED_ACTION, [$this, 'schedule'], 10, 0);
        add_action(self::SCHEDULED_AFTER_SYNC_ACTION, [$this, 'runAfterSync'], 10, 0);
        add_action('rsssl_daily_cron', [$this, 'schedule']);
    }

    /**
     * Schedule the after-sync notification decision process.
     *
     * @return void
     */
    public function schedule(): void
    {
        $this->scheduleDebounced(
            self::SCHEDULED_AFTER_SYNC_ACTION,
            self::SYNC_DEBOUNCE_SECONDS,
            []
        );
    }

    /**
     * Run the after-sync notification decision process.
     *
     * @return void
     */
    public function runAfterSync(): void
    {
        $this->service->run();
        // Release the debounce lock after processing.
        $this->releaseDebounceLock(self::SCHEDULED_AFTER_SYNC_ACTION);
        // Signal that the after-sync process has completed.
        do_action(self::AFTER_SYNC_COMPLETED_ACTION);
    }
}
