<?php

declare(strict_types=1);

namespace App\Framework\Discovery\Events;

use App\Framework\Core\ValueObjects\Byte;
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\Discovery\ValueObjects\MemoryStrategy;

/**
 * Event fired when chunk processing starts, progresses, or completes
 */
final readonly class ChunkProcessingEvent
{
    public function __construct(
        public ChunkEventType $eventType,
        public int $chunkIndex,
        public int $totalChunks,
        public int $chunkSize,
        public int $processedFiles,
        public int $totalFiles,
        public Byte $chunkMemoryUsage,
        public float $chunkComplexity,
        public ?Duration $processingTime,
        public MemoryStrategy $strategy,
        public ?string $context,
        public Timestamp $timestamp
    ) {
    }

    public function getProgressPercentage(): float
    {
        return $this->totalFiles > 0 ? ($this->processedFiles / $this->totalFiles) * 100 : 0.0;
    }

    public function getChunkProgressPercentage(): float
    {
        return $this->totalChunks > 0 ? (($this->chunkIndex + 1) / $this->totalChunks) * 100 : 0.0;
    }

    public function getProcessingRate(): ?float
    {
        if ($this->processingTime === null || $this->processingTime->toSeconds() <= 0) {
            return null;
        }

        return $this->chunkSize / $this->processingTime->toSeconds(); // Files per second
    }

    public function getMemoryEfficiency(): float
    {
        return $this->chunkSize > 0
            ? $this->chunkMemoryUsage->toBytes() / $this->chunkSize
            : 0.0; // Bytes per file
    }

    public function toArray(): array
    {
        return [
            'event_type' => $this->eventType->value,
            'chunk_index' => $this->chunkIndex,
            'total_chunks' => $this->totalChunks,
            'chunk_size' => $this->chunkSize,
            'processed_files' => $this->processedFiles,
            'total_files' => $this->totalFiles,
            'chunk_memory_usage' => $this->chunkMemoryUsage->toHumanReadable(),
            'chunk_memory_usage_bytes' => $this->chunkMemoryUsage->toBytes(),
            'chunk_complexity' => round($this->chunkComplexity, 2),
            'processing_time_seconds' => $this->processingTime?->toSeconds(),
            'processing_time_human' => $this->processingTime?->humanReadable(),
            'strategy' => $this->strategy->value,
            'context' => $this->context,
            'progress_percentage' => round($this->getProgressPercentage(), 2),
            'chunk_progress_percentage' => round($this->getChunkProgressPercentage(), 2),
            'processing_rate_files_per_sec' => $this->getProcessingRate() !== null
                ? round($this->getProcessingRate(), 2)
                : null,
            'memory_efficiency_bytes_per_file' => round($this->getMemoryEfficiency(), 0),
            'timestamp' => $this->timestamp->toFloat(),
        ];
    }
}
