<?php

declare(strict_types=1);

namespace App\Framework\Reflection;

use ReflectionMethod;
use ReflectionAttribute;

final readonly class WrappedReflectionMethod
{
    public function __construct(
        public ReflectionMethod $reflection
    ) {}

    public function getName(): string
    {
        return $this->reflection->getName();
    }

    public function getWrappedParameters(): array
    {
        return array_map(
            fn($param) => new WrappedReflectionParameter($param),
            $this->reflection->getParameters()
        );
    }

    // Erweiterte Parameter-Info als Array (für DI)
    public function getParameterInfo(): array
    {
        $params = [];
        foreach ($this->reflection->getParameters() as $param) {
            $type = $param->getType();
            $params[] = [
                'name' => $param->getName(),
                'type' => $type ? $type->getName() : null,
                'isBuiltin' => $type ? $type->isBuiltin() : true,
                'allowsNull' => $param->allowsNull(),
                'isOptional' => $param->isOptional(),
                'hasDefaultValue' => $param->isDefaultValueAvailable(),
                'default' => $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null,
                'position' => $param->getPosition(),
            ];
        }
        return $params;
    }

    public function getAttributeInstances(?string $attributeClass = null): array
    {
        $attributes = $this->reflection->getAttributes($attributeClass);
        return array_map(fn(ReflectionAttribute $attr) => $attr->newInstance(), $attributes);
    }

    public function hasAttribute(string $attributeClass): bool
    {
        return !empty($this->reflection->getAttributes($attributeClass));
    }

    public function getFirstAttribute(string $attributeClass): ?object
    {
        $instances = $this->getAttributeInstances($attributeClass);
        return $instances[0] ?? null;
    }
}
