<?php

declare(strict_types=1);

namespace App\Framework\Queue\ValueObjects;

/**
 * Value Object representing a dependency relationship between jobs
 */
final readonly class JobDependency
{
    public function __construct(
        public string $dependentJobId,
        public string $dependsOnJobId,
        public DependencyType $type = DependencyType::COMPLETION,
        public ?string $condition = null
    ) {
        $this->validate();
    }

    public static function completion(string $dependentJobId, string $dependsOnJobId): self
    {
        return new self($dependentJobId, $dependsOnJobId, DependencyType::COMPLETION);
    }

    public static function success(string $dependentJobId, string $dependsOnJobId): self
    {
        return new self($dependentJobId, $dependsOnJobId, DependencyType::SUCCESS);
    }

    public static function conditional(string $dependentJobId, string $dependsOnJobId, string $condition): self
    {
        return new self($dependentJobId, $dependsOnJobId, DependencyType::CONDITIONAL, $condition);
    }

    public function isCompleted(): bool
    {
        return $this->type === DependencyType::COMPLETION;
    }

    public function requiresSuccess(): bool
    {
        return $this->type === DependencyType::SUCCESS;
    }

    public function isConditional(): bool
    {
        return $this->type === DependencyType::CONDITIONAL;
    }

    public function getCondition(): ?string
    {
        return $this->condition;
    }

    public function equals(self $other): bool
    {
        return $this->dependentJobId === $other->dependentJobId
            && $this->dependsOnJobId === $other->dependsOnJobId
            && $this->type === $other->type
            && $this->condition === $other->condition;
    }

    public function toArray(): array
    {
        return [
            'dependent_job_id' => $this->dependentJobId,
            'depends_on_job_id' => $this->dependsOnJobId,
            'type' => $this->type->value,
            'condition' => $this->condition,
        ];
    }

    private function validate(): void
    {
        if (empty(trim($this->dependentJobId))) {
            throw new \InvalidArgumentException('Dependent job ID cannot be empty');
        }

        if (empty(trim($this->dependsOnJobId))) {
            throw new \InvalidArgumentException('Depends on job ID cannot be empty');
        }

        if ($this->dependentJobId === $this->dependsOnJobId) {
            throw new \InvalidArgumentException('Job cannot depend on itself');
        }

        if ($this->type === DependencyType::CONDITIONAL && empty($this->condition)) {
            throw new \InvalidArgumentException('Conditional dependency must have a condition');
        }
    }
}
