<?php

declare(strict_types=1);

namespace App\Framework\EventSourcing\Projections;

use App\Framework\Cache\Cache;
use App\Framework\Cache\CacheItem;
use App\Framework\Cache\CacheKey;
use App\Framework\Core\ValueObjects\Duration;

/**
 * Cache-based Projection Repository
 *
 * Stores projection state in cache for fast access
 */
final readonly class CacheProjectionRepository implements ProjectionRepository
{
    public function __construct(
        private Cache $cache
    ) {
    }

    public function getState(string $projectionName): ProjectionState
    {
        $cacheKey = $this->getCacheKey($projectionName);
        $cacheItem = $this->cache->get($cacheKey);

        if ($cacheItem && $cacheItem->value instanceof ProjectionState) {
            return $cacheItem->value;
        }

        // Return initial state if not found
        return ProjectionState::initial($projectionName);
    }

    public function saveState(ProjectionState $state): void
    {
        $cacheKey = $this->getCacheKey($state->projectionName);

        $cacheItem = CacheItem::forSetting(
            key: $cacheKey,
            value: $state,
            ttl: Duration::fromDays(30) // Long TTL for projection state
        );

        $this->cache->set($cacheItem);
    }

    public function deleteState(string $projectionName): void
    {
        $cacheKey = $this->getCacheKey($projectionName);
        $this->cache->forget($cacheKey);
    }

    public function getAllStates(): array
    {
        // Note: This requires cache implementation that supports prefix scanning
        // For now, return empty array - would need enhancement for full functionality
        return [];
    }

    private function getCacheKey(string $projectionName): CacheKey
    {
        return CacheKey::fromString("projection:state:{$projectionName}");
    }
}
