<?php

namespace AC_SYNC\Includes\Classes\Async;

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

class Action_Wear_Job_Result
{
    const TYPE_SUCCESS = 'success';
    const TYPE_RETRY   = 'retry';
    const TYPE_FAIL    = 'fail';

    /** @var string */
    private $type;

    /** @var array Follow-up jobs to enqueue on success */
    private $followUpJobs;

    /** @var int Cooldown seconds before retry */
    private $cooldownSeconds;

    /** @var string Reason for retry or failure */
    private $reason;

    private function __construct(string $type, array $followUpJobs = [], int $cooldownSeconds = 0, string $reason = '')
    {
        $this->type = $type;
        $this->followUpJobs = $followUpJobs;
        $this->cooldownSeconds = $cooldownSeconds;
        $this->reason = $reason;
    }

    /**
     * Job completed successfully, optionally enqueue follow-up jobs.
     *
     * @param array $followUpJobs Array of ['type' => string, 'payload' => array, 'priority' => int, 'conflict_group' => string|null]
     * @return self
     */
    public static function success(array $followUpJobs = []): self
    {
        return new self(self::TYPE_SUCCESS, $followUpJobs);
    }

    /**
     * Retry the job after a cooldown period.
     *
     * @param int    $cooldownSeconds
     * @param string $reason
     * @return self
     */
    public static function retry(int $cooldownSeconds, string $reason = ''): self
    {
        return new self(self::TYPE_RETRY, [], $cooldownSeconds, $reason);
    }

    /**
     * Permanent failure — do not retry.
     *
     * @param string $reason
     * @return self
     */
    public static function fail(string $reason = ''): self
    {
        return new self(self::TYPE_FAIL, [], 0, $reason);
    }

    public function isSuccess(): bool
    {
        return $this->type === self::TYPE_SUCCESS;
    }

    public function isRetry(): bool
    {
        return $this->type === self::TYPE_RETRY;
    }

    public function isFail(): bool
    {
        return $this->type === self::TYPE_FAIL;
    }

    public function getFollowUpJobs(): array
    {
        return $this->followUpJobs;
    }

    public function getCooldownSeconds(): int
    {
        return $this->cooldownSeconds;
    }

    public function getReason(): string
    {
        return $this->reason;
    }
}
