<?php

declare(strict_types=1);

namespace App\Framework\Console\Analytics\ValueObjects;

use App\Framework\Console\ExitCode;
use App\Framework\Core\ValueObjects\Duration;
use DateTimeImmutable;

/**
 * Value object representing a single command usage metric
 */
final readonly class CommandUsageMetric
{
    public function __construct(
        public string $commandName,
        public DateTimeImmutable $executedAt,
        public Duration $executionTime,
        public ExitCode $exitCode,
        public int $argumentCount,
        public ?string $userId = null,
        public ?array $metadata = null
    ) {
    }

    public function isSuccessful(): bool
    {
        return $this->exitCode === ExitCode::SUCCESS;
    }

    public function toArray(): array
    {
        return [
            'command_name' => $this->commandName,
            'executed_at' => $this->executedAt->format('Y-m-d H:i:s'),
            'execution_time_ms' => $this->executionTime->toMilliseconds(),
            'execution_time_seconds' => $this->executionTime->toSeconds(),
            'execution_time_human' => $this->executionTime->toHumanReadable(),
            'exit_code' => $this->exitCode->value,
            'argument_count' => $this->argumentCount,
            'user_id' => $this->userId,
            'metadata' => $this->metadata,
            'is_successful' => $this->isSuccessful(),
        ];
    }

    public static function fromArray(array $data): self
    {
        return new self(
            commandName: $data['command_name'],
            executedAt: new DateTimeImmutable($data['executed_at']),
            executionTime: Duration::fromMilliseconds((float) $data['execution_time_ms']),
            exitCode: ExitCode::from((int) $data['exit_code']),
            argumentCount: (int) $data['argument_count'],
            userId: $data['user_id'] ?? null,
            metadata: $data['metadata'] ?? null
        );
    }

    public static function create(
        string $commandName,
        Duration $executionTime,
        ExitCode $exitCode,
        int $argumentCount,
        ?string $userId = null,
        ?array $metadata = null
    ): self {
        return new self(
            commandName: $commandName,
            executedAt: new DateTimeImmutable(),
            executionTime: $executionTime,
            exitCode: $exitCode,
            argumentCount: $argumentCount,
            userId: $userId,
            metadata: $metadata
        );
    }
}
