<?php

namespace WPSN\Cli;

use WPSN\Core\Container;
use WPSN\Core\Queue\QueuePause;

defined('ABSPATH') || exit;

/**
 * Queue CLI commands.
 */
final class QueueCommand
{
    private Container $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    /**
     * Show queue status (counts by status).
     *
     * ## EXAMPLES
     *
     *     wp wpsn queue status
     */
    public function status(array $args, array $assocArgs): void
    {
        /** @var \WPSN\Core\Queue\QueueInterface $queue */
        $queue = $this->container->get('queue');
        $counts = $queue->counts();

        \WP_CLI::log('Queue paused: ' . (QueuePause::isPaused() ? 'yes' : 'no'));
        foreach ($counts as $k => $v) {
            \WP_CLI::log(sprintf('%s: %d', $k, (int) $v));
        }
    }

    /**
     * Run the internal queue worker.
     *
     * ## OPTIONS
     *
     * [--max=<n>]
     * : Max jobs to process (default: 10)
     *
     * [--force]
     * : Run even if Queue is paused.
     *
     * ## EXAMPLES
     *
     *     wp wpsn queue run --max=25
     */
    public function run(array $args, array $assocArgs): void
    {
        $max = isset($assocArgs['max']) ? (int) $assocArgs['max'] : 10;
        $max = max(1, min(200, $max));

        $force = !empty($assocArgs['force']);
        if (QueuePause::isPaused() && !$force) {
            \WP_CLI::warning('Queue is paused. Use --force to run anyway.');
            return;
        }

        /** @var \WPSN\Core\Queue\QueueRunner $runner */
        $runner = $this->container->get('queue_runner');

        $processed = (int) $runner->run($max);
        \WP_CLI::success(sprintf('Processed %d job(s).', $processed));
    }

    /**
     * Pause queue processing.
     *
     * ## OPTIONS
     *
     * [--for=<seconds>]
     * : Seconds to pause (default: 3600)
     */
    public function pause(array $args, array $assocArgs): void
    {
        $seconds = isset($assocArgs['for']) ? (int) $assocArgs['for'] : 3600;
        $seconds = max(60, min(7 * DAY_IN_SECONDS, $seconds));
        $until = QueuePause::pause($seconds, 'wp_cli');
        \WP_CLI::success('Queue paused until ' . gmdate('Y-m-d H:i:s', $until) . ' UTC');
    }

    /**
     * Resume queue processing.
     */
    public function resume(array $args, array $assocArgs): void
    {
        QueuePause::resume();
        \WP_CLI::success('Queue resumed.');
    }
}
