<?php

declare(strict_types=1);

/**
 * Minimal Manual Test for DataProvider Resolution Flow
 *
 * This test manually verifies the DataProvider resolution logic without
 * full framework bootstrap to isolate the specific feature being tested.
 */

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

use App\Application\LiveComponents\InfiniteScroll\InfiniteScrollComponent;
use App\Application\LiveComponents\Services\DemoScrollDataProvider;
use App\Application\LiveComponents\Services\ScrollDataProvider;
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Discovery\Results\AttributeRegistry;
use App\Framework\Discovery\Results\DiscoveryRegistry;
use App\Framework\Discovery\Results\InterfaceRegistry;
use App\Framework\Discovery\ValueObjects\DiscoveredAttribute;
use App\Framework\LiveComponents\DataProviderResolver;
use App\Framework\LiveComponents\ValueObjects\ComponentId;
use App\Framework\Reflection\WrappedReflectionClass;

echo "\nMinimal DataProvider Resolution Test\n";
echo str_repeat('=', 70) . "\n\n";

// 1. Create Mock Discovery System
echo "1. Creating mock DataProviderResolver...\n";

// Create mock registries
$attributeRegistry = new AttributeRegistry();
$interfaceRegistry = new InterfaceRegistry();
$discoveryRegistry = new DiscoveryRegistry($attributeRegistry, $interfaceRegistry);

// Manually register DataProvider
$reflectionClass = new WrappedReflectionClass(ClassName::create(DemoScrollDataProvider::class));
$attributeRegistry->register(
    new DiscoveredAttribute(
        attributeClass: 'App\\Framework\\LiveComponents\\Attributes\\DataProvider',
        targetClass: DemoScrollDataProvider::class,
        targetType: 'class',
        targetName: null,
        attributeInstance: new \App\Framework\LiveComponents\Attributes\DataProvider(
            interface: ScrollDataProvider::class,
            name: 'demo'
        ),
        context: null,
        reflection: $reflectionClass
    )
);

// Create mock discovery service
$mockDiscovery = new class ($attributeRegistry, $discoveryRegistry) {
    public function __construct(
        private AttributeRegistry $attributeRegistry,
        private DiscoveryRegistry $discoveryRegistry
    ) {
    }

    public function getAttributeRegistry(): AttributeRegistry
    {
        return $this->attributeRegistry;
    }

    public function getDiscoveryRegistry(): DiscoveryRegistry
    {
        return $this->discoveryRegistry;
    }
};

// Create resolver
$resolver = new DataProviderResolver($mockDiscovery);
echo "✓ Mock DataProviderResolver created\n\n";

// 2. Test: Initial Component Creation
echo "2. Test: Initial Component Creation with dataSource='demo'...\n";
$component = new InfiniteScrollComponent(
    id: ComponentId::fromString('scroll:test'),
    dataProviderResolver: $resolver,
    items: [],
    currentPage: 0,
    pageSize: 5,
    dataSource: 'demo'
);
echo "✓ Component created successfully\n";

// Get initial state
$initialData = $component->getData();
echo "  - Data has 'data_source': " . ($initialData->has('data_source') ? 'YES' : 'NO') . "\n";
echo "  - dataSource value: '" . $initialData->get('data_source') . "'\n";
echo "  - Items count: " . count($initialData->get('items')) . "\n\n";

// 3. Test: Execute Action
echo "3. Test: Execute Action - loadMore()...\n";

try {
    $actionResult = $component->loadMore();
    echo "✓ Action executed successfully\n";

    echo "  - Items loaded: " . count($actionResult->get('items')) . "\n";
    echo "  - Current page: " . $actionResult->get('current_page') . "\n";
    echo "  - Has 'data_source': " . ($actionResult->has('data_source') ? 'YES' : 'NO') . "\n";
    echo "  - dataSource value: '" . $actionResult->get('data_source') . "'\n\n";
} catch (\Exception $e) {
    echo "✗ FAILED: " . $e->getMessage() . "\n";
    echo "  File: " . $e->getFile() . ":" . $e->getLine() . "\n";
    exit(1);
}

