<?php

declare(strict_types=1);

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

use App\Application\Components\CounterComponent;
use App\Framework\LiveComponents\ComponentEventDispatcher;
use App\Framework\LiveComponents\LiveComponentHandler;
use App\Framework\LiveComponents\ValueObjects\ComponentEvent;

echo "=== LiveComponent Event System Test ===\n\n";

// 1. Setup
echo "1. Setting up LiveComponent with EventDispatcher...\n";
$eventDispatcher = new ComponentEventDispatcher();
$handler = new LiveComponentHandler($eventDispatcher);

$component = new CounterComponent(
    id: 'counter:test',
    initialData: ['count' => 5]
);

echo "   ✓ Component created with count = 5\n\n";

// 2. Test increment with event dispatching
echo "2. Testing increment action (5 → 6)...\n";
$update = $handler->handle($component, 'increment', []);

echo "   New count: " . $update->state->data['count'] . "\n";
echo "   Events dispatched: " . count($update->events) . "\n";

foreach ($update->events as $event) {
    echo "   - Event: {$event->name}\n";
    echo "     Payload: " . json_encode($event->payload, JSON_PRETTY_PRINT) . "\n";
}

echo "\n";

// 3. Test increment to milestone (9 → 10)
echo "3. Testing increment to milestone (9 → 10)...\n";
$component = new CounterComponent(
    id: 'counter:test',
    initialData: ['count' => 9]
);

$update = $handler->handle($component, 'increment', []);

echo "   New count: " . $update->state->data['count'] . "\n";
echo "   Events dispatched: " . count($update->events) . "\n";

foreach ($update->events as $event) {
    echo "   - Event: {$event->name}\n";
    echo "     Payload: " . json_encode($event->payload, JSON_PRETTY_PRINT) . "\n";
}

echo "\n";

// 4. Test addAmount with milestone crossing
echo "4. Testing addAmount (5 + 15 = 20, crossing milestone 10)...\n";
$component = new CounterComponent(
    id: 'counter:test',
    initialData: ['count' => 5]
);

$update = $handler->handle($component, 'addAmount', ['amount' => 15]);

echo "   New count: " . $update->state->data['count'] . "\n";
echo "   Events dispatched: " . count($update->events) . "\n";

foreach ($update->events as $event) {
    echo "   - Event: {$event->name}\n";
    echo "     Payload: " . json_encode($event->payload, JSON_PRETTY_PRINT) . "\n";
}

echo "\n";

// 5. Test reset action
echo "5. Testing reset action (10 → 0)...\n";
$component = new CounterComponent(
    id: 'counter:test',
    initialData: ['count' => 10]
);

$update = $handler->handle($component, 'reset', []);

echo "   New count: " . $update->state->data['count'] . "\n";
echo "   Events dispatched: " . count($update->events) . "\n";

foreach ($update->events as $event) {
    echo "   - Event: {$event->name}\n";
    echo "     Payload: " . json_encode($event->payload, JSON_PRETTY_PRINT) . "\n";
}

echo "\n";

// 6. Test ComponentEvent Value Object
echo "6. Testing ComponentEvent Value Object...\n";

// Broadcast event
$broadcastEvent = ComponentEvent::broadcast('test:broadcast', ['message' => 'Hello all']);
echo "   Broadcast event: {$broadcastEvent->name}\n";
echo "   Is broadcast: " . ($broadcastEvent->isBroadcast() ? 'Yes' : 'No') . "\n";
echo "   Payload: " . json_encode($broadcastEvent->payload) . "\n\n";

// Targeted event
$targetedEvent = ComponentEvent::target('test:targeted', 'counter:specific', ['value' => 42]);
echo "   Targeted event: {$targetedEvent->name}\n";
echo "   Target: {$targetedEvent->targetComponentId}\n";
echo "   Is broadcast: " . ($targetedEvent->isBroadcast() ? 'Yes' : 'No') . "\n";
echo "   Targets 'counter:specific': " . ($targetedEvent->targetsComponent('counter:specific') ? 'Yes' : 'No') . "\n";
echo "   Targets 'counter:other': " . ($targetedEvent->targetsComponent('counter:other') ? 'Yes' : 'No') . "\n";

echo "\n";

// 7. Test event serialization
echo "7. Testing event serialization for JSON response...\n";

$events = [
    ComponentEvent::broadcast('counter:changed', ['count' => 10]),
    ComponentEvent::target('notification:show', 'notification:bell', ['message' => 'Counter updated']),
];

$serialized = array_map(fn ($e) => $e->toArray(), $events);
echo "   Serialized events:\n";
echo "   " . json_encode($serialized, JSON_PRETTY_PRINT) . "\n";

echo "\n=== All Tests Completed ✓ ===\n";
