<?php

declare(strict_types=1);

namespace App\Framework\GraphQL\ValueObjects;

use App\Framework\Exception\ErrorCode;
use App\Framework\Exception\FrameworkException;

/**
 * Represents a valid GraphQL field name
 */
final readonly class GraphQLFieldName
{
    private function __construct(
        public string $value
    ) {
    }

    public static function fromString(string $name): self
    {
        $trimmed = trim($name);

        if (empty($trimmed)) {
            throw FrameworkException::create(
                ErrorCode::VAL_BUSINESS_RULE_VIOLATION,
                'GraphQL field name cannot be empty'
            );
        }

        // Check for reserved double underscore prefix
        if (str_starts_with($trimmed, '__')) {
            throw FrameworkException::create(
                ErrorCode::VAL_BUSINESS_RULE_VIOLATION,
                'GraphQL field names starting with "__" are reserved for introspection'
            )->withData(['name' => $trimmed]);
        }

        // Validate pattern
        if (! preg_match('/^[_a-zA-Z][_a-zA-Z0-9]*$/', $trimmed)) {
            throw FrameworkException::create(
                ErrorCode::VAL_BUSINESS_RULE_VIOLATION,
                'Invalid GraphQL field name. Must start with letter or underscore'
            )->withData(['name' => $trimmed]);
        }

        return new self($trimmed);
    }

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

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

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