<?php

declare(strict_types=1);

namespace App\Framework\Queue\ValueObjects;

/**
 * Queue Name Value Object
 *
 * Represents a fully qualified queue name with type awareness
 */
final readonly class QueueName
{
    public function __construct(
        public string $value,
        public QueueType $type,
        public ?string $tenant = null
    ) {
        if (empty($value)) {
            throw new \InvalidArgumentException('Queue name cannot be empty');
        }

        if (! preg_match('/^[a-z0-9\-_.]+$/i', $value)) {
            throw new \InvalidArgumentException(
                sprintf('Queue name "%s" contains invalid characters. Only alphanumeric, dash, underscore and dot allowed.', $value)
            );
        }
    }

    public static function forCommand(string $name = 'default'): self
    {
        return new self("command.{$name}", QueueType::COMMAND);
    }

    public static function forEvent(string $eventType = 'default'): self
    {
        return new self("event.{$eventType}", QueueType::EVENT);
    }

    public static function forEmail(string $priority = 'default'): self
    {
        return new self("email.{$priority}", QueueType::EMAIL);
    }

    public static function forWebhook(string $service = 'default'): self
    {
        return new self("webhook.{$service}", QueueType::WEBHOOK);
    }

    public static function forReport(string $type = 'default'): self
    {
        return new self("report.{$type}", QueueType::REPORT);
    }

    public static function forImport(string $source = 'default'): self
    {
        return new self("import.{$source}", QueueType::IMPORT);
    }

    public static function default(): self
    {
        return new self('default', QueueType::DEFAULT);
    }

    public function withTenant(string $tenant): self
    {
        return new self($this->value, $this->type, $tenant);
    }

    public function toString(): string
    {
        $base = "{$this->type->value}.{$this->value}";

        return $this->tenant ? "{$this->tenant}.{$base}" : $base;
    }

    public function equals(self $other): bool
    {
        return $this->toString() === $other->toString();
    }

    public function __toString(): string
    {
        return $this->toString();
    }

    /**
     * Get Redis key for this queue
     */
    public function toRedisKey(): string
    {
        return 'queue:' . $this->toString();
    }

    /**
     * Get file path for this queue (for FileQueue)
     */
    public function toFilePath(): string
    {
        return str_replace('.', '/', $this->toString());
    }
}
