<?php

declare(strict_types=1);

namespace App\Framework\Core;

use App\Framework\Attributes\Route;
use App\Framework\Reflection\WrappedReflectionClass;
use App\Framework\Reflection\WrappedReflectionMethod;
use App\Framework\Router\ValueObjects\MethodParameter;
use App\Framework\Router\ValueObjects\ParameterCollection;

final readonly class RouteMapper implements AttributeMapper
{
    public function getAttributeClass(): string
    {
        return Route::class;
    }

    public function map(WrappedReflectionClass|WrappedReflectionMethod $reflectionTarget, object $attributeInstance): ?array
    {
        if (! $attributeInstance instanceof Route) {
            return null;
        }

        // Route attributes are only valid on methods
        if (! $reflectionTarget instanceof WrappedReflectionMethod) {
            return null;
        }

        // Collect all non-Route attributes on the method
        $attributes = [];
        foreach ($reflectionTarget->getAttributes() as $attribute) {
            if ($attribute->getName() !== Route::class) {
                $attributes[] = $attribute->getName();
            }
        }

        // Extract method parameters using type-safe Value Objects
        $methodParameters = [];
        foreach ($reflectionTarget->getParameters() as $parameter) {
            $methodParameters[] = MethodParameter::fromWrappedParameter($parameter);
        }
        $parameterCollection = new ParameterCollection(...$methodParameters);

        return [
            'class' => $reflectionTarget->getDeclaringClass()->getFullyQualified(),
            'method' => $reflectionTarget->getName(),
            'http_method' => $attributeInstance->method,
            'path' => $attributeInstance->path,
            'name' => $attributeInstance->name,
            'parameters' => $parameterCollection->toLegacyArray(), // Backward compatibility
            'parameter_collection' => $parameterCollection, // New type-safe collection
            'attributes' => $attributes,
        ];
    }
}
