<?php

declare(strict_types=1);

namespace App\Framework\LiveComponents\Profiling\ValueObjects;

use App\Framework\Core\ValueObjects\Byte;
use App\Framework\Core\ValueObjects\Duration;

/**
 * Profile Phase Value Object
 *
 * Represents a single phase in the component lifecycle (resolve, render, action, cache).
 */
final readonly class ProfilePhase
{
    /**
     * @param string $name Phase name (e.g., 'resolve', 'render', 'action.submit')
     * @param Duration $duration Duration of the phase
     * @param Byte $memoryDelta Memory change during phase
     * @param array<string, mixed> $attributes Additional phase attributes
     */
    public function __construct(
        public string $name,
        public Duration $duration,
        public Byte $memoryDelta,
        public array $attributes = []
    ) {
    }

    /**
     * Create from raw values
     */
    public static function create(
        string $name,
        float $durationMs,
        int $memoryBytes,
        array $attributes = []
    ): self {
        return new self(
            name: $name,
            duration: Duration::fromMilliseconds($durationMs),
            memoryDelta: Byte::fromBytes($memoryBytes),
            attributes: $attributes
        );
    }

    /**
     * Get duration in milliseconds
     */
    public function getDurationMs(): float
    {
        return $this->duration->toMilliseconds();
    }

    /**
     * Get memory in bytes
     */
    public function getMemoryBytes(): int
    {
        return $this->memoryDelta->toBytes();
    }

    /**
     * Get memory in megabytes
     */
    public function getMemoryMB(): float
    {
        return $this->memoryDelta->toMegabytes(2);
    }

    /**
     * Check if phase was successful
     */
    public function isSuccessful(): bool
    {
        return ($this->attributes['success'] ?? false) === true;
    }

    /**
     * Get error message if phase failed
     */
    public function getError(): ?string
    {
        return $this->attributes['error'] ?? null;
    }

    /**
     * Convert to array
     */
    public function toArray(): array
    {
        return [
            'name' => $this->name,
            'duration_ms' => $this->getDurationMs(),
            'memory_bytes' => $this->getMemoryBytes(),
            'memory_mb' => $this->getMemoryMB(),
            'attributes' => $this->attributes,
        ];
    }
}
