<?php

declare(strict_types=1);

namespace App\Application\Analytics\ValueObject;

use App\Framework\Core\ValueObjects\Percentage;

/**
 * User action breakdown for analytics reporting
 */
final readonly class ActionBreakdown
{
    /**
     * @param array<int, array{action: string, count: int}> $actions
     */
    public function __construct(
        public array $actions
    ) {
        foreach ($actions as $action) {
            if ($action['count'] < 0) {
                throw new \InvalidArgumentException('Action counts cannot be negative');
            }
        }
    }

    /**
     * @param array<int, array{action: string, count: int}> $actions
     */
    public static function fromArray(array $actions): self
    {
        return new self($actions);
    }

    public function getTotal(): int
    {
        return array_sum(array_column($this->actions, 'count'));
    }

    /**
     * @return array{action: string, count: int}|null
     */
    public function getTopAction(): ?array
    {
        if (empty($this->actions)) {
            return null;
        }

        $sorted = $this->actions;
        usort($sorted, fn ($a, $b) => $b['count'] <=> $a['count']);

        return $sorted[0];
    }

    /**
     * @param int $limit
     * @return array<int, array{action: string, count: int, percentage: string}>
     */
    public function getTopActions(int $limit = 10): array
    {
        $sorted = $this->actions;
        usort($sorted, fn ($a, $b) => $b['count'] <=> $a['count']);

        $total = $this->getTotal();
        $topActions = array_slice($sorted, 0, $limit);

        return array_map(function ($action) use ($total) {
            return [
                'action' => $action['action'],
                'count' => $action['count'],
                'percentage' => Percentage::fromRatio($action['count'], $total)->format(),
            ];
        }, $topActions);
    }

    public function getActionCount(string $actionName): int
    {
        foreach ($this->actions as $action) {
            if ($action['action'] === $actionName) {
                return $action['count'];
            }
        }

        return 0;
    }

    public function getActionPercentage(string $actionName): Percentage
    {
        $count = $this->getActionCount($actionName);

        return Percentage::fromRatio($count, $this->getTotal());
    }

    /**
     * @return array<int, array{action: string, count: int}>
     */
    public function toArray(): array
    {
        return $this->actions;
    }

    /**
     * Legacy format for backward compatibility
     * @return array<int, array{action: string, count: int}>
     */
    public function toAnalyticsArray(): array
    {
        return $this->actions;
    }
}
