<?php

declare(strict_types=1);

namespace App\Framework\LiveComponents\ValueObjects;

use App\Framework\LiveComponents\Contracts\LiveComponentContract;
use App\Framework\View\Contracts\StaticComponent;

/**
 * Component Mapping - Einzelnes Name-zu-Class Mapping
 *
 * Repräsentiert ein einzelnes Mapping von Komponenten-Namen zu Klasse.
 * Wird als Teil von ComponentNameMap verwendet.
 */
final readonly class ComponentMapping
{
    /**
     * @param string $name Komponenten-Name (z.B. "counter", "search-bar")
     * @param class-string<LiveComponentContract|StaticComponent> $className Vollqualifizierter Klassenname
     */
    public function __construct(
        public string $name,
        public string $className
    ) {
        if (empty($this->name)) {
            throw new \InvalidArgumentException('Component name cannot be empty');
        }

        if (empty($this->className)) {
            throw new \InvalidArgumentException('Component class name cannot be empty');
        }

        // Validiere dass Klasse existiert
        if (!class_exists($this->className)) {
            throw new \InvalidArgumentException(
                "Component class does not exist: {$this->className}"
            );
        }

        // Validiere dass Klasse LiveComponent oder StaticComponent implementiert
        $isLiveComponent = is_subclass_of($this->className, LiveComponentContract::class);
        $isStaticComponent = is_subclass_of($this->className, StaticComponent::class);

        if (!$isLiveComponent && !$isStaticComponent) {
            throw new \InvalidArgumentException(
                "Component class must implement LiveComponentContract or StaticComponent: {$this->className}"
            );
        }
    }

    /**
     * Prüfen ob dieses Mapping ein LiveComponent ist
     */
    public function isLiveComponent(): bool
    {
        return is_subclass_of($this->className, LiveComponentContract::class);
    }

    /**
     * Prüfen ob dieses Mapping ein StaticComponent ist
     */
    public function isStaticComponent(): bool
    {
        return is_subclass_of($this->className, StaticComponent::class);
    }
}
