<?php

namespace App\Tests\Unit\Service;

use App\Service\Forecast\ImpactScoreService;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use App\Service\Push\PushNotificationService;

class ImpactScoreServiceTest extends TestCase
{
    private ImpactScoreService $service;

    protected function setUp(): void
    {
        $connection = $this->createStub(Connection::class);
        $em         = $this->createStub(EntityManagerInterface::class);
        $cache      = new ArrayAdapter();
        $push       = $this->createStub(PushNotificationService::class);

        $this->service = new ImpactScoreService(
            $connection,
            $em,
            $cache,
            new NullLogger(),
            $push,
        );
    }

    // ── scoreToLevel ──────────────────────────────────────────────────────────

    #[\PHPUnit\Framework\Attributes\DataProvider('scoreLevelProvider')]
    public function testScoreToLevel(int $score, string $expected): void
    {
        $method = new \ReflectionMethod(ImpactScoreService::class, 'scoreToLevel');
        $result = $method->invoke($this->service, $score);

        self::assertSame($expected, $result);
    }

    /** @return array<string, array{int, string}> */
    public static function scoreLevelProvider(): array
    {
        return [
            'score 0 → low'        => [0,   'low'],
            'score 30 → low'       => [30,  'low'],
            'score 31 → medium'    => [31,  'medium'],
            'score 70 → medium'    => [70,  'medium'],
            'score 71 → high'      => [71,  'high'],
            'score 100 → high'     => [100, 'high'],
        ];
    }

    // ── emptyScore ────────────────────────────────────────────────────────────

    public function testEmptyScoreReturnsCorrectStructure(): void
    {
        $method = new \ReflectionMethod(ImpactScoreService::class, 'emptyScore');
        $result = $method->invoke($this->service);

        self::assertSame(0,        $result['score']);
        self::assertSame('low',    $result['level']);
        self::assertNull($result['distance']);
        self::assertSame(0.0,      $result['density']);
        self::assertSame('stable', $result['trend']);
        self::assertNull($result['etaHours']);
    }
}