// 4. Test: State Restoration
echo "4. Test: State Restoration from ComponentData...\n";
echo "  - Attempting to reconstruct component from action result...\n";

try {
    $restoredComponent = new InfiniteScrollComponent(
        id: ComponentId::fromString('scroll:test-restored'),
        dataProviderResolver: $resolver,
        initialData: $actionResult  // This triggers state restoration path
    );
    echo "✓ Component restored from ComponentData\n";

    $restoredData = $restoredComponent->getData();
    echo "  - Restored items count: " . count($restoredData->get('items')) . "\n";
    echo "  - Restored page: " . $restoredData->get('current_page') . "\n";
    echo "  - Restored dataSource: '" . $restoredData->get('data_source') . "'\n\n";
} catch (\Exception $e) {
    echo "✗ FAILED: " . $e->getMessage() . "\n";
    echo "  File: " . $e->getFile() . ":" . $e->getLine() . "\n";
    echo "  Stack trace:\n" . $e->getTraceAsString() . "\n\n";
    exit(1);
}

// 5. Test: Action on Restored Component
echo "5. Test: Action on Restored Component...\n";

try {
    $secondActionResult = $restoredComponent->loadMore();
    echo "✓ Second action executed successfully\n";

    echo "  - Total items: " . count($secondActionResult->get('items')) . "\n";
    echo "  - Current page: " . $secondActionResult->get('current_page') . "\n";
    echo "  - dataSource: '" . $secondActionResult->get('data_source') . "'\n\n";
} catch (\Exception $e) {
    echo "✗ FAILED: " . $e->getMessage() . "\n";
    echo "  File: " . $e->getFile() . ":" . $e->getLine() . "\n";
    exit(1);
}

// 6. Verify All Requirements
echo "6. Verification of Requirements...\n";
$allPassed = true;

// Requirement 1: dataSource preserved through state transformations
if ($secondActionResult->get('data_source') !== 'demo') {
    echo "✗ FAIL: dataSource not preserved\n";
    echo "  Expected: 'demo'\n";
    echo "  Got: '" . $secondActionResult->get('data_source') . "'\n";
    $allPassed = false;
} else {
    echo "✓ PASS: dataSource preserved correctly ('demo')\n";
}

// Requirement 2: Component state preserved correctly
if ($secondActionResult->get('current_page') !== 2) {
    echo "✗ FAIL: Page progression incorrect\n";
    echo "  Expected page: 2\n";
    echo "  Got page: " . $secondActionResult->get('current_page') . "\n";
    $allPassed = false;
} else {
    echo "✓ PASS: Page progression correct (2)\n";
}

// Requirement 3: Data accumulated correctly
$expectedItems = 10; // 5 items per page * 2 pages
$actualItems = count($secondActionResult->get('items'));
if ($actualItems !== $expectedItems) {
    echo "✗ FAIL: Item accumulation incorrect\n";
    echo "  Expected items: $expectedItems\n";
    echo "  Got items: $actualItems\n";
    $allPassed = false;
} else {
    echo "✓ PASS: Item accumulation correct ($expectedItems items)\n";
}

echo "\n" . str_repeat('=', 70) . "\n";
if ($allPassed) {
    echo "✅ ALL TESTS PASSED\n";
    echo "DataProvider resolution flow is working correctly!\n";
    echo "\n";
    echo "Summary:\n";
    echo "- Initial render with dataSource ✓\n";
    echo "- Action execution with state update ✓\n";
    echo "- State restoration from ComponentData ✓\n";
    echo "- Provider resolution in restored component ✓\n";
    echo "- Subsequent actions on restored component ✓\n";
    exit(0);
} else {
    echo "❌ SOME TESTS FAILED\n";
    echo "Review failures above for details.\n";
    exit(1);
}
