<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Sourcing\Domain\Validation;

use PpPhp\Core\Platform\Event\Sourcing\Domain\DomainEventDispatcherRuntime;
use PpPhp\Core\Platform\Event\Sourcing\Domain\DomainEventListener;
use PpPhp\Core\Platform\Event\Sourcing\EventStore\EventStoreRuntime;

final class DomainEventDispatcherVerifier
{
    public function verify(string $basePath): array
    {
        $eventStore = EventStoreRuntime::resetInstance($basePath);
        $eventStore->clear();

        $eventStore->append('domain-order-1', 'Order', 'OrderCreated', ['status' => 'created']);
        $eventStore->append('domain-order-1', 'Order', 'OrderPaid', ['status' => 'paid']);
        $eventStore->append('domain-customer-1', 'Customer', 'CustomerRegistered', ['name' => 'Ada']);

        $runtime = DomainEventDispatcherRuntime::resetInstance($basePath);
        $runtime->clear();

        $listener = $runtime->register(DomainEventListener::create('order_listener', 'Order Listener', [], ['Order']));
        $processed = $runtime->dispatchNew();
        $summary = $runtime->summary();
        $stats = $summary['statistics'];

        $replayed = $runtime->replay();
        $runtime->save();

        $second = DomainEventDispatcherRuntime::resetInstance($basePath);
        $second->hydrate();

        $secondSummary = $second->summary();
        $secondStats = $secondSummary['statistics'];

        $checks = [
            'register' => $listener->listenerId() === 'order_listener',
            'dispatch' => $processed === 3,
            'listenerMatch' => ($stats['dispatched'] ?? 0) === 2 && ($stats['failed'] ?? 0) === 1,
            'checkpoint' => ($stats['lastSequence'] ?? 0) === 3,
            'replay' => $replayed === 3,
            'statistics' => ($secondStats['events'] ?? 0) === 3 && ($secondStats['results'] ?? 0) === 3,
            'persistence' => $second->store()->exists(),
            'hydration' => count($secondSummary['envelopes']) === 3,
        ];

        $issues = [];
        foreach ($checks as $check => $ok) {
            if (!$ok) {
                $issues[] = ['check' => $check, 'message' => 'Domain event dispatch verification failed: ' . $check];
            }
        }

        return [
            'ok' => !in_array(false, $checks, true),
            'checks' => $checks,
            'issues' => $issues,
            'summary' => [
                'listeners' => $secondStats['listeners'] ?? 0,
                'events' => $secondStats['events'] ?? 0,
                'dispatched' => $secondStats['dispatched'] ?? 0,
                'failed' => $secondStats['failed'] ?? 0,
                'score' => in_array(false, $checks, true) ? 80 : 100,
            ],
        ];
    }
}
