<?php

declare(strict_types=1);

namespace App\Framework\GraphQL\Schema;

use App\Framework\GraphQL\ValueObjects\GraphQLFieldName;
use App\Framework\GraphQL\ValueObjects\GraphQLTypeRef;

/**
 * Represents a GraphQL field definition
 *
 * Immutable value object containing all field metadata
 */
final readonly class FieldDefinition
{
    /**
     * @param array<string, ArgumentDefinition> $arguments
     */
    public function __construct(
        public GraphQLFieldName $name,
        public GraphQLTypeRef $type,
        public \Closure $resolver,
        public array $arguments = [],
        public ?string $description = null,
        public bool $deprecated = false,
        public ?string $deprecationReason = null
    ) {
    }

    /**
     * Convert to GraphQL schema definition language (SDL)
     */
    public function toSDL(): string
    {
        $sdl = $this->name->toString();

        // Add arguments if any
        if (! empty($this->arguments)) {
            $argStrings = array_map(
                fn (ArgumentDefinition $arg) => $arg->toSDL(),
                $this->arguments
            );
            $sdl .= '(' . implode(', ', $argStrings) . ')';
        }

        // Add return type
        $sdl .= ': ' . $this->type->toSchemaString();

        // Add deprecation
        if ($this->deprecated) {
            $reason = $this->deprecationReason ?? 'No longer supported';
            $sdl .= ' @deprecated(reason: "' . addslashes($reason) . '")';
        }

        return $sdl;
    }

    /**
     * Resolve field value
     */
    public function resolve(mixed $rootValue, array $args, mixed $context): mixed
    {
        return ($this->resolver)($rootValue, $args, $context);
    }
}
