<?php
declare(strict_types=1);

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

use PpPhp\Core\Platform\Event\Sourcing\Compaction\EventCompactionPolicy;
use PpPhp\Core\Platform\Event\Sourcing\Compaction\EventCompactionRuntime;
use PpPhp\Core\Platform\Event\Sourcing\EventStore\EventStoreRuntime;

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

        $eventStore->append('compact-order-1', 'Order', 'OrderCreated', ['status' => 'created']);
        $eventStore->append('compact-order-1', 'Order', 'OrderPaid', ['status' => 'paid']);
        $eventStore->append('compact-order-1', 'Order', 'OrderPacked', ['status' => 'packed']);
        $eventStore->append('compact-order-1', 'Order', 'OrderShipped', ['status' => 'shipped']);

        $runtime = EventCompactionRuntime::resetInstance($basePath, new EventCompactionPolicy(2, true, true));
        $runtime->clear();

        $result = $runtime->compactAggregate('compact-order-1');

        $optimized = $runtime->optimize([
            ['eventId' => 'evt_b', 'sequence' => 2],
            ['eventId' => 'evt_a', 'sequence' => 1],
            ['eventId' => 'evt_a', 'sequence' => 1],
        ]);

        $runtime->save();

        $second = EventCompactionRuntime::resetInstance($basePath, new EventCompactionPolicy(2, true, true));
        $second->hydrate();

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

        $checks = [
            'compaction' => $result->compactedCount() === 2,
            'optimization' => count($optimized) === 2 && (($optimized[0]['eventId'] ?? '') === 'evt_a'),
            'archive' => ($stats['archives'] ?? 0) === 1 && ($stats['archivedEvents'] ?? 0) === 2,
            'snapshotSafety' => (($summary['policy']['snapshotSafe'] ?? false) === true),
            'statistics' => ($stats['streams'] ?? 0) === 1 && ($stats['compactedEvents'] ?? 0) === 2,
            'persistence' => $second->store()->exists(),
            'hydration' => count($summary['results']) === 1,
        ];

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

        return [
            'ok' => !in_array(false, $checks, true),
            'checks' => $checks,
            'issues' => $issues,
            'summary' => [
                'streams' => $stats['streams'] ?? 0,
                'compactedEvents' => $stats['compactedEvents'] ?? 0,
                'archives' => $stats['archives'] ?? 0,
                'archivedEvents' => $stats['archivedEvents'] ?? 0,
                'score' => in_array(false, $checks, true) ? 80 : 100,
            ],
        ];
    }
}
