<?php
declare(strict_types=1);

namespace PpPhp\Core\Designer\Property;

use PpPhp\Core\Designer\Component\DesignerComponentRuntime;

final class DesignerPropertyRuntime
{
    private DesignerPropertyEditorRegistry $editors;
    private DesignerComponentRuntime $components;
    private DesignerInspectorGenerator $generator;

    public function __construct(?DesignerComponentRuntime $components = null, ?DesignerPropertyEditorRegistry $editors = null)
    {
        $this->components = $components ?? new DesignerComponentRuntime();
        $this->editors = $editors ?? DesignerPropertyEditorRegistry::defaults();
        $this->generator = new DesignerInspectorGenerator();
    }

    public function editors(): DesignerPropertyEditorRegistry { return $this->editors; }

    public function schemaFor(string $componentType): array
    {
        $definition = $this->components->registry()->get($componentType);
        if (!$definition) {
            throw new \RuntimeException('Unknown Designer component type for property schema: ' . $componentType);
        }

        return DesignerPropertySchema::fromComponentDefinition($definition->toArray(), $this->editors)->toArray();
    }

    public function inspectorFor(array $component): array
    {
        $type = (string) ($component['type'] ?? '');
        $definition = $this->components->registry()->get($type);
        if (!$definition) {
            throw new \RuntimeException('Unknown Designer component type for inspector: ' . $type);
        }

        $schema = DesignerPropertySchema::fromComponentDefinition($definition->toArray(), $this->editors);
        return $this->generator->generate($component, $definition->toArray(), $schema);
    }

    public function apply(array $component, array $changes): array
    {
        $component['props'] = array_replace_recursive((array) ($component['props'] ?? []), $changes);
        $component['meta'] = array_replace_recursive((array) ($component['meta'] ?? []), [
            'lastPropertyUpdateAt' => date('c'),
        ]);
        return $component;
    }

    public function summary(): array
    {
        $componentSummary = $this->components->summary();
        return [
            'editors' => count($this->editors->all()),
            'components' => $componentSummary['components'] ?? 0,
            'propertySchemas' => $componentSummary['propertySchemas'] ?? 0,
        ];
    }
}
