<?php
declare(strict_types=1);

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

use PpPhp\Core\Platform\Event\Sourcing\Aggregate\AggregateRepositoryRuntime;
use PpPhp\Core\Platform\Event\Sourcing\EventStore\EventStoreRuntime;
use PpPhp\Core\Platform\Event\Sourcing\Snapshot\SnapshotPolicy;
use PpPhp\Core\Platform\Event\Sourcing\Snapshot\SnapshotRuntime;

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

        $aggregateRuntime = AggregateRepositoryRuntime::resetInstance($basePath);
        $aggregateRuntime->clear();

        $snapshotRuntime = SnapshotRuntime::resetInstance($basePath, new SnapshotPolicy(2));
        $snapshotRuntime->clear();

        $state1 = $aggregateRuntime->save('snapshot-cart-1', 'Cart', 'CartCreated', ['status' => 'open']);
        $maybe1 = $snapshotRuntime->maybeCreate($state1, ['source' => 'verifier']);

        $state2 = $aggregateRuntime->save('snapshot-cart-1', 'Cart', 'ItemAdded', ['items' => [['sku' => 'A1']]]);
        $snapshot = $snapshotRuntime->maybeCreate($state2, ['source' => 'verifier']);

        $state3 = $aggregateRuntime->save('snapshot-cart-1', 'Cart', 'CartCheckedOut', ['status' => 'checked_out']);

        $rehydrated = $snapshotRuntime->rehydrateFromLatest('snapshot-cart-1');
        $snapshotRuntime->save();

        $secondRuntime = SnapshotRuntime::resetInstance($basePath, new SnapshotPolicy(2));
        $secondRuntime->hydrate();

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

        $checks = [
            'policy' => $maybe1 === null && $snapshot !== null,
            'create' => $snapshot !== null && $snapshot->version() === 2,
            'latest' => $secondRuntime->latest('snapshot-cart-1') !== null,
            'rehydrate' => $rehydrated->version() === 3 && (($rehydrated->state()['status'] ?? '') === 'checked_out'),
            'statistics' => ($stats['snapshots'] ?? 0) === 1 && ($stats['aggregates'] ?? 0) === 1,
            'persistence' => $secondRuntime->store()->exists(),
            'hydration' => count($summary['snapshots']) === 1,
        ];

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

        return [
            'ok' => !in_array(false, $checks, true),
            'checks' => $checks,
            'issues' => $issues,
            'summary' => [
                'snapshots' => $stats['snapshots'] ?? 0,
                'aggregates' => $stats['aggregates'] ?? 0,
                'maxVersion' => $stats['maxVersion'] ?? 0,
                'score' => in_array(false, $checks, true) ? 80 : 100,
            ],
        ];
    }
}
