<?php

declare(strict_types=1);

namespace App\Framework\EventSourcing\Snapshots;

use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\EventSourcing\AggregateRoot;

/**
 * Time-Based Snapshot Strategy
 *
 * Creates snapshot if last snapshot is older than threshold
 */
final readonly class TimeBasedStrategy implements SnapshotStrategy
{
    public function __construct(
        private Duration $threshold,
        private SnapshotStore $store
    ) {
    }

    public function shouldTakeSnapshot(AggregateRoot $aggregate): bool
    {
        $lastSnapshot = $this->store->getLatest(
            $aggregate->getAggregateId()
        );

        if (! $lastSnapshot) {
            return true; // No snapshot exists yet
        }

        $timeSinceSnapshot = Timestamp::now()->getTimestamp()
            - $lastSnapshot->getCreatedAt()->getTimestamp();

        return $timeSinceSnapshot >= $this->threshold->toSeconds();
    }

    public static function daily(SnapshotStore $store): self
    {
        return new self(Duration::fromDays(1), $store);
    }

    public static function hourly(SnapshotStore $store): self
    {
        return new self(Duration::fromHours(1), $store);
    }
}
