<?php

declare(strict_types=1);

namespace App\Framework\Router\ValueObjects;

/**
 * Represents a subdomain pattern for route matching
 */
final readonly class SubdomainPattern
{
    public function __construct(
        public string $pattern,
        public bool $isWildcard = false,
        public bool $isOptional = false
    ) {
    }

    /**
     * Check if this pattern matches the given subdomain
     */
    public function matches(string $subdomain): bool
    {
        if ($this->isWildcard) {
            return fnmatch($this->pattern, $subdomain);
        }

        return $this->pattern === $subdomain;
    }

    /**
     * Create SubdomainPattern from string
     */
    public static function fromString(string $pattern): self
    {
        $isWildcard = str_contains($pattern, '*');
        $isOptional = str_starts_with($pattern, '?');

        return new self(
            pattern: trim($pattern, '?'),
            isWildcard: $isWildcard,
            isOptional: $isOptional
        );
    }

    /**
     * Create array of SubdomainPattern from mixed input
     */
    public static function fromInput(array|string $input): array
    {
        if (is_string($input)) {
            return $input ? [self::fromString($input)] : [];
        }

        return array_map(fn (string $pattern) => self::fromString($pattern), $input);
    }

    /**
     * Check if this is a default pattern (no subdomain restriction)
     */
    public function isDefault(): bool
    {
        return empty($this->pattern);
    }

    /**
     * Get the key for this pattern in route compilation
     */
    public function getCompilationKey(): string
    {
        if ($this->isDefault()) {
            return 'default';
        }

        if ($this->isWildcard) {
            return 'wildcard:' . $this->pattern;
        }

        return 'exact:' . $this->pattern;
    }

    public function toString(): string
    {
        $prefix = $this->isOptional ? '?' : '';

        return $prefix . $this->pattern;
    }
}
