<?php

declare(strict_types=1);

namespace App\Framework\Router;

use ReflectionNamedType;
use ReflectionProperty;

final readonly class PropertyValueConverter
{
    /**
     * Setzt einen Wert für eine Property mit entsprechender Typenkonvertierung
     */
    public function setPropertyValue(ReflectionProperty $property, object $instance, mixed $value): void
    {
        // Nur Default-Wert setzen wenn kein anderer Wert bereitgestellt wurde
        if ($value === null && $property->hasDefaultValue()) {
            $property->setValue($instance, $property->getDefaultValue());

            return;
        }

        if ($value === null) {
            $property->setValue($instance, null);

            return;
        }

        $type = $property->getType();

        if ($type instanceof ReflectionNamedType) {
            $typeName = $type->getName();
            $value = $this->convertValueToType($value, $typeName);
        }

        $property->setValue($instance, $value);
    }

    /**
     * Konvertiert einen Wert in den angegebenen Typ
     */
    private function convertValueToType(mixed $value, string $typeName): mixed
    {
        return match ($typeName) {
            'int' => (int) $value,
            'float' => (float) $value,
            'bool' => filter_var($value, FILTER_VALIDATE_BOOLEAN),
            'string' => (string) $value,
            'array' => is_array($value) ? $value : [$value],
            default => $value
        };
    }
}
