<?php

declare(strict_types=1);

namespace PrettyLinks\Pro\Health;

use PrettyLinks\Pro\Options\Store as OptionsStore;

/**
 * Schedules the `prli_link_health_check` WP-Cron event according to the
 * configured Pro `link_health_frequency` option.
 */
class Scheduler
{
    public const HOOK = 'prli_link_health_check';

    /**
     * Pro options store.
     *
     * @var OptionsStore
     */
    private OptionsStore $options;

    /**
     * Constructor.
     *
     * @param OptionsStore $options Pro options store.
     */
    public function __construct(OptionsStore $options)
    {
        $this->options = $options;
    }

    /**
     * Schedules or clears the link-health WP-Cron event based on the current options.
     *
     * @return void
     */
    public function boot(): void
    {
        if (!(bool) $this->options->getPro('enable_link_health', false)) {
            if (wp_next_scheduled(self::HOOK)) {
                wp_clear_scheduled_hook(self::HOOK);
            }
            return;
        }

        $frequency = (string) $this->options->getPro('link_health_frequency', 'weekly');
        // Valid values are 'weekly' and 'monthly'. Legacy 'daily' (and any
        // unexpected value) rewrites to 'weekly' — v4 dropped Daily because
        // the batched runner self-chains for as long as a full pass takes,
        // and an overlap window of less than a week is untenable on big
        // sites (see HealthChecker::runCheck). Writing the normalized
        // value back keeps the UI in sync with what the scheduler does.
        if ($frequency !== 'weekly' && $frequency !== 'monthly') {
            $frequency = 'weekly';
            $this->options->setPro('link_health_frequency', 'weekly');
        }
        $recurrence = $frequency === 'monthly' ? 'prli_monthly' : 'weekly';

        // If the user changed frequency since the last schedule, clear the
        // existing event so we don't keep firing on the old cadence. Only
        // the recurring event needs resetting — self-chained single events
        // use the same hook and will fall in line on the next boot.
        $current = wp_get_schedule(self::HOOK);
        if ($current !== false && $current !== $recurrence) {
            wp_clear_scheduled_hook(self::HOOK);
        }

        if (!wp_next_scheduled(self::HOOK)) {
            wp_schedule_event(time() + HOUR_IN_SECONDS, $recurrence, self::HOOK);
        }
    }
}
