<?php

declare(strict_types=1);

namespace App\Framework\Discovery\Events;

use App\Framework\Cache\CacheKey;
use App\Framework\Core\ValueObjects\Byte;
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\Discovery\ValueObjects\CacheLevel;

/**
 * Event fired when discovery results are loaded from cache
 *
 * Extended for memory-aware caching with data size and cache level tracking.
 */
final readonly class CacheHitEvent
{
    public function __construct(
        public CacheKey $cacheKey,
        public int $itemCount,
        public Duration $cacheAge,
        public Timestamp $timestamp,
        public ?Byte $dataSize = null,
        public ?CacheLevel $cacheLevel = null
    ) {
    }

    public function isFresh(): bool
    {
        // Consider cache fresh if less than 30 minutes old
        return $this->cacheAge->lessThan(Duration::fromMinutes(30));
    }

    /**
     * Check if this is a large cache hit
     */
    public function isLargeCacheHit(): bool
    {
        return $this->dataSize?->greaterThan(Byte::fromMegabytes(1)) ?? false;
    }

    /**
     * Get cache efficiency rating
     */
    public function getEfficiencyRating(): string
    {
        if ($this->dataSize === null) {
            return 'unknown';
        }

        return match (true) {
            $this->isFresh() && ! $this->isLargeCacheHit() => 'optimal',
            $this->isFresh() => 'good',
            $this->dataSize->greaterThan(Byte::fromMegabytes(5)) => 'poor',
            default => 'fair'
        };
    }

    public function toArray(): array
    {
        $baseArray = [
            'cache_key' => (string) $this->cacheKey,
            'item_count' => $this->itemCount,
            'cache_age_seconds' => $this->cacheAge->toSeconds(),
            'cache_age_human' => $this->cacheAge->humanReadable(),
            'is_fresh' => $this->isFresh(),
            'timestamp' => $this->timestamp->toFloat(),
        ];

        // Add memory-aware fields if available
        if ($this->dataSize !== null) {
            $baseArray['data_size'] = $this->dataSize->toHumanReadable();
            $baseArray['is_large_hit'] = $this->isLargeCacheHit();
            $baseArray['efficiency_rating'] = $this->getEfficiencyRating();
        }

        if ($this->cacheLevel !== null) {
            $baseArray['cache_level'] = $this->cacheLevel->value;
        }

        return $baseArray;
    }
}
