<?php

declare(strict_types=1);

require_once __DIR__ . '/../../vendor/autoload.php';

use App\Framework\LiveComponents\Contracts\ComponentRegistryInterface;
use App\Framework\LiveComponents\Contracts\LiveComponentContract;
use App\Framework\LiveComponents\Performance\ComponentMetadataCacheInterface;
use App\Framework\LiveComponents\Performance\CompiledComponentMetadata;
use App\Framework\LiveComponents\Performance\ComponentPropertyMetadata;
use App\Framework\LiveComponents\ValueObjects\ComponentData;
use App\Framework\LiveComponents\ValueObjects\ComponentId;
use App\Framework\LiveComponents\ValueObjects\ComponentRenderData;
use App\Framework\View\Contracts\HtmlComponentRegistryInterface;
use App\Framework\View\DomComponentService;
use App\Framework\View\Processors\XComponentProcessor;
use App\Framework\View\RenderContext;
use App\Framework\Template\Parser\DomTemplateParser;
use App\Framework\Meta\MetaData;

echo "=== Test XComponentProcessor Flow ===\n\n";

// 1. Create mocks manually
$liveComponentRegistry = new class implements ComponentRegistryInterface {
    public function resolve(ComponentId $componentId, ?ComponentData $state = null): LiveComponentContract
    {
        echo "✓ resolve() called with ComponentId: {$componentId->toString()}\n";
        echo "  State: " . json_encode($state?->toArray()) . "\n";

        return new class implements LiveComponentContract {
            public function getId(): ComponentId { return ComponentId::create('counter', 'demo'); }
            public function getData(): ComponentData { return ComponentData::fromArray(['initialValue' => 5]); }
            public function getRenderData(): ComponentRenderData {
                return new ComponentRenderData('counter-template', ['value' => 5]);
            }
        };
    }

    public function render(LiveComponentContract $component): string
    {
        return '<div>Basic Counter</div>';
    }

    public function renderWithWrapper(LiveComponentContract $component): string
    {
        echo "✓ renderWithWrapper() called\n";
        return '<div data-component-id="counter:demo">Counter HTML</div>';
    }

    public function isRegistered(string $componentName): bool
    {
        echo "✓ isRegistered() called for: {$componentName}\n";
        return $componentName === 'counter';
    }

    public function getClassName(string $componentName): ?string
    {
        echo "✓ getClassName() called for: {$componentName}\n";
        return $componentName === 'counter' ? 'TestCounterComponent' : null;
    }

    public function getAllComponentNames(): array
    {
        return ['counter'];
    }
};

$htmlComponentRegistry = new class implements HtmlComponentRegistryInterface {
    public function has(string $componentName): bool
    {
        echo "✓ htmlComponentRegistry->has() called for: {$componentName}\n";
        return false;
    }

    public function render(string $componentName, string $content, array $attributes): string
    {
        return '';
    }

    public function getAllComponentNames(): array
    {
        return [];
    }
};

$metadataCache = new class implements ComponentMetadataCacheInterface {
    public function get(string $className): CompiledComponentMetadata
    {
        echo "✓ metadataCache->get() called for: {$className}\n";

        return new CompiledComponentMetadata(
            className: 'TestCounterComponent',
            componentName: 'counter',
            properties: [
                'initialValue' => new ComponentPropertyMetadata(
                    name: 'initialValue',
                    type: 'int',
                    isPublic: true,
                    isReadonly: false
                )
            ],
            actions: [],
            constructorParams: []
        );
    }

    public function has(string $className): bool
    {
        return true;
    }

    public function invalidate(string $className): bool
    {
        return true;
    }

    public function warmCache(array $classNames): int
    {
        return 0;
    }
};

$componentService = new DomComponentService();

// 2. Create processor
$processor = new XComponentProcessor(
    $liveComponentRegistry,
    $htmlComponentRegistry,
    $metadataCache,
    $componentService
);

// 3. Parse HTML
$parser = new DomTemplateParser();
$html = '<html><body><x-counter id="demo" initialValue="5" /></body></html>';
echo "Input HTML: {$html}\n\n";

$dom = $parser->parseToWrapper($html);

// 4. Create context
$context = new RenderContext(
    template: 'test-template',
    metaData: new MetaData('Test Component Processing'),
    data: []
);

// 5. Process
echo "=== Processing ===\n";
try {
    $result = $processor->process($dom, $context);
    echo "\n=== Result ===\n";
    $resultHtml = $result->document->saveHTML();
    echo "Output HTML: {$resultHtml}\n";

    if (str_contains($resultHtml, 'data-component-id="counter:demo"')) {
        echo "\n✅ SUCCESS: Component was properly replaced!\n";
    } else {
        echo "\n❌ FAILURE: Component was NOT replaced!\n";
    }
} catch (\Throwable $e) {
    echo "\n❌ ERROR: " . $e->getMessage() . "\n";
    echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
}
