<?php

namespace AC_SYNC\Includes\Classes\Async;

if (!defined('ABSPATH')) exit;

use AC_SYNC\Includes\Classes\Async\Backends\Action_Wear_Custom_Queue_Backend;
use AC_SYNC\Includes\Classes\Async\Backends\Action_Wear_Action_Scheduler_Backend;

class Action_Wear_Job_Queue
{
    /** @var Action_Wear_Queue_Backend_Interface|null */
    private static $backend = null;

    /**
     * Get the active queue backend based on setting.
     *
     * @return Action_Wear_Queue_Backend_Interface
     */
    public static function getBackend(): Action_Wear_Queue_Backend_Interface
    {
        if (self::$backend === null) {
            $engine = get_option('_ACTIONWEAR_QUEUE_ENGINE', 'action_scheduler');

            if ($engine === 'action_scheduler') {
                self::$backend = new Action_Wear_Action_Scheduler_Backend();
            } else {
                self::$backend = new Action_Wear_Custom_Queue_Backend();
            }
        }

        return self::$backend;
    }

    /**
     * Reset cached backend (call after switching engine).
     */
    public static function resetBackend(): void
    {
        self::$backend = null;
    }

    /**
     * Check if currently using Action Scheduler.
     */
    public static function isActionScheduler(): bool
    {
        return self::getBackend() instanceof Action_Wear_Action_Scheduler_Backend;
    }

    // --- Delegating static methods ---

    public static function push(
        string $jobType,
        ?array $payload = null,
        int $priority = 50,
        ?string $availableAt = null,
        ?string $conflictGroup = null,
        int $maxAttempts = 3,
        ?int $excludeJobId = null
    ) {
        return self::getBackend()->push($jobType, $payload, $priority, $availableAt, $conflictGroup, $maxAttempts, $excludeJobId);
    }

    public static function pushProductImport(string $sku, ?array $productData = null): int
    {
        return self::getBackend()->pushProductImport($sku, $productData);
    }

    public static function batchPushProductImport(array $skus): int
    {
        return self::getBackend()->batchPushProductImport($skus);
    }

    public static function cancel(int $jobId): bool
    {
        return self::getBackend()->cancel($jobId);
    }

    public static function cancelByType(string $jobType): int
    {
        return self::getBackend()->cancelByType($jobType);
    }

    public static function hasPending(string $jobType, ?int $excludeJobId = null): bool
    {
        return self::getBackend()->hasPending($jobType, $excludeJobId);
    }

    public static function hasRunning(string $conflictGroup): bool
    {
        return self::getBackend()->hasRunning($conflictGroup);
    }

    public static function hasPendingJobs(): bool
    {
        return self::getBackend()->hasPendingJobs();
    }

    public static function countPending(): int
    {
        return self::getBackend()->countPending();
    }

    public static function getJobs(array $filters = [], int $limit = 200): array
    {
        return self::getBackend()->getJobs($filters, $limit);
    }

    public static function getJobCounts(): array
    {
        return self::getBackend()->getJobCounts();
    }

    public static function pruneCompleted(int $olderThanHours = 48): int
    {
        return self::getBackend()->pruneCompleted($olderThanHours);
    }

    public static function resetClaimed(): int
    {
        return self::getBackend()->resetClaimed();
    }

    public static function retryAllFailed(): int
    {
        return self::getBackend()->retryAllFailed();
    }

    public static function retryJob(int $jobId): bool
    {
        return self::getBackend()->retryJob($jobId);
    }
}
