<?php

namespace MintyPHP\Tests\Service\Data;

use MintyPHP\Service\Data\GridUserCountEnricher;
use PHPUnit\Framework\TestCase;

class GridUserCountEnricherTest extends TestCase
{
    private function enricher(): GridUserCountEnricher
    {
        return new GridUserCountEnricher();
    }

    public function testComputeCountsWithTypicalRows(): void
    {
        $rows = [
            ['id' => 1, 'description' => 'A'],
            ['id' => 2, 'description' => 'B'],
        ];
        $countTotal = static fn (array $ids): array => [1 => 5, 2 => 3];
        $countActive = static fn (array $ids): array => [1 => 3, 2 => 1];

        $result = $this->enricher()->computeCounts($rows, $countTotal, $countActive);

        $this->assertSame(['active_users' => 3, 'inactive_users' => 2], $result[1]);
        $this->assertSame(['active_users' => 1, 'inactive_users' => 2], $result[2]);
    }

    public function testComputeCountsWithEmptyRows(): void
    {
        $called = false;
        $countTotal = static function () use (&$called): array {
            $called = true;
            return [];
        };
        $countActive = static fn (): array => [];

        $result = $this->enricher()->computeCounts([], $countTotal, $countActive);

        $this->assertSame([], $result);
        $this->assertFalse($called, 'Count callables should not be invoked for empty rows');
    }

    public function testComputeCountsDeduplicatesIds(): void
    {
        $rows = [
            ['id' => 1],
            ['id' => 1],
            ['id' => 2],
        ];
        $receivedIds = null;
        $countTotal = static function (array $ids) use (&$receivedIds): array {
            $receivedIds = $ids;
            return [1 => 10, 2 => 5];
        };
        $countActive = static fn (array $ids): array => [1 => 8, 2 => 3];

        $this->enricher()->computeCounts($rows, $countTotal, $countActive);

        $this->assertSame([1, 2], $receivedIds);
    }

    public function testComputeCountsSkipsZeroIds(): void
    {
        $rows = [
            ['id' => 0],
            ['id' => -1],
            ['id' => 3],
        ];
        $receivedIds = null;
        $countTotal = static function (array $ids) use (&$receivedIds): array {
            $receivedIds = $ids;
            return [3 => 2];
        };
        $countActive = static fn (array $ids): array => [3 => 1];

        $result = $this->enricher()->computeCounts($rows, $countTotal, $countActive);

        $this->assertSame([3], $receivedIds);
        $this->assertCount(1, $result);
        $this->assertSame(['active_users' => 1, 'inactive_users' => 1], $result[3]);
    }

    public function testComputeCountsWithZeroCounts(): void
    {
        $rows = [['id' => 5]];
        $countTotal = static fn (array $ids): array => [];
        $countActive = static fn (array $ids): array => [];

        $result = $this->enricher()->computeCounts($rows, $countTotal, $countActive);

        $this->assertSame(['active_users' => 0, 'inactive_users' => 0], $result[5]);
    }

    public function testInactiveNeverNegative(): void
    {
        $rows = [['id' => 1]];
        $countTotal = static fn (array $ids): array => [1 => 2];
        $countActive = static fn (array $ids): array => [1 => 5];

        $result = $this->enricher()->computeCounts($rows, $countTotal, $countActive);

        $this->assertSame(0, $result[1]['inactive_users']);
    }
}
