<?php

declare(strict_types=1);

namespace App\Framework\SlidingWindow\Aggregator;

use App\Framework\SlidingWindow\WindowEntry;

/**
 * Aggregator for numeric values - useful for Performance Metrics
 *
 * @implements SlidingWindowAggregator<NumericResult>
 */
final readonly class NumericAggregator implements SlidingWindowAggregator
{
    public function aggregate(WindowEntry ...$entries): NumericResult
    {
        if (empty($entries)) {
            return new NumericResult(
                count: 0,
                sum: 0,
                average: 0,
                min: null,
                max: null,
                median: null,
                percentile95: null
            );
        }

        $values = array_map(fn (WindowEntry $entry) => (float) $entry->value, $entries);
        sort($values);

        $count = count($values);
        $sum = array_sum($values);
        $average = $sum / $count;
        $min = min($values);
        $max = max($values);

        // Calculate median
        $middle = intval($count / 2);
        $median = $count % 2 === 0
            ? ($values[$middle - 1] + $values[$middle]) / 2
            : $values[$middle];

        // Calculate 95th percentile
        $p95Index = intval($count * 0.95);
        $p95Index = min($p95Index, $count - 1);
        $percentile95 = $values[$p95Index];

        return new NumericResult(
            count: $count,
            sum: $sum,
            average: $average,
            min: $min,
            max: $max,
            median: $median,
            percentile95: $percentile95
        );
    }

    public function getIdentifier(): string
    {
        return 'numeric';
    }
}
